Repository navigation
Heading without trusting the compass
Get the position right and the heading wrong, and your AR overlay is still useless — worse than useless, because it points confidently in a direction that does not exist. A navigation arrow off by 30° sends someone down the wrong path with no indication anything is amiss.
The obvious source for heading is the magnetometer. It is also the least reliable sensor in the device.
A phone magnetometer measures the local magnetic field, which is the Earth's field plus everything else nearby:
- Hard-iron effects from the phone's own speakers, vibration motor and battery — largely calibrated out, until a magnetic case is attached.
- Soft-iron distortion from the environment: cars, railings, reinforced concrete, street furniture, a laptop on the table beside the user.
- Magnetic declination, the difference between magnetic and true north, varying by location and slowly over time. Real, correctable, and frequently forgotten.
- Calibration state. The famous figure-eight gesture exists because the calibration genuinely lapses, and the API rarely tells you it has.
Outdoors near a steel structure, errors of tens of degrees are ordinary. The sensor reports them with the same confidence as a correct reading.
There is another way to know which way the world faces, and it is already in your data.
The AR session tracks the user's motion precisely in its own local frame: "you moved 8 metres along local +X". GPS, meanwhile, reports where that motion happened on Earth: "you moved 8 metres roughly north-east". Those two descriptions of the same walk are related by exactly one rotation — the heading you are looking for.
One pair of readings gives a noisy answer. Accumulated over a short walk, with outliers rejected, they give a good one. And unlike the magnetometer, this estimate is immune to every source of error listed above: a steel railing does not change how far you actually walked.
The trade is that it needs motion. Standing still produces no baseline and no estimate, which is why the compass remains useful as an initial guess — good enough to start with, replaced by something better within a few metres of walking.
- Seed from device orientation. At session start, the compass is all you have. Use it, and treat the result as provisional.
- Refine from motion. As the user walks, the odometry-versus-GPS correspondence constrains the heading far more tightly than the magnetometer can.
- Do not fight the estimate. Once motion-derived heading is available, the overlay should stop depending on device-orientation readings rather than averaging the two — a bad compass reading averaged with a good estimate produces a slightly bad estimate.
- Correct heading like any other alignment change: gradually, and preferably while the affected content is off-screen. A rotating world is more disturbing to look at than a translating one.
Position and heading fail in different ways and users react to them differently.
A position error of two metres is often invisible: the label is on roughly the right bench. A heading error of ten degrees is invisible at two metres and badly wrong at fifty — errors in angle scale with distance, so the same mistake is trivial nearby and disastrous across a field. For any experience that points at something far away — wayfinding especially — heading deserves more of your engineering attention than position does.
Motion-derived heading needs a walk, and some experiences need to be correct at the first frame. That is one of the strongest arguments for anchoring to a printed marker: solving a marker's pose yields position and orientation at once, from a single detection, before the user has taken a step. The pose solver and the vote builder for this are implemented and tested; assembling them into a running app is not done for you yet.
Start here
Building with it
How the alignment works
Testing & debugging
Perception
Shipping it
12 more pages — see the page list above.