[There is now a better method for removing offsets in flight. See this discussion. - WJP]

The picture shows a UAV DevBoard connected to Jordi's magnetometer breakout board.

First, since my discussions tend to get long winded, if you want to "cut to the chase", you might want to read this.

I recently integrated Jordi's HMC5843 magnetometer breakout board with the UAV DevBoard (UDB).

Jordi's board is really great, having the onboard bidirectional level shifters and builtin pullup resistors made it possible to simply connect Jordi's board directly to the I2C pins in the programming connector. Thank you very much, Jordi.

So, heli and quadcopter pilots who are using the UDB would do well to buy Jordi's board, my plan is to integrate it into the heli firmware that is being developed for the UDB. There is now a magnetometer demo and instructions for the UDB.

But that is all besides the point of this discussion....

Along the way to implementing the magnetometer demo, I realized the hardest part was going to be determining the offsets of the magnetometer. The integration of the magnetometer itself into the DCM algorithm was trivial, but what to do about the offsets?

The HMC5843 has a self calibration feature, so you can determine the gains just fine. But the first magnetometer I bought had rather large offsets. So I bought 3 more (1 more from Jordi, and 2 more from Sparkfun). It turned out that all 4 units had some offsets. Even if they did not have offsets, it would still be possible for stray magnetic fields in the aircraft to create offsets.

So, some sort of procedure is needed to null the offsets.

I thought of several manual ways to do that, and I read several postings on the subject....

Then I wondered if there might be some way to use the direction cosine matrix to automatically compute the offsets in flight. And there is....even for dynamically changing offsets, such as from power leads to the motors...

The basic idea is the following...

When the aircraft is rotating, the offset fields rotate with the aircraft, while the earth's magnetic field is stationary. So it should be possible to use the direction cosines to separate the two fields.

The basis of the idea is the same as flipping the magnetometer exactly 180 degrees along one of the axis and averaging the two readings. The result is the offset.

The idea can be extended to rotations other than 180 degrees, even small rotations, by using the direction cosine matrix and some vector algebra.

The resulting theory and implementation is described here, and it has been tested. It works rather well.

It was interesting to watch the computations of the offsets during the tests. A few random turns along a couple of the axes was all that was needed to compute the offsets. So, you can either null the offsets prior to takeoff by rotating your aircraft a bit, or simply let it happen automatically during the first few turns of the flight.

It was also interesting to see what would happen if I deliberately manually set the offsets to the wrong values, they would quickly reset to the correct values after a few turns.

The bottom line is that now both the calibration and the nulling of offsets can be done completely automatically, without any manual operations or entry of measurements. It is possible to extend any DCM-based IMU, such as the ArduIMU, to use this method to simplify the integration of a magnetometer.

Best regards,
Bill

Tags: DCM, DevBoard, UAV, magnetometer

Views: 5547

Reply to This

Replies to This Discussion

You never cease to amaze. I thought of something I heard Homer Simpson say about donoughts and I laughed as I said to myself, "DCMs. Is there anything they can't do?" , lol .
Lovely, clear description of the problem and the solution. I feel smarter already!

Many thanks for answering something many of us have probably puzzled over but never articulated as well as this.
Like the wind estimation algorithm, this is an excellent development and addition to the DCM filter. Thank you for sharing.
For once/first time , I am able to understand DCM and this offset article completely without having to read it 10 times !! :)),
I too feel very smart today already :-), amazing to noobs like me, thanks Billu Bhaiya for wonderful work and Jordi for great product dev.
Hey Bill,
I'm doing something similar, but store it to flash so the next time it powers up it has a reasonable estimation without having to make the rotations. Thanks for the clear explanations as usual.

Brian
Bravo, Bill. Your papers, and your research in general, have given me a tremendous head-start in "catching up" with what you guys are doing. Great work.
Rana,

I think the dspic from the UDB has internal eeprom...
Be careful with the magnetometer board. This capacitor DOESN'T MATCH the manufacture requirement (low ESR) and it can make troubles to you.

I had a bad experience under ~0ºC, the magnetometer couldn't read anymore until the temperature rose again (aluminium electrolytic and this kind of SMD increasing its ESR dramatically under low temperatures).

The solution is to remove this cap and put an polymer/organic electrolytic capacitor :P

If you don't expect this temperatures then it doesn't matter xD
Nice work Bill,
a really elegant solution to the problem...

Jose.
Jose,
Thank you for your kind words.
Bill
I've been trying to understand the C code example. The line "MatrixMultiply(1,3,3,
rmatTransposeMagField,magFieldEarthPrevious,rmat) ;" has got me stumped. I'm not familiar with the dsPic devices and their compilers, but this looks like it is multiplying rmat by the previous value of the earth field, and storing it in rmatTransposeMagField. But from the equation derivations, shouldn't the term rmat be rmat transpose?

John
John,

Regarding rmat and rmat transpose, I took advantage of the fact that C stores row and column vectors the same way (as arrays) to avoid having to actually take the time and memory space to compute the transpose of rmat.

So, lets suppose that I want to compute y = RT*x, where y is a vector, RT is the transpose of rmat, and x is a vector.

I could just as well compute yT (y transpose), since it will be stored the same way in memory.

Now, it is a property of vectors and matrices that the transpose of the product of factors is the product of the transposed factors, taken in reverse order.

So, yT = xT*(RT)T = xT*R

So, to compute rmat transpose times a vector, you simpy multiply the vector times rmat.

That is why the first three argument to MatrixMultiply are 1, 3, 3. That means that magFieldEarthPrevious is to be treated as a 1 by 3 matrix, and that rmat is a 3 by 3 matrix, and the result is a 1 by 3 matrix. Conveniently, a 1 by 3 matrix is stored exactly the same as a 3 by 1 matrix.

Best regards,
Bill

RSS

© 2014   Created by Chris Anderson.

Badges  |  Report an Issue  |  Terms of Service