Clarification on min distance on LocationManager.requestLocationUpdates method, min Distance parameter - java

I researched online and saw that Location Manager.requestLocationUpdates method and saw that it took an argument of minDistance. The definition that the site(http://blog.doityourselfandroid.com/2010/12/25/understanding-locationlistener-android/) gave me for that argument was "minimum distance interval for notifications" with an example of 10 meters. Can anyone clarify what that means? Everytime i move 10 meters with a phone, i get an gps update?

Yes, essentially this means that if the platform observes your current position as being more than minDistance from the last location that was saved by the platform, your listener will get notified with the updated position. Note that these two positions don't necessarily need to be sequential (i.e., there could be a number of small displacements that eventually add up to minDistance, and the location that finally exceeds the threshold will be the one reported to the app).
The actual platform code can be seen on Github, which I've also pasted below:
private static boolean shouldBroadcastSafe(
Location loc, Location lastLoc, UpdateRecord record, long now) {
// Always broadcast the first update
if (lastLoc == null) {
return true;
}
// Check whether sufficient time has passed
long minTime = record.mRequest.getFastestInterval();
long delta = (loc.getElapsedRealtimeNanos() - lastLoc.getElapsedRealtimeNanos())
/ NANOS_PER_MILLI;
if (delta < minTime - MAX_PROVIDER_SCHEDULING_JITTER_MS) {
return false;
}
// Check whether sufficient distance has been traveled
double minDistance = record.mRequest.getSmallestDisplacement();
if (minDistance > 0.0) {
if (loc.distanceTo(lastLoc) <= minDistance) {
return false;
}
}
...
Note that minDistance parameter only affects when your app gets notified if the value is greater than 0.
Also please be aware that with all positioning systems there is a significant level of error when calculating locations, so with small minDistance values you may get notified frequently, but these notifications may be error in positioning calculations, not true user movement.

Related

Always getting same speed from GPS location - Kotlin

I'm trying to get the user's speed 10 times in three seconds when a function is called, and then calculate the sum of all the gotten values. I have the global variable:
lateinit var fusedLocationProviderClient : FusedLocationProviderClient
Which I then initialize in the onCreate method like this:
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
And then this is the code where I try to calculate the sum of the speeds:
val task = fusedLocationProviderClient.lastLocation
var sumSpeed = 0F
task.addOnSuccessListener {
if (it != null) {
for (i in 1..10) {
Thread.sleep(300)
sumSpeed += it.speed
}
}
current_gps_speed_tv.text = "Total is: $sumSpeed"
if (sumSpeed < 25) {
...
}
}
The result of sumSpeed always remains the same (34m/s), which is 10 times it.speed, which is also the same every time (3.4m/s).
I've searched for other answers (like this one) but what I'm using seems to be different. Why does this happen? Thank you.
This won't work for at least a few different reasons.
You're trying to poll it more than once per second. I think the fastest rate position is updated is at best once per second, and it's going to depend on device.
You are simply adding the same value to the sum 10 times and sleeping the thread pointlessly. Calling sleep pauses execution of your code. It does not magically change the value of it to some new value polled from the GPS.
Calling Thread.sleep on the main thread will freeze your app.
You are polling lastLocation, which is some location already known from the last time the GPS was used. It only reports a single value that comes from the past. It cannot report multiple new values. Your success listener is called only one time, because either the last location is available or it's not.
To get multiple locations over a period of time, you need to use requestLocationUpdates instead of lastLocation. See here for the documentation.
Edit, to expand on 2 based on your comment:
Imagine this code:
val x = 5
var sum = 0
for (i in 0..9) {
sum = sum + 5
}
println(sum)
This adds the value of x to sum 10 times, so the result will be 50.
Now consider this code:
val x = 5
var sum = 0
for (i in 0..9) {
Thread.sleep(100)
sum = sum + 5
}
println(sum)
This code has the exact same result. It just takes a lot longer to return because it keeps pausing to sleep. Sleeping has no effect on the value of x. x is always the same value. The same is true of it in your code. There is only ever one instance of it in your function.

How to assume if a pedestrian crossed an intersection on OSM

I need to validate if a pedestrian crossed an intersection using GPS' readings and findNearestIntersectionOSM calls to get the nearest intersections.
For each response from geoname, i check if the distance between the 2 points is less than a certain threshold and also using the sin function, i check if the angle between the intersection(GeoPoint.BearingTo) and pedestrian's current location flips its sign
Sin(previous location reading) * Sin(Current location read) < 0
Unfortunately, this is insufficient, and i sometimes receive false positives and so on.
Is there a better approach, or anything I'm missing?
Just to make clear, I'm not planning to dive into Image Processing field, but simply use some of OSM's functionality (if possible)
private void OnClosestIntersectionPoint(GeoPoint gPtIntersection) {
int iDistance = mGeoLastKnownPosition.distanceTo(gPtIntersection);
double dbCurrentBearing = mGeoLastKnownPosition.bearingTo(gPtIntersection);
if(mDbLastKnownBearing == null) {
mDbLastKnownBearing = new Double(dbCurrentBearing);
return;
}
boolean bFlippedSignByCrossing = Math.sin(mDbLastKnownBearing) * Math.sin(dbCurrentBearing) < 0;
mDbLastKnownBearing = dbCurrentBearing; // update bearing regardless to what's going to happen
if(bFlippedSignByCrossing && iDistance <= 10 && !HasntMarkIntersectionAsCrossed(gPtIntersection))
MarkAsIntersectionCrossed(mGeoLastKnownIntersection);
}

Java A* Implementation Issues

I have written an implementation of the A* algorithm, taken mainly from This wiki page, however I have a major problem; in that I believe I am visiting way too many nodes while calculating a route therefore ruining my performance. I've been trying to figure out the issue for a few days and I can't see what's wrong. Please note, all my data structures are self implemented however I've tested them and believe they're not the issue.
I've included my Priority Queue implementation just in case.
closedVertices is a Hash map of Vertices.
private Vertex routeCalculation(Vertex startLocation, Vertex endLocation, int routetype)
{
Vertex vertexNeighbour;
pqOpen.AddItem(startLocation);
while (!(pqOpen.IsEmpty()))
{
tempVertex = pqOpen.GetNextItem();
for (int i = 0; i < tempVertex.neighbors.GetNoOfItems(); i++) //for each neighbor of tempVertex
{
currentRoad = tempVertex.neighbors.GetItem(i);
currentRoad.visited = true;
vertexNeighbour = allVertices.GetNewValue(currentRoad.toid);
//if the neighbor is in closed set, move to next neighbor
checkClosed();
nodesVisited++;
setG_Score();
//checks if neighbor is in open set
findNeighbour();
//if neighbour is not in open set
if (!foundNeighbor || temp_g_score < vertexNeighbour.getTentativeDistance())
{
vertexNeighbour.setTentativeDistance(temp_g_score);
//calculate H once, store it and then do an if statement to see if it's been used before - if true, grab from memory, else calculate.
if (vertexNeighbour.visited == false)
vertexNeighbour.setH(heuristic(endLocation, vertexNeighbour));
vertexNeighbour.setF(vertexNeighbour.getH() + vertexNeighbour.getTentativeDistance());
// if neighbor isn't in open set, add it to open set
if (!(foundNeighbor))
{
pqOpen.AddItem(vertexNeighbour);
}
else
{
pqOpen.siftUp(foundNeighbourIndex);
}
}
}
}
}
return null;
}
Can anyone see where I may be exploring too many nodes?
Also, I've attempted to implement a way to calculate the quickest (timed) route, by modifying F by the speed of the road. Am I right in saying this the correct way to do it?
(I divided the speed of the road by 100 because it was taking a long time to execute otherwise).
I found my own error; I had implemented the way in which I calculate the heuristic for each node wrong - I had an IF statement to see if the H had already been calculated however I had done this wrong and therefore it never actually calculated the H for some nodes; resulting in excessive node exploration. I simply removed the line: if (vertexNeighbour.visited == false) and now I have perfect calculations.
However I am still trying to figure out how to calculate the fastest route in terms of time.

Java maze solving and reinforcement learning

I'm writing code to automate simulate the actions of both Theseus and the Minoutaur as shown in this logic game; http://www.logicmazes.com/theseus.html
For each maze I provide it with the positions of the maze, and which positions are available eg from position 0 the next states are 1,2 or stay on 0. I run a QLearning instantiation which calculates the best path for theseus to escape the maze assuming no minotaur. then the minotaur is introduced. Theseus makes his first move towards the exit and is inevitably caught, resulting in reweighting of the best path. using maze 3 in the game as a test, this approach led to theseus moving up and down on the middle line indefinatly as this was the only moves that didnt get it killed.
As per a suggestion recieved here within the last few days i adjusted my code to consider state to be both the position of thesesus and the minotaur at a given time. when theseus would move the state would be added to a list of "visited states".By comparing the state resulting from the suggested move to the list of visited states, I am able to ensure that theseus would not make a move that would result in a previous state.
The problem is i need to be able to revisit in some cases. Eg using maze 3 as example and minotaur moving 2x for every theseus move.
Theseus move 4 -> 5, state added(t5, m1). mino move 1->5. Theseus caught, reset. 4-> 5 is a bad move so theseus moves 4->3, mino catches on his turn. now both(t5, m1) and (t3 m1) are on the visited list
what happens is all possible states from the initial state get added to the dont visit list, meaning that my code loops indefinitly and cannot provide a solution.
public void move()
{
int randomness =10;
State tempState = new State();
boolean rejectMove = true;
int keepCurrent = currentPosition;
int keepMinotaur = minotaurPosition;
previousPosition = currentPosition;
do
{
minotaurPosition = keepMinotaur;
currentPosition = keepCurrent;
rejectMove = false;
if (states.size() > 10)
{
states.clear();
}
if(this.policy(currentPosition) == this.minotaurPosition )
{
randomness = 100;
}
if(Math.random()*100 <= randomness)
{
System.out.println("Random move");
int[] actionsFromState = actions[currentPosition];
int max = actionsFromState.length;
Random r = new Random();
int s = r.nextInt(max);
previousPosition = currentPosition;
currentPosition = actions[currentPosition][s];
}
else
{
previousPosition = currentPosition;
currentPosition = policy(currentPosition);
}
tempState.setAttributes(minotaurPosition, currentPosition);
randomness = 10;
for(int i=0; i<states.size(); i++)
{
if(states.get(i).getMinotaurPosition() == tempState.getMinotaurPosition() && states.get(i).theseusPosition == tempState.getTheseusPosition())
{
rejectMove = true;
changeReward(100);
}
}
}
while(rejectMove == true);
states.add(tempState);
}
above is the move method of theseus; showing it occasionally suggesting a random move
The problem here is a discrepancy between the "never visit a state you've previously been in" approach and your "reinforcement learning" approach. When I recommended the "never visit a state you've previously been in" approach, I was making the assumption that you were using backtracking: once Theseus got caught, you would unwind the stack to the last place where he made an unforced choice, and then try a different option. (That is, I assumed you were using a simple depth-first-search of the state-space.) In that sort of approach, there's never any reason to visit a state you've previously visited.
For your "reinforcement learning" approach, where you're completely resetting the maze every time Theseus gets caught, you'll need to change that. I suppose you can change the "never visit a state you've previously been in" rule to a two-pronged rule:
never visit a state you've been in during this run of the maze. (This is to prevent infinite loops.)
disprefer visiting a state you've been in during a run of the maze where Theseus got caught. (This is the "learning" part: if a choice has previously worked out poorly, it should be made less often.)
For what is worth, the simplest way to solve this problem optimally is to use ALPHA-BETA, which is a search algorithm for deterministic two-player games (like tic-tac-toe, checkers, chess). Here's a summary of how to implement it for your case:
Create a class that represents the current state of the game, which
should include: Thesesus's position, the Minoutaur's position and
whose turn is it. Say you call this class GameState
Create a heuristic function that takes an instance of GameState as paraemter, and returns a double that's calculated as follows:
Let Dt be the Manhattan distance (number of squares) that Theseus is from the exit.
Let Dm be the Manhattan distance (number of squares) that the Minotaur is from Theseus.
Let T be 1 if it's Theseus turn and -1 if it's the Minotaur's.
If Dm is not zero and Dt is not zero, return Dm + (Dt/2) * T
If Dm is zero, return -Infinity * T
If Dt is zero, return Infinity * T
The heuristic function above returns the value that Wikipedia refers to as "the heuristic value of node" for a given GameState (node) in the pseudocode of the algorithm.
You now have all the elements to code it in Java.

An efficient algorithm to move ostrichs along a line at a constant speed

Problem: move an object along a straight line at a constant speed in the Cartesian coordinate system (x,y only). The rate of update is unstable. The movement speed must be close to exact and the object must arrive very close to the destination. The line's source and destination may be anywhere.
Given: the source and destination addresses (x0,x1,y0, y1), and a speed of arbitrary value.
An asside: There is an answer on the SO regarding this, and it's good, however it presumes that total time spend traveling is given.
Here's what I've got:
x0 = 127;
y0 = 127;
x1 = 257;
y1 = 188;
speed = 127;
ostrich.x=x0 //plus some distance along the line;
ostrich.y=y0 // plus some distance along the line;
//An arbitrarily large value so that each iteration increments the distance a minute amount
SPEED_VAR = 1000;
xDistPerIteration = (x1 - x0) / SPEED_VAR;
yDistPerIteration = (y1 - y0) / SPEED_VAR;
distanceToTravel = ;//Pythagorean theorum
limitX = limit1 = 0; //determines when to stop the while loop
//get called 40-60 times per second
void update(){
//Keep incrementing the ostrich' location
while (limitX < speed && limitY < speed) {
limitX += Math.abs(xDistPerIteration);
limitY += Math.abs(yDistPerIteration);
ostrich.x += xDistPerIteration;
ostrich.y += yDistPerIteration;
}
distanceTraveled -= Math.sqrt(Math.pow(limitX, 2) + Math.pow(limitY, 2));
if (distanceTraveled <=0)
//ostrich arrived safely at the factory
}
This code gets the job done, however it takes up exclusively 18% of program time in a CPU intensive program. It's garbage, programatically and in terms of performance. Any ideas on what to do here?
An asside: There is an answer on the
SO regarding this, and it's good,
however it presumes that total time
spend traveling is given.
basic physics to the rescue
total time spent traveling = distance/speed
btw Math.hypot(limitX,limitY) is faster than Math.sqrt(Math.pow(limitX, 2) + Math.pow(limitY, 2))
though really it's that while loop you should refactor out
One thing to improve is:
There is no need to compute the square root in each call to the update function. You may use the squared distanceTraveled instead.
Similarly, Math.abs(xDistPerIteration) and Math.abs(yDistPerIteration) do not change at each call to update, you may save those values and get rid of the calls to the absolute value function in order to bit a save a bit more computing time.
Update gets called 40-60 times per second, right? In other words, once per frame. So why is there a while loop inside it?
Also, doing sqrt once, and pow twice, per frame is unnecessary.
Just let d2 be the distance squared, and stop when limitX*limitX+limitY*limitY exceeds it.

Categories

Resources