Can anyone figure out why this guy's IMU AHRS code results in all 3 axes drift?

This is the code I'm talking about:

I'm using it on an Arduino Micro and a Pololu MiniIMU-9 v3. I even went out and bought a second MiniIMU because I thought there was something wrong with my first one, but I still have the same problem. All 3 AHRS axes, roll pitch and yaw, drift by anywhere from 0.01 degree per second to 0.1 degree per second, constantly, in one constant direction, while the device is sitting perfectly still on a table. If I leave and come back 10-15 minutes later, I'll find the AHRS thinks the device is now upside down.

This is not a calibration issue. I have used both his magnetometer and accelerometer calibration to perfection, and I know I've got them perfectly calibrated because I've outputted the calibrated magneto and accel axes and plotted them in a scatter plot, and they draw perfect centered circles, whereas the uncalibrated axes show slightly offset and ellipsoid circles. And besides, calibrating it made absolutely no difference to the drift whatsoever.

I know it is possible to eliminate drift, because the Official Pololu AHRS code results in 0 drift after 15 minutes of leaving the device still. I come back and all 3 axes are exactly where I left them. But this official code is noisy and laggy - it goes up and down by about a degree or so constantly (the noise), and when you quickly rotate the IMU, the AHRS will "snap" to somewhere close, then finally zero in on the exact location about 5 seconds later - no good for a headtracking device. Whereas the code that I'm here trying to get working is much faster - you rotate the device quickly, and the AHRS instantly snaps to that location as well. The only problem is the constant drifting of all 3 axes never goes away.

I also know it is possible to eliminate drift with this guy's code, because someone else in the "issues" section of the Github posted this image:


Noisy on the order of about 0.2 degrees, but no drift. Whereas what I'm getting with the exact same code and IMU looks more like this:


After 500 seconds, everything had shifted by 20 degrees or more.

Even the yaw axis! This is supposed to be the one that is tied to the magnetometer. It's supposed to act like a compass (and does, on the official Pololu code), it will even read the same value after rebooting the device, never changing because magnetic north is never changing.

I really want to use this guy's AHRS code, because it's so much faster and snappier than the official Pololu code. And I know it's possible to get it working right, because A) Pololu themselves recommended it, and B) someone on the github showed a sample readout that didn't drift at all unlike mine. I do know that the code is written for 3 slightly different versions of the MiniIMU-9, some operate at 75hz whereas others at 100hz, for example. And it was originally written for the v2, but only later updated to also work with the v3. But I've tried messing around with every single variable in the code, even forcing it to recognize my device and eliminating the others, with no luck.

I have tried:

  • Buying a new MiniIMU-9 v3, to make sure mine wasn't malfunctioning
  • Using an Arduino Uno instead of an Arduino Micro
  • Different rooms of the house
  • Different computer to both upload the code and monitor the serial output
  • Different USB cables
  • Different breadboard, in case mine was magnetized somehow
  • Calibrating the bejeesus out of it
  • Randomly changing variables like the sensor scale, timing delays, calibrations, and AHRS filters

But I cannot for the life of me get it to work as well as the author and other users have gotten it working.

Why waste the time?

By far the best available open source AHRS code is RTIMUlib. You can read about my experience in implementing it here: State of the art AHRS for $25 - Sensors - Pololu Forum

jremington: Why waste the time?

By far the best available open source AHRS code is RTIMUlib. You can read about my experience in implementing it here:

Hey thanks! The link to the RTIMUlib on the forum post you linked just seems to link to his main webpage, I can't find anything about IMU or AHRS or RTIMUlib on his page. Is this the same code you were using?

EDIT: Well I tried it out, and nope, it's just as bad as the official Pololu lib - laggy and noisy. I don't care so much about the noise, but the lag makes it unusable. Just look at this example:


I make a couple big movements, and look how long it takes that red line at the top right to finally stabilize! That means if I'm trying to use this as a headtracker, and I move my head, my view in game will snap most of the way there, then spend the next 10 seconds or so slowly moving another 2-3 degrees. That's no good. Although it looks like messing around with the "slerp" value affects the speed at which this adjustment happens, whereas the tradeoff looks to be even more noise.

I did not see any significant lag or instability in my experiments. Try a different sensor.

It is essential to ACCURATELY calibrate both the magnetometer and accelerometer, and verify that the corrections are correctly applied.