I'm developing an app which uses augmented reality and GPS data in order to improve the True North accuracy of the device.
Currently, iPhones have a True North accuracy of about 15º at best, which is fine for displaying a heading on maps, but not good enough when you want to overlay things onto the world using Augmented Reality. As the AR "scene" can be aligned to gravity and True North, I thought I could use the GPS updates as the user moves through the world in order to improve the True North accuracy, down to perhaps within 1º of accuracy.
Each time a new coordinate is received, about once per second, I store it along with the user's current position within the AR scene (measured on a x/y/z axis). After 10 seconds, if the user has moved in a straight line, I'm able to compare the user's position 10 seconds ago with their position now, in order to determine their bearing, and I can compare data points across that span of time to ensure they walked in a straight line.
Knowing that they did walk in a straight line for 10 seconds, and their bearing, I can theoretically take their GPS coordinates from the readings across the same period and take that bearing. Thus, I can then measure the angle of difference between the user's bearing and the GPS bearing, and know how inaccurate the user's bearing is.
The problem is that the GPS data is a lot more zig-zaggy. Here's a screenshot from a period when I was walking in a straight line, along a pavement.
The green circles on the map represent each recent location estimate and their range of accuracy (in this case about 25m). The yellow line is the route between each of those GPS points. The other data shown can be ignored - green icon is the most accurate GPS estimate, and the orange icon is where the user is presumed to be based on that estimate and their movement since then, with the blue line just being a line between those points.
I've used a few techniques to try and get the true bearing of the GPS path, but because of inaccurate data points, like the point where it suddenly jumps north incorrectly, that throws off the average bearing.
So, the data I have:
- I know the user has moved in a straight line for the past 10 seconds (and indeed in this example for more than 15 seconds before that)
- I have a coordinate for the user's location, taken every second
The 25 most recent coordinates:
lat: 51.481508456031484, long: -0.014432226002130824 lat: 51.481507477162651, long: -0.0144049132597354 lat: 51.481506884611207, long: -0.014389807458603288 lat: 51.481509960771142, long: -0.014373092399400777 lat: 51.481507855339153, long: -0.014348176495456588 lat: 51.481509945317967, long: -0.014317286536546627 lat: 51.481505189244366, long: -0.014294481275542248 lat: 51.481506703609959, long: -0.014272413434476617 lat: 51.481505235807262, long: -0.01425324957115618 lat: 51.481498779846952, long: -0.014239295878236219 lat: 51.481501712942894, long: -0.014214523322743366 lat: 51.481508305052301, long: -0.014194804404044298 lat: 51.481512575463469, long: -0.014166769148728857 lat: 51.481519965341164, long: -0.014157078200848361 lat: 51.481521638215781, long: -0.01413473757481863 lat: 51.481520698352988, long: -0.014114195453429512 lat: 51.481518763912348, long: -0.014092665529632791 lat: 51.481516373462448, long: -0.014073392691598534 lat: 51.481517130888442, long: -0.014052945595763552 lat: 51.481522471260533, long: -0.014031560984244714 lat: 51.481519806277156, long: -0.014018366235482322 lat: 51.481521076237108, long: -0.0140037919026139 lat: 51.481522270228304, long: -0.013984366007679964 lat: 51.48152335719741, long: -0.013964033303506903 lat: 51.481522384989098, long: -0.013942519179059738
Goal: Use 10 of these points to find an average bearing of the route, which isn't made inaccurate by the outlying results.