I've recently purchased the MPU9150 IMU from InvenSense. Testing it, I'm astonished to see that, at rest, it constantly output 0.25 °⋅s-1 around the Z axis, -0.5 °⋅s-1 around the Y axis and -1 °⋅s-1 around the X axis. Is there a way to correct this ? Is this really normal ? I know there is a drift coming from gyroscopes, but with such values this will lead to enormous error in a few minutes…
Electronic – Gyroscope bias on the MPU9150
gyroimu
Related Solutions
I like your graphs. They clearly show that roll, pitch, and yaw seem to be working. Congratulations! That's already more progress than most people make.
I'm guessing that the code you presented is calculating "the wrong" MAG_Heading value, different from the MAG_Heading value you expected.
It would be a lot easier for us to help you if you gave us: (This is the "describe the symptoms" section of "How To Ask Questions The Smart Way" )
- the AK8975 magnetometer output values m_x, m_y, and m_z at some single point in time.
- The pitch and roll values at the same instant
- the allegedly wrong MAG_Heading output value calculated from those values
- what you expected the correct MAG_Heading to be
So I'm left to speculate that perhaps you're running into the same sorts of problems I create for myself :-).
- What angle format do your sin() and cos() and atan2() functions expect? Do you need to do some sort of conversion between the format pitch and roll are stored in to that format? Do you need to convert from that format to what you need MAG_heading? (brads, degrees, or radians? floating-point or fixed-point?)
- Is there an offset in the raw m_x, m_y, m_z values that needs to be subtracted off?
- Are all the parts lined up in the way assumed by the code? In particular, is the pitch and roll axis lined up with the magnetometer axis? (Is m_x supposed to point forward, along the roll axis? Is m_y supposed to point to the right, along the pitch axis?)
- Maybe some sensor value or another -- perhaps m_z -- needs to be negated before feeding into this code?
- Is maybe this code being interrupted by one interrupt or another that corrupts its internal values? I seem to recall a different project that, after someone put a "divide" in an interrupt routine, every trig function calculation everywhere else in the program would often give the wrong result.
- Is maybe interrupts firing so often that this code never actually finishes running?
There seems to be other people discussing very similar code elsewhere: http://diydrones.com/forum/topics/heading-from-3d-magnetometer ; http://diydrones.ning.com/profiles/blogs/dcm-imu-theory-first-draft ; http://aeroquad.com/showthread.php?1138-REVOLUTION!!!-New-IMU!!! ; http://www.rcgroups.com/forums/showthread.php?t=1436742&page=6 ; http://aeroquad.com/showthread.php?691-Hold-your-heading-with-HMC5843-Magnetometer ; etc.
They are three sensors that are useful for determining position and orientation, but they measure different things.
- A magnetometer measures magnetic fields. Because the earth has a significant magnetic field, the magnetometer can be used as a compass. As such it is useful to determine absolute orientation in the NESW plane.
- An accelerometer measures accelerations. This is useful to measure changes in velocity (directly, as the acceleration is the first time derivative of the velocity) and changes in position (by integrating the signal). They are usually used for measuring small movements. Also note that gravity acts like a continuous acceleration upward (via Einstein's equivalency principle), so a multiple-axis accelerometer can also be used as an absolute orientation sensor in the UP-DOWN plane.
- A gyroscope measures either changes in orientation (regular gyro or integrating rate gyro) or changes in rotational velocity (rate gyro).
The reason these sensors are combined is because they excel at different things. For example, for orientation, a magnetometer has poor accuracy for fast movement, but pretty much zero drift over time. An integrating scheme using gyros on the other hand reacts quickly and accurately to changes, but accumulates vast error over time. It also requires to start from a known orientation, as it only reacts to changes.
Combining the inputs to these sensors allows for quick and accurate position and orientation determination with a low amount of drift over time.
Together, these sensors are also referred to as an Inertial Measurement Unit, or IMU. You can find more information on the wikipedia page for this term. Note that the unit is not strictly speaking purely inertial when you add magnetometers, but this nomenclature is widely used.
Best Answer
Dude - You've got a good one.
Per the data sheet http://store.invensense.com/datasheets/invensense/MPU-9150_DataSheet_V4%203.pdf (page 11) the Zero Rate Output limits are +/- 20 degrees per second.
I think you've overestimated what these things are for. They are not intended as the heart of an IMU. When used in a controller, they are part of a feedback loop that stabilizes or detects angular rates in the Hz region. From their webpage http://www.invensense.com/technology/motion/
Game controllers and smartphones simply don't care about drift rates of a degree per second.
To some degree you can work around this, if you can provide frequent calibration points, but otherwise you'll have to start looking into the mathematics of Kalman filters and sensor fusion. Here's http://seat.massey.ac.nz/conferences/icst2013/proceedings/papers%5C1569816521.pdf a paper discussing a MEMS gyro with drift rates pretty close to yours.
Also, keep in mind that what's important is not so much the instantaneous value of the bias, but rather the bias stability, since you can measure the bias on the bench and zero it out. So try running your unit for an hour, grabbing a sample per second, and see how much the bias changes. If you're serious about this, you'll also need to do it at different temperatures. And if you're REALLY serious about this, don't forget to take earth rates into account.