How can I calculate an average speed in geolocation on mobile devices? - android

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)

Related

Accurate distance with GPS?

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.

How to calculate distance while running on Android?

I understand that there are three approaches for it
GPS Based: Add up short distances travelled (calculated using Location.distanceTo) in small time intervals (5-10 secs), but this method is prone to GPS errors and would not work indoors or in short running area (like a small park)
Double Integration of acceleration: I can do double integral of accelerometer data to calculate distance but errors due to noise in accelerometer readings may add up.
Step counting: I can detect steps by measuring spikes in accelerometer data OR using Google Fit API and then multiply the total number of steps with the average stride length. But the problem here is figuring out average stride length.
I am inclined towards using #3 as it works indoors and is not much error prone OR battery draining. But How do I get average stride length for each step, especially when runner's stride varies in length when sprinting and jogging.
Does anyone know of any combination of these methods to get the best results? OR any other totally different but efficient method?
Well it's engineering - there is no simple answer ;)
All these methods you've mentioned has their pros and cons.
GPS tracking won't sumarize errors of each measurement - it's great but on the other hand each location will be given with noticeable error. What is more you'll have problems with using your app in buildings etc.
Double integration of acceleration works great on small distances by the time error grow to big number. It is also difficult to create program which will calculate it in appropriate way. There is a lot of important issues like e.g time of sampling or rotation and translation matrix calculation that makes these application very problematic on android.
In my app I used following algorytm:
Calculate location from GPS (from Network provider or GPS provider - best precision wins)
Start using accelerometer-based algorytm.
Stop using accelerometer-based algorytm when:
GPS and accelerometer measurements are very different
Accelerometer-based algorythm finds that calculated quaternions are different from what magnetometer says.
The velocity or acceleration from measurments is bigger than given value.
Go to point 1
Hope it helps

Finding the direction between two bluetooth devices (localization)

I have an app that scans for a specific UUID that another phone is broadcasting and measures the signal strength between them and tells you whether you're getting closer or further away from them. I want to add an arrow for direction. I know you can use triangulation if you have 3 points but I want to get something somewhat accurate with 2 points.
Any algorithm or suggestion that would help?
My current idea (since for this app's use case one node will be relatively still) is to have some algorithm learning as you walk. Like if you get further away the arrow knows to disregard this direction and keep refining itself as you walk different directions.
I found a bunch of research papers on the topic but I'm not an electrical engineer so it's easy to get lost. Also I read this post and understand the many pitfalls How to measure distance between two iphone devices using bluetooth?
Thanks!
Such a solution is extremely convoluted.
Getting the direction of the signal requires far more data than normal app usage can provide. The user would have to slowly rotate the phone while taking many samples of all directions.
Getting the relative distance, as you said like "getting closer" or "going farther away" is kinda possible within a 12 meter range using the formula posted below. Above 12 meters it gets very buggy. But it's quite complex and requires you to use a moving average solution with a length that you consider adequate.
You can calculate the relation between RSSI and distance using the following formula:
RSSI = -(10*n*log10(d) + A)
In this case,
n = path loss exponent, since you don't want an exact distance, just a way to check if it's closer or further, you can use 2 as a value, I found this the most realistic one in most cases.
A = the measured RSSI value at 1 meter distance, you need to measure this in advance to do your calculations, but since this varies a lot, just use a value like -60dB. Also this one is about average in most situations.
So getting a crudely guessed distance in meters can be achieved by the formula:
distance = 10 ^ ((-RSSI - 60) / (10 * 2));
This isn't very exact but will be sufficient to tell you if it is closer/farther within a limited range.

How to get the most accurate possible speed from GPS in Android

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 :)

Best practice to calculate the average speed from GPS coordinates

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

Categories

Resources