android gps spikes issue - java

I am getting a very stupid problem
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, ll);
float spd = myLoc.distanceTo(previousLocation) / (myLoc.getTime() - previousLocation.getTime());
previous location is the myLoc stored last time onLocationChanged was called i-e each after 1 second.
Now my problem is, sometimes it gives extremely big peak values. making spd go way higher than it usually is.
Anyone can tell how can i reduce this
Best Regards

A few recommendations:
Check Location.hasSpeed() to see if this information is provided for you. It may be more reliable than your calculation, though I don't know anything about the algorithm used to produce this value.
Check Location.getAccuracy() to decide when to ignore a particular fix for calculating speed.
Read these tips thoroughly to see an example of how to be selective when dealing with GPS results. They could be too old or too imprecise to be used for speed. http://developer.android.com/guide/topics/location/strategies.html#Updates
For an app I worked on, I implemented a filter that compared the current location to the two previous locations and used the lowest calculated speed. You may need a more or less complex method to determine speed that will be useful for you.

Related

Tricks for removing floating point rounding error?

First, let me start off by saying that I know there is no way to avoid rounding errors. My question rather lies in how to take rounding errors and fix them. "Why does it matter?", you may ask. In a java project of mine I have used the Separating Axis Theorem to implement collision detection/resolution for moving objects, and it works spectacularly well, but there is a flaw that I keep running into...
Rounding errors
I've made a picture to help illustrate what I'm talking about:
Above is how I do collision resolution in my java project. Let me show how rounding errors can be problematic in this situation.
SV = MV.scale(2f(distance)/3f(move length))
2f/3f = 0.666666667 (approximately what will be displayed if you print 2/3)
0.666666667 is very bad because it actually causes the scale to be too large
0.000000001 scale too large, which means SV will be larger than expected, causing it to barely clip into the other shape upon collision resolution. Yes this is so very small that it cant be detected by a human, but it does indeed cause clipping, however small it may be, and as such I consider it a FAILED collision resolution.
My working solution thus far has been something like such
MV.scale((int)(2f/3f)*10000f)/10000f)
While this will probably work for all applications I would use my algorithm for, the loss in precision and probable eventual breaking at high numbers (because of the precision loss encountered there due to the nature of floating point numbers) make it hard to accept. I wouldn't have an issue with choosing 0.666666665 (or something close to it) through an algorithm, but I can't find an algorithm for finding the next closest floating point number to a number (and if it exists I'd be wary of performance drain).
Any ideas or alternate strategies? I'm kinda at my wits end here. Thanks in advance!

AnyLogic: compensating for double overflow in GISRegion.area()

I'm trying to sort a collection of AnyLogic GISRegions by their geographical area. Said area is calculated using GISRegion.area(units), which is straightforward enough. The areas I'm using, however, are city-scale and the method returns a double. This appears to cause overflow problems:
I don't think I'm doing anything wrong with my code, so presumably this is an AnyLogic problem. For brevity, I've included a line that prints each region's area rather than the sorting steps:
// For each region of the Australian Capital Territory, print its area in km^2:
areas.forEach(next -> traceln(""+next.name+": " + next.gisRegion.area(SQ_KILOMETER)));
Has anyone encountered this issue? How did you get around it?
For non-AnyLogic users, I have all the lat-long points in each geoshape. How might I calculate the area using those points?
[Not really a full answer, but the ideas are too long for a comment.]
I assume you've raised an AnyLogic support request since it seems 100% a bug. Since this is just a basic 'calculate area' function, I can't see any way round it other than, as you suggest, calculating it in an alternative manner from the vertex lat/longs that you have, and can get via getPoints() on the GISRegion.
Since this is just an N-sided polygon, surely there must be standard Java libraries that could calculate that, though that's not allowing for the GIS projection (not sure what level of error that might introduce); you'd expect open GIS libraries to cope with the latter. Since a GISRegion has a createOMGraphicObject() method to create an OpenMap standard(?) format graphic, that could be useful if that's a standard format other libraries can work with.
There's code on glennon's answer to this GIS StackOverflow question that claims to perform the calculation (or you make be able to hook in to PostGIS as in fmark's answer).

GPS too inaccurate

I am new in android devlopment and I am trying to create a lap counting app.
In favor I calculate a distance (finishline) and look for intersections with toher distances (two latest coordinates).
My Problem is that my gps coordinates got 3.0 m (radius) accuracy in best case and this this is not enough.
Do you have any idea how to improve my accuracy? or is there a smarter way to count laps?
help and advice is greatly appreciated. Thank you!
Ok, this comment became too long so posting as an answer although it is more in the form of a suggestion.
Without going into much detail, you can use activity recognition to determine wheter the user is walking, running, driving. Using this information, keep a hold on the 'good quality' location updates and use a combination of accuracy and assumed max velocity based on activity to detect poor quality location updates.
This idea might be extended to perform dead reconing in areas where the location updates are too inaccurate.
I have added Activity Recognition to the library https://github.com/mcharmas/Android-ReactiveLocation, greatly reducing the code needed to get it up and running.

Watchmaker genetic algorithm combining Termination conditions

Using Stagnation(numGenerations, true) to terminate an evolution in Watchmaker.
I would like the numGenerations to depend on how well the evolution is doing. If I have a rotten population (low fitness) then I would like to bail out early. If the population is performing well, I'd like to give it more time.
How would I do that?
I read the user manual, worked through the examples on http://watchmaker.uncommons.org/, looked at the API, and searched around the web. Didn't see this topic addressed specifically. I'm new to Java and genetic algorithms, so I could have easily missed something.
Rereading the API I discovered that multiple TerminationConditions can be supplied to engine.evolvePopulation(). That let me write a recursive function that keeps going as long as the fitness continues to improve.
process (Parameters params) {
result = engine.evolvePopulation(params.size, 0,
new Stagnation(params.stagnation, true),
new TargetFitness(params.target, true));
if (result.get(0).getFitness() >= params.target)
process(params.increase());
return;
}
In my case, the target is incremented by a fixed amount every time. The size and stagnation are increased as a function of the cube of the target. That way, the better a particular population becomes, the more time gets invested into it. Not sure that's the best approach, but for this problem it got the answer I was looking for.
Oh by the way, my program doesn't really look like what I pasted in above. I'm a pretty lousy programmer and my code is a lot uglier than that. Just trying to show the gist of the idea.
The Stagnation termination condition only aborts the evolution if the best fitness score in the population does not improve for a certain number of consecutive generations. It does not cut-off after a fixed number of generations from the start (for that you would use the GenerationCount condition), it only kicks in when the evolution appears to have stopped making progress. So if your population is performing well (by which I take it you mean that the fitness is continuing to improve) the stagnation condition is unlikely to be triggered.
If you want something different you might need to write your own TerminationCondition. It's just a single method that takes the PopulationData as an argument so that you can make decisions based on that at the end of each generation. You just need to be able to define "rotten population" in terms of the mean and/or best fitness and the number of generations so far.

longitude and latitude points change for the same place

I am Android developer.
I am getting the longitude and latitude point of a place but for the same place these values changes and the third decimal varies.
My main purpose is to detect a place so it works only
when all these values of longitude and latitude matches so they must
be constant.
My questions are:
What is the reason for this variation?
Is there any method by which ti make these values remain constant for a specific place?
The phone's GPS isn't very accurate. That is, it is very accurate for navigate in your car, but missing by 20 meters is not unheard of.
To figure out if you're in the same place, you should calculate the distance between your current location and the place's coordinates. If it's lower than a threshold (try to find one that makes sense) - you're there.
Try using the GPS for more accurate data, but know that they will not be the same values everytime, but not very different either
You can look at the accuracy as well. The Location class has a getAccuracy() method -- if your accuracy decreased from the last method, it may be that the person went inside and lost line-of-sight to the sky.
As I have said before in other posts, I recommend using Google's Play Location service rather than the pure GPS. You can also use an isBetterLocation method as documented here.
As stated above, the GPS inherent accuracy isn't the best. For an idea of how the decimal places show accuracy levels, see the Wikipedia page
In short, the third decimal place results in an accuracy differential of 43-111 meters, depending on your position on the globe. So I would either look at some other method of refining the data, or implementing some sort of threshold processing.

Categories