Getting "yaw" bearing

If there’s one thing that’s popular these days, it’s quadcopters, and one of the obstacles in making a quadcopter is making it balance by obtaining roll and pitch. A simple google search will flood you with information on simple complementary, Kalman, Mahony and Madgwick filters. But what happens when you want yaw? After a bit of searching online and complementary filters (which were good enough for my application of a omnidirectional four wheeled robot), I couldn’t find a single source pointing to how to fuse gyro and magnetometer data together, and so I endeavored to approach the task from scratch. Currently, I’m using a LSM9DS0 but this should apply to all 9DOF imu’s.

Perhaps the best explanation of the complementary filter can be found here [Update. Link doesn’t work but should still be accessible via waybackmachine] which is a must read. Now, usually accelerometer input is used to compensate for gyro drift but instead we’re using the magnetometer.

LPF diagram

So we have

To obtain the bearing/yaw from magnetometer data, you simply get the x and y components of the magnetometer and find the angle of the vector that is created by it’s sum. In other words (you’d have to use atan2() function when programming)

Naturally, then when working in degrees.

Here’s where the first issue arrives. When numerically integrating the gyro data, the range of yaw purely from gyro data is not limited. Furthermore, the complementary filter essentially “weights” the gyro and magnetometer data, and so when “weighting” the data, it is necessary for both estimates to be of the same form. For example, the gyro data may be saying the while the magnetometer data says . Though they’re only 2 degrees apart, the software cannot tell. The software must then make sure that the integrated yaw is in the same form (same sign) as the magnetometer yaw.

So there’s my first blog post! Also make sure you calibrate you’re magnetometer. Instead of writing a lengthy post on implementation, this page explains it well enough. I’ve also seen calibrations methods involving complicated matrix transformations and inverses etc. to correctly to transform elliptical 3d shapes to spheres but a simple 2d scaling and translation calibration method works for me.