views:

95

answers:

2

I'm working on a fairly simplistic trip application for the iPhone for use when running, biking, etc.

One of the features I'd like to implement is an odometer.

I'm getting the location periodically via didUpdateToLocation.

I've tried measuring the distance between newLocation and oldLocation and accumulating the result, but this is not very accurate. The accumulated value is generally much greater than actual distance traveled.

What algorithm can I use to improve the accuracy of this calculation?

+1  A: 

It sounds like poor GPS signal is moving the (reported) location of your device all over the place, which your app interprets as the user constantly changing direction. Perhaps it would help to separate the movement from one location to the next into its x- and y-component, and run them through some kind of low-pass filter. This should minimise the effect of "bad" updates that have the effect of moving your location completely out of your actual path.

L Cassarani
A: 

I'm trying to figure this out and think something can be done with the CLLocationManager distanceFilter property. The property lets you limit didUpdateToLocation delegate calls to updates that are at least a minimum distance from the previous update. For example with the odometer problem, say you're standing still but the gps is erratically reporting positions 1m around you. If you set the distanceFilter to 2, then none of these updates will be registered as movement.

The trick is to find a value of distanceFilter that works, and I believe this is somehow related to the horizontalAccuracy of the GPS (which I assume is the cause of the erroneous updates) and the speed at which you're traveling. The horizontalAccuracy should be good with outdoor activity, but the assumption is that these little inaccuracies accumulate and cause the incorrect odometer reading.

If each call to didUpdateLocation introduces a small amount of error (say, up to 10cm per reading), then it makes sense a slow activity such as walking will be grossly inaccurate if a call were made each meter to didUpdateToLocation. That would be up to (10cm/1m=) 10% of error per update. If this were done in a car traveling at 100km/h and the distanceFilter were set to 10m (which is a safe setting since a car traveling at 100km/h will drive very close to a straight line over 10m), then that same error of 10cm will only have a maximum of (10cm/10m=) 1% error per update. It's probably more complicated than this, but I'm trying to illustrate that speed plays a role.

I think the solution is to pick a value for distanceFilter that minimizes erroneous updates, but most importantly takes into account the speed of the user (such as with the car in the previous example). Anyone want to figure out an algorithm or formula?

chris