I a trying to create an application that will be able to guide people in a city, with points of interest. For this, I need the better accuracy I get, in order not to place POI where there is nothing...
To do this I use droidAR (it gives me a radar, and I can place my POI thanks to their coordinates). But the accuracy is so bad I can't see how this can used.
For exemple, to determine if I a close to a POI, I calculate the distance between it and my GPS position. It can be that, with a 10 meters accuracy given by Android when I place the POI, it is then 80 meters away when I try to find it.
SO I looked forward to find another position systems, I found :
skyhook, which is supposed to give a more accurate position. With this, I took 1000 points and checked their distance to the last point, it is always moving and it was sometimes 300m away, so it seems even less precise. Maybe anyone could use it successfully ?
someone told me to use DCM algo (Direct Cosine Matrix), that can give me an accurate relative position (no problem for my use cases to do every positioninf relative to a start point). Some drones are using it, it could reach 1 meter accuracy. But I couldn't find any implementation or help with Android.
Did anyone succeed into using the android GPS with accuracy ?
Either your android phone has a bad GPS device, or more probably you are doing something wrong. you can set a POI in city aprox. 5m acuracy, sometimes 20m. that is sufficient. check it with another GPS app that allows setting a waypoint.
In your app you could concentrate on the 95% GPS accuracy. There is nothing better than GPS (espcecialla yon a mobile phone), the other methods you described are for short time assistance to GPS, but they will not work good for pedestrians, they are made for vehicles (vehicles move straight most of the times, they cannot change its direction so fast like a human does).
Your problem is not the GPS location accuracy, it is the augmented reality projection of droidAR.
Related
I'm developing iOS/Android app that tracks mileage user has driven in his car.
Even though the task seems pretty trivial, there are 2 problems:
1) Mileage is not accurate comparing to car's odometer. (OD-10mi, App-8.5mi)
2) When user stays still outside the car, mileage keeps accumulating (it can add up like 4mi within 30 minutes.)
Is there any "easy" fix for that without adding complicated filtering, etc?
There are two small but significant things you can do:
For each GPS sample, check its accuracy. If it's over some threshold (say 20 meters) - ignore it.
Add a method that detects if the mobile is static or not. You can do it by reading the device's accelerometer - if the delta between two readings is bigger than some threshold - the car is moving. If it's too small - ignore the GPS. You'll have to try some values until you find the right threshold/
For question 1, vehicle odometer, in the US, are only required to be within 5mph of the actual speed at 50mph. My experience shows most vehicles are more erroneous than the law requires. That 10% difference could easily become the 1.5 miles you saw.
Vehicles odometers are allowed to over estimate in europe by 7%.
My car has about 3% over estimate.
There are simple solutions, that work for cars, that have been posted here on Stackoverflow multiple times, including by myself.
There is no simple solution for pedestrians.
Answer to question 2: problem certainly comes from the accurary of the GPS location.
Android Location object comes with an estimated accuracy for the given coordinates.
Suppose you stay in absolute position (0,0) without moving. The android device GPS could produce the following Locations stream:
(1,1) with an accuracy of 2m
(-2,3) with an accuracy of 5m
(0,0) with an accuracy of 1m
etc...
If you just keep adding the distances between the successive Locations, the sum will indefinitely increase, although you don't move.
One solution could be that you take into account new Locations from the stream only if their accuracy is small enough compared to the distance to the last location.
I asked a similar question about a year ago and was given some good advice (to use location.getAccuracy() ) and if the accuracy is under some threshold, not handle the location change. This worked well on my phone at the time but my new phone is all over the map (no pun intended) in terms of receiving location updates. Unfortunately, they are not very accurate and so if I look for an accuracy value of say, less than 7 meters, my logic inside the onlocationchanged handler isn't reached. As a result, when the points are plotted on my google map, it catches some and then draws a straight line over some terrain on my hike that I would love to be able to cover, but I'm pretty sure that not even Superman could. What really bothers me though is the fact that my distance calculation is significantly shorter than it really should be (which is obvious because it thinks I'm able to fly directly from point A to point B).
I tried to resolve this by keeping a tally of each time the location changed handler was called but didn't meet my threshold and if that tally reaches 20, log the point anyway then reset the counter. This got me a little closer to the actual distance, but still isn't very accurate. I've changed that value to 30, and 40 etc but it seems silly that I'd have to keep tweaking that to find a sweet spot for this one phone specifically. As a control test, I installed MapMyRun and its distance calculation is spot on and it is only using GPS location services as well.
I'm at a loss of what else I can do to get my distance calculations to be more accurate. It obviously can be done because MapMyRun works just fine.
Anyone have some suggestions as to other ideas to try?
TIA
How can I get an accurate speed from GPS in Android?
Yes, I am aware of the location.getSpeed() method in the Location class. Problem is, the default implementation returns 0.0 as speed: apparently that is the default behavior.
What I'm currently doing, is as follows, consider location objects a and b, where a is taken first, b later:
a.distanceTo(b)/(b.getTime()-a.getTime());
(simplified for readability, original code deals with history ArrayList)
Problem is that this is somewhat inaccurate: under normal circumstances, the data points are so close to one another that the GPS inaccuracy really becomes an issue. Either I would need to reduce the update frequency or calculate the speed relative to a point further away. The former I don't want to do, as I want to get as high a frequency as possible, but perhaps I could filter the points to calculate speed against based on their distance to one another?
The optimal solution, which I assumed the getSpeed() method would do, would be to calculate the speed against the GPS satellites themselves, thus getting a more accurate result.
Am I using the getSpeed() wrong somehow?
Since your keeping a history why not...
Get the current location and time
Find the speed between current and last ~10
Take an average of your results
Use the formula you stated to determine average speed but makes sure your two points are in a straight line. You could see if the user is still traveling in the same direction by calling Location.getBearing(). If it is close enough you could assume they traveled in a straight line. If not just discard the result.
Keep in mind this speed will be affected by any stops such as stop signs or stop lights. Sample as often as possible and discard any obvious outliers.
The emulator apparently always answers 0 as speed, but the real device
should not. Do you have the same issue on the real device? – Stefan
Mar 20 at 8:21
Stefan's answer was actually correct. Apparently the emulator does not give the speed, as that's not contained in the GPX file input as the testing data. So if you want to show speed, test on a real device and go for a jog, it'll work (for most devices).
Below are some thoughts for other methods of detecting speed, but not strictly relevant, but might be interesting if you're working with GPS.
Due to the relative inaccuracy of GPS, particularly at slow speeds or curvy roads the speed is hard to calculate: either the distance between data points is so short GPS inaccuracy comes to play, or so long it becomes inaccurate when not moving straight. Also, if the minimum distance between data points to calculate speed is long, at slow speeds the update interval becomes a problem.
There are ways around this problem, such as using the getAccuracy() method to calculate minimum safe distance between data points and using it dynamically, filtering data points based on maximum acceleration and deceleration values, movement direction and so on. You can also calculate a rolling average to calm down the changes a little and get a pretty good idea of what's what.
The above methods may be useful also even if you don't calculate speed based on distance covered, as sometimes the GPS seems to return speed as 0, even when you're moving. I used acceleration/deceleration figures from F1 cars as filters :)
Is it possible to get the location of the building shown in the Camera view using Augmented Reality in Android??
I have the GPS coordinates of the mobile but now i want to get the GPS coordinates of the building shown in the Camera view???
Please suggest me some ideas?????
If you have the GPS coordinate of your mobile phone and the direction (using the compass of the mobile phone) in which it is hold, you could use some trigonometry to approximate the location of the building. The remaining problem is that you have to somewhere estimate how far the building is away from your phone.
But if you assume for example that you're always walking in streets and the point to a building, it should be easier to find the building.
I would not depend on the compass output, it's always in question.
What I did was use Gogle maps, get a location fix, draw the point on the map (if you want to draw a line use bearing that would be a better hint I guess) then let the user draw or adjust the line using sattelite view to pinpoint the target. You can then get the new geo-coord and get a fairly accurate bearing ( if that's required )
I would also suggest using both the network and gps provider, in cities sometimes the network provider is more accurate than the GPS if the glass/metal canyon is preventing it, even a couple of hundred yards can get you close to your position.
Anyway it's a somewhat manual process but it's more reliable then trying to guess distance and hoping the azimuth is reliable (rarely is)
let's say i want to build a smartphone app that tells a user when/where to get off a subway station. i can think of two ways of doing this:
1) using GPS and map of the subway routes, track the location of the user and notifies him when the destination is reached
2) have him press start when he gets on a train as the train starts (which may not be realistic because the user could simply forget to do this), use the known travel time from starting station to end station, and simply notifies him when the time is up.
can someone tell me if there are any other good approaches? thanks.
You may have to go with 'dead reckoning'. Basically, dead reckoning is a navigation technique that uses a confirmed starting location plus accurate velocity and time to calculate a new location. Keep in mind that velocity is itself a combination of heading and speed and that the heading must be a true heading. In an airplane, compass heading would have to be combined with wind speed and direction to get a true heading. I don't think you have to account for drift on a subway, but you will have to account for varying device orientation as the user moves around or uses the device itself. Also, just because heading is normally a compass bearing doesn't mean that it has to be. You may be able to get the job done using only the accelerometers and a timer.
Proper use of dead-reckoning also requires frequent 'resets' to known locations as you reach them so that errors can't add up too badly. For this application, I would argue that curve- and stop-detection can be used as resets. You may get false positives for 'service' stops that are too close to real stops, but those may be rare enough to ignore. In fact, if it wasn't the exit stop, it might not matter because you might still be accurate enough for the next-stop warning and if was the exit stop, it won't matter because the ride is over.
To summarize: you need to be sure that you have a good initial starting point; you need to compensate for device reorientation to get true heading; you need to know your average speed between heading changes and the time-on-heading to calculate distance-on-heading. You can improve overall accuracy by resetting at known landmarks.
Edit: I don't know if this gets you any closer to the answer, but Chris Stratton raised an interesting point about summing the accelerometer vectors. Is it possible to track the orientation of the device accurately enough to have a reliable orientation-independent gravity vector? Can you keep that out of your vector sum? Can that provide a useful acceleration along a useful orientation-independent vector? If so, then tracking the duration of the acceleration will get you an average speed for that duration and a final speed for the end of acceleration. Absent acceleration, the speed will remain constant. Putting that all together might pile inaccuracy on top of inaccuracy to the point of uselessness.
If the subway line has cellular service (some that were going to had it turned off on security concerns) you might be able to do something with network location.
You could use the accelerometer to try to detect and count station stops - but trains stop in between stations from time to time due to delays ahead. Also battery life would be reduced. EDIT: realized you won't be able to tell acceleration from deceleration as you have no idea of orientation (unless you find the compass sensor workable in that environment) - you could only see that the vector sum of the three accelerometers was greater than gravity for a period of seconds.
You could try to use the microphone to detect the sounds of train motors and brakes (some are extremely characteristic) but that has the same problem with battery life and unscheduled stops between stations. Not to mention scheduled stations bypassed for repair work.
Perhaps you should give the user a scrollable list of stations marking the journey and let them keep track.
Both of those sound like poor solutions. You almost certainly won't get a GPS trace in a subway. And the 2nd way sounds like it will be inaccurate enough to make the app useless.
Read carefully Falmarri's answer. He's completely right, although he didn't give you an answer. Let me try then...
If the routes have no many curves, it will be easier: you just have to hardcode the latitude and longitude of each station, and then, calculating the position of the user will be straightforward (just a little of math and that's it). If the routes have curves, then you have more work to do but it's basically the same.
You will probably want to use a way to know the distance between the current location and the station location. You could use some of the existing algorithms, for instance the Haversine formula.