Friday, March 9, 2012

AVC: Is a 3D Compass Necessary?

As you may know, I'm working on Data Bus, my Sparkfun AVC robot (in case you missed it, I'm now officially on the active participant list!)

Having evaluated a couple of AHRS (attitude heading reference system) solutions, and after wondering if a compass was even necessary at all, another fundamental question arose. Suppose I do use a compass...

Do I really need a 3D, tilt-compensated compass in the first place? Or can I get away with a much simpler 2D compass? How much heading error can I expect from a 2D versus 3D solution?

Scott (Team Tobor), AVC winner for the last two years, employed a 2D compass heading calculation. Of course he also fed this value into an Extended Kalman Filter (EKF) along with odometry heading calculations.

What should I do? Time for more math, Octave (Matlab), and Gnuplot fun. Let's figure this out...


I'm not building an airplane, I'm building a car that will drive on relatively flat ground. That's important because it's substantially easier to compute a 2D compass heading than a 3D one for a moving vehicle.

A 2D heading is calculated by taking the arctangent of the ratio of the y-axis and x-axis readings: atan2(mag_y/mag_x). That's really easy.

Computing an accurate 3D compass heading for a moving vehicle requires an orientation estimate which relies on an IMU and complex algorithms to fuse gyro and accelerometer signals. In some cases one must consider the effects of acceleration on the accelerometers.

Is it worth the effort? I mean, how bad can the error of a 2D compass be?

Let's say the maximum tilt of the sensor with respect to "level" is 10 degrees of pitch. What's the error of a 2d heading for a range of true headings from 0 to 180 degrees?


I wrote an Octave script that iterated from 0 to 180 degrees of actual heading and computed the error between actual heading and 2d heading for a range of vehicle tilt angles.

How to model this?  Start with a magnetic field vector of magnitude 1 pointing north and  rotate it by 50° of pitch to represent magnetic inclination. Then rotate it counterclockwise about the z-axis in the direction by the true heading.

The result is the normalized vector that would be read by our simulated magnetometer. For example, if the magnetometer is at a 45° heading, the vector will point approximately 50° down and 45° counterclockwise. In other words, this new vector is the magnetic vector is expressed in the sensor frame of reference.

To simulate a pitching magnetometer, I rotated the magnetic vector about the y-axis, then calculated the heading using only the x and y components of the magnetic field vector. Finally, I determined the error between the actual heading and the 2d heading.

A maximum error of less than half a degree at multiples of 45° heading. That's not too bad. How about 10° of pitch? Not surprisingly, a similar plot, shifted by 180 degrees.

Suppose we look at 10°  of roll and 10° of pitch?  In Octave, I multiplied the magnetometer matrix by a y-axis rotation matrix then an x-axis rotation matrix.

Here the error is about 1.8° and the maximum error occurs at 90° and 270°. Naturally, I'm curious about the relationship between tilt and error. How much tilt can I get away with before errors get too high?

Below is a plot of heading error versus heading versus tilt, with tilt values of 0-10 where roll=pitch=tilt, and heading from 0 to 360 degrees.

Let's focus in on just pitch+roll angles versus error for the maximum error at 90 degrees heading..

You can see that above about 10 degrees, error starts to grow pretty quickly.


Somewhere around 5° is probably a safe limit and that's a lot of tilt. It even looks steep. A 6% grade is only a 3.4° while 5° would be an 8.7% grade. In fact, I surveyed the slopes at the Sparkfun building parking lot; they looked terrible, but the angles are generally 3° or less.

Informal SFE site survey, most angles are 0-3°
Even if the combination of ground tilt and chassis pitch and roll stay under 10°, then heading error still will be less than 2°. Most digital compasses already have an accuracy of only about 1-2° under ideal conditions.

But that's not the whole story because the compass isn't the only possible heading sensor anyway. In fact, relying on compass as the only heading sensor is probably unwise as it's subject to local field disturbances from ferrous objects like the drainage covers on the sidewalk around the SFE building.

Source of compass distortion. Don't drive too close!
So one can use odometry and/or GPS heading information. Typically, a gyro measures heading changes and the compass and/or GPS provides an absolute reference to correct gyro drift very gradually.

In such a scenario, tilt will have a less significant and less immediate effect on heading error so that, for brief maneuvers or short stretches of uneven ground, the error may be acceptably low.

Here's the Octave script if you're interested: TiltCompTest.m


  1. Great thorough analysis. Certainly seems like tilt-compensation isn't needed for this application. But there's also what looks like a neat product that does all the math on-board to provide tilt-compensated output for about $35: That way you don't spend $100's and you don't add the additional trig processing to your main controller. I've never used one, but I've bought one to play with soon. I'd love to know if anyone's used one of these and what their experience has been.

  2. @ViennaMike: Thanks! That's an interesting device. Looks like a PIC16F on the board? The only downside is the linear and centripetal acceleration but one could simply ignore the compass during turns and when accelerating/decelerating and use it to compensate for gyro drift only when heading rate is < some value. Hmmmmm....

  3. P.S. Don't forget that your vehicle's electric motor (which probably has permanent magnets in it) is going to generate a magnetic field that can significantly impact your readings and will vary to the point that you can't do simple measurement compensation for it. You usually have to physically separate the sensor from the motor by many inches.


  4. @Dean : yes, good point. Don't worry, I didn't forget :) see: