I have here a device which can give me GPS coordinates. The time interval I can define. I want to use it to calculate the average speed during driving or travelling by car. Actually I used a orthodrome formula to calculate the distance between two points and then divided it by the given time interval. By the implementation I followed this term. Unfortunately I could only find a German link, but I think the formula should be understandable in any language ;)
Unfortunately, using this formula and a time interval of 1 second gives very unprecise results. The speed while walking is between 1 km/h and 20 km/h.
So I wonder if there is a general reference on how to implement distance calculation between two GPS coordinates (I found something similar on SO) and particulary, which is the best time interval to update the GPS coordinates?
I assume that you're testing this by walking at a constant speed (I think ~5 kph is a normal walking speed) while measuring your GPS position once per second.
The variation that you're seeing in instantaneous speed (the distance between each measured point divided by 1 second) is either due to random variation in the measured GPS position or else you aren't taking your measurements exactly one second apart (or it could be both of these things).
I'm going to assume your measurements are being taken precisely one second apart. Hand-held GPS devices are much less accurate than advertised. While it's often claimed that the devices are accurate to within 10 ft. of the true position, this simply isn't so.
The best way to measure and report the accuracy of a GPS device is to leave it in a place where it can see the satellites and not be rained on, and record a few day's worth of data. You can then use Google Maps to plot the points - I've done this around my house and around the office, which is a good way to give you a sense of scale.
Obviously, if the devices were perfectly accurate, you would see all your measured points in one spot. Or, if the 10 ft. accuracy thing were true, you would see all the points in a little cluster inside a 20 ft. diameter circle.
What you see instead (with every GPS-enabled device I've ever tested) is a combination of relatively small positional scattering (on the order of a few tens of feet) occurring on a scale of a few seconds, and a longer-term "random walk" of the average position which might move 200 or 300 ft. in the course of a day or two. When plotted over your own house, for example, it might look like your PDA wandered over to the neighbor's house, then across the street, then down the street two houses, back towards you etc., all while jittering around 5 or 10 feet here or there like it drank too much coffee.
GPS can be more accurate than this. Surveyors use devices with much more powerful receiver sets (so they get a much more accurate read on the satellite signals), and they leave them in place for days at a time to average successive measurements. Handheld devices have cheap receiver chips and cheap antennas and have to deal with all kinds of signal interference anyway.
Your best bet is to do a running average to calculate your instantaneous speed. Instead of dividing the distance between the current point and the previous point by 1 second, take the last 5 distances between points and divide by 5 seconds (or whatever number of seconds you use). It's important not to just take the difference between the current point and the point 5 seconds ago and divide this distance by 5, as that would miss any non-linear movement.
Update: I noticed in a comment that you're using an Android device. Do you know if it has a built-in GPS receiver? Many (most?) Android devices don't, which means their GPS is not the triangulate-on-the-satellites version of GPS, but the guess-where-I-am-based-on-the-signal-from-the-cell-towers version. This is much less accurate positionally, as I'm sure you could tell from the snarkiness of my description. :)
GPS systems can yield instantaneous velocity directly, without interpolating positions. I read somewhere that the velocity reading is actually more accurate than the position reading. What device/system/OS are you using?
On Android, try the android.location.Location.getSpeed() method (along with hasSpeed()) in your LocationListener implementation.
Search on google for GPS SPEED ACCURACY, and you will find reports stating that speed calculated out of position-vs-time is ten times worse than just using the speed parameter coming right out from the GPS receiver. The speed parameter is not depending on position accuracy, but is calculated out of doppler (speed/frequency difference) from the satellite signals.
Good luck
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.
Geolocation is very approximate, especially in buildings.
For example, behind thick concrete walls my sensors on mobile phones show me that i'm moving up to 3 meters when the device is on the table motionless .
Which makes accurate calculations impossible in the areas which are not in the open streets.
What I think - I can make an array of 20 geopoints in 20 seconds and get average speed, but what data should I use?
If I take 19 distances from this array and divide them by (lastTime-firstTime) - I wouldn't get the average speed because of it can "jump" 3 meters without really moving, so the result will be totally wrong in obscured areas.
So , I can take a distance between first and last geopoints and divide it by (lastTime-firstTime), but... the results will be correct only if a person move perfectly straight. If he would go 10 seconds straight and after that turned right - distance will be not the real distance he walked - the sum of two cathetuses , it would be the hypotenuse of this triangle. So, this is not the way of calculating the real speed.
What I need (I suppose) is some complex algorythm of an approximated straightened route that would be gathered into some array of correctedDistancesand we can find a more or less true speed using them?
Like the picture shows - red is the data we get from the sensors, and black lines are the approximate real route of a person by which we can calculate more or less faithful speed.
But may be there is already a ready-made algorythm or formula made for such tasks? I don't mean google maps or any other, just a plain formula or algorythm (may be there is much simpler logic for that than I imagine)
I hope I'm asking this at the right part of Stack Exchange. Please bear with me if I'm wrong.
I'm developing some gps based applications. The demands I have for precision are not very high, but I need to know the possible errors.
I have learned that the fourth decimal gives you ~10 meters precision. That should be enough for me.
The real question is how fast will I get that precision realiably in different environments (indoors, outdoors free sky, forest, cloudy, city etc).
The applications I'm developing is for handheld devices so I prefer to have the gps active in as short intervals as possible.
As I do now, the intervals I use the gps are more governed by battery life than precision. Now I'm trying to balance the two.
if you have good view (no major obstructions like high buildings) to sky, with A-GPS 20s, normal GPS 30-45 seconds.
If you have bad view, it can take much longer.
However you better check that the timestamp of the location is a recent one, (time diff to current time is small) and that horicontal accuracy (Location.getAccuracy()) is not horrible:
check for < 20m, if you check for 10m you may loose many positions especially in the first minute.
You shouldn't wait for some number of seconds and assume that that's enough to get a GPS fix. Instead, when you get locations from location manager, check the result of Location.getAccuracy() and wait until that returns a number less than 10 meters.
I'm building a small yacht racing app to measure my speed upwind, where the speed is relatively low, in the 6-10 knot range, and where the inherent GPS positional error is causing significant fluctuations in reported speed (which is why I'm going to this effort instead of using a hand-held GPS unit).
So, I'm trying to smooth out the errors by calculating the speed over longer periods of 5 and 10 calls to the onNmeaReceived event (which occur by default at 1000 ms), using the NMEA lat/lon and time from the $GPRMC sentence.
When comparing the NMEA reported speed to the speed computed since the previous event I find they are significantly different, so I'm wondering how the NMEA speed provided in the $GPRMC sentence is computed?
Possible answers could be
Deduced from GPS Doppler speed ?
calculated as distance/time over the previous second?
Or something else....?
The documentation is entirely silent on this matter.
Using Android 4.0.3 Samsung SGS 11
speed in GPS comes from Doppler Effect, which is much more accurate than the position itself. ( this works only when the device is moving, the faster, the better)
Determing the speed from location change related to time, does work for GPS only for higher speeds. (> 10 km/h).
Same applies four "course" (heading).
These values always come from the GPS chip, although hardly documented on API side.
averaging over the last x calls is a bit to simple, it should be over the last x seconds. if you dont get a position, you still have to close the averge window. when the device stands still, some devices do not report any position, so you cant wait to get exactly x events.
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 :)