Fixing berserk rotations in Mapper

Maemo Mapper has a nice feature which is called "automatic rotation" and consists in automatically rotating the map so that the direction you are going to is always oriented toward the top of the screen. The direction information comes from the GPS device, and applications can access it from a liblocation structure.
Unfortunately, while this value is rather reliable when you are moving fast, it's totally pointless when you are not moving: and this can be easily seen in the alpha versions of Mapper, when the map starts spinning crazily as soon as you stop moving. One thing that I didn't notice is that besides giving the direction, liblocation also gives the estimated error: the epd field in the LocationGPSDeviceFix structure represents the error on the angle, as a value from 0 to 359. In my opinion it doesn't make much sense to have an error greater than 180 on an angle, so I assume that it must be divided by two.

In the image on the right, the epd is represented by 2 × β. Now, if v⃗0is the current direction the map is oriented towards, and v⃗1 is the new direction reported by the GPS with an error (uncertainty) of β, how do we decide if (and how much) we should rotate towards v⃗1?
The algorithm I've implemented goes like this:

  • if β is greater than 90°, ignore the information altogether (i.e., don't change the rotation). Or,
  • if α (the angle between v⃗0 and v⃗1) is less than 5°, then let the map rotate to v⃗1. Or,
  • rotate towards v⃗1 by γ = α × (90 - β)90, that is the rotation is limited according to the error.
I've been testing the algorithm in the last few days, and it is indeed a huge improvement over the previous situation: now the map does not rotate while I'm not moving, or it does fairly seldom. But still, the map almost always rotates once just right after stopping, and not by a small amount, which is pretty annoying as it means that most of the times when you pause you'll have the map wrongly oriented — and pauses are usually the very moment when you'd look at the map...

I'll investigate this a bit more; this means that I'll have to keep a terminal window open with a view on the syslog, while using Mapper :-)


There's also webmention support.