[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
Permalink Reply by Paul Truong on December 21, 2010 at 2:09pm Hi everyone,
I am getting a BUILD FAILED error when trying to build the demo project to program it to the devboard. I was able to run the roll/pitch/yaw demo fine, so I don't know why I'm getting an error now. Here is the error message:
-------------------------------------------------------------------------------------------------------------------------
Program Memory [Origin = 0x100, Length = 0x7f00]
section address length (PC units) length (bytes) (dec)
------- ------- ----------------- --------------------
.text 0x100 0x23d8 0x35c4 (13764)
.const 0x24d8 0x2ca 0x42f (1071)
.text 0x27a2 0xa6c 0xfa2 (4002)
.dinit 0x320e 0x414 0x61e (1566)
.text 0x3622 0x21e2 0x32d3 (13011)
.isr 0x5804 0x2 0x3 (3)
Total program memory used (bytes): 0x8289 (33417) 68%
Data Memory [Origin = 0x800, Length = 0x800]
section address alignment gaps total length (dec)
------- ------- -------------- -------------------
.nbss 0x800 0 0x102 (258)
.ndata 0x902 0 0x94 (148)
.nbss 0x996 0 0x90 (144)
.ndata 0xa26 0 0x3c (60)
.nbss 0xa62 0 0x92 (146)
.ndata 0xaf4 0 0x2a (42)
.nbss 0xb1e 0 0x24 (36)
.ndata 0xb42 0 0x4a (74)
.nbss 0xb8c 0 0xc (12)
.ndata 0xb98 0 0x10 (16)
.nbss 0xba8 0 0xc (12)
.ndata 0xbb4 0 0x2 (2)
.data 0xbb6 0 0x330 (816)
.dconst 0xee6 0 0x2a (42)
.bss 0xf10 0 0x18 (24)
.data 0xf28 0 0x2 (2)
Total data memory used (bytes): 0x72a (1834) 89%
Dynamic Memory Usage
region address maximum length (dec)
------ ------- ---------------------
heap 0 0 (0)
stack 0xf2a 0xd6 (214)
Maximum dynamic memory (bytes): 0xd6 (214)
c:/program files/microchip/mplabc30/v3.25/bin/bin/../../lib\libc-coff.a(vsnprintf.o)(.libc.vsnprintf+0x1e):fake: undefined reference to `assert'
c:/program files/microchip/mplabc30/v3.25/bin/bin/../../lib\libc-coff.a(vsnprintf.o)(.libc.vsnprintf+0x22):fake: undefined reference to `alloc'
Link step failed.
----------------------------------------------------------------------
Release build of project `C:\Documents and Settings\Administrator\Desktop\UAV\magnetometer\Magnetometer\MagnetometerDemo.mcp' failed.
Language tool versions: pic30-as.exe v3.25, pic30-gcc.exe v3.25, pic30-ld.exe v3.25, pic30-ar.exe v3.25
Wed Dec 22 12:54:57 2010
----------------------------------------------------------------------
BUILD FAILED
-------------------------------------------------------------------------------------------------------------------------
I am a beginner, so please bear with me. If anyone can help, it would be greatly appreciated.
Thanks,
-Paul
Hi Paul,
This problem has been reported a couple of times. Most users have not had any trouble, only a few have reported it. It has something to do with the linker and the library code for the vsnprintf function.
I suggest you repost your question on the uavdevboard group, there may be someone there who can help you. In fact, someone recently posted a similar question.
The code compiles and links ok on my computer, so I am not sure what is going on.
By the way, the demo code only runs on the "green-board" and the "red-board", it does not work on the newest board, the "UDB3", which has the flat-mounted Invensense gyros. If you have the newer board, and want to use the magnetometer in conjunction with MatrixPilot, you should use a recent release of MatrixPilot.
Best regards,
Bill
Permalink Reply by andrew on January 22, 2011 at 6:48am Hi Bill,
I read your paper on DCM yesterday and today, and I started to understand a bit of how DCM works. Although I did not understand everything, i think I caught the idea. You use a PI loop for the correction of the three component vectors of the plane seen from the earth frame that automatically corrects for all kind of offsets like wind and gyro drift etc. A cute idea. But rather intensive computationally-wise.
My idea is to use three complimentary filters that will also free me of gyro drift and saturation problems.
I have a 3axis HMC5843, 3 axis gyro and 3 axis accel. If I compensate the HMC with roll and pitch from the accel, I have a heading in earth frame. Right?
Now if I want to fuse this heading with my yaw gyro angle, I would need to tranform the gyro angle into the earth frame. Can you help me explaining how to do that?
Thanks! Andreas
Hi Andreas,
Integration of the magnetometer data into your computations is rather easy if you maintain the 9 elements of the direction cosine matrix (DCM):
1. Use the DCM to transform the body frame magnetometer 3D vector into the earth frame.
2. Throw away the Z component of the magnetic field in the earth frame. Take the cross product of the measured X and Y magnetic field components in the earth frame with X and Y magnetic field that should be present in the earth frame. This will give you a yaw error in the earth frame that is a vector in the Z direction.
3. Transform the earth frame Z yaw magnetic error back into the body frame of reference, using the DCM.
4. Use the 3D yaw magnetic error vector in the body frame any way you want to adjust for drift.
The transformations of vectors back and forth between body and earth frame of reference is easy to do with DCM, it involves multiplying a matrix times a vector.
Best regards,
Bill
Permalink Reply by andrew on January 25, 2011 at 4:01am Thanks, Bill, for your answer.
I don't understand it all. Point 2.: do you mean that I have to take the cross product of the gyro X and Y components in the earth frame with the X and Y components of the magnetic field in the earth frame? Then I would get an error vector which I can use for correction of drift after transposing it into the body frame. If you mean that, I think I can follow.
But as I am dealing with an IMU for a boat, I really only need the gyro yaw angle in the earth frame. That's all. Is there any way to get this angle without computing the DCM?
There may be a way to calculate the yaw angle in the earth frame from the gyros if one has the roll and pitch angles, just the same way as one can calculate the earth frame of the magnetic vectors with the help of the Euler angles.
Thanks for your comment, and my congratulations for the neat code you write!
Andreas
Permalink Reply by Navigator on February 1, 2012 at 1:41pm Hi Bill,
I have implemented the Roll/Pitch Error using DCM (smartphone applications)and I am getting very good results (Roll And Pitch)but i have observed one thing that i get no improvement after numerical error correction. Anyhow now I am implementing yaw error using magnetometer, I have some questions for understanding
1- are you using magnetometer values in micro tesla in magnetic field vector for calculation or some other scaling conversion.
2- After obtaining magnetic field vector in earth frame of reference, it has been multiplied with declination vector to get magnetic error in earth plane. I am confused at this point because declination angle is difference angle between the true North and compass North. How it can be considered as the known horizontal component of the earth's magnetic field. (As cog in GPS/compass is the angle wrt North)
regards
Navigator
Hi Navigator,
1. I am not sure what the units are in MatrixPilot. I use whatever the default gains are for the Honeywell magnetometers. The binary values for the horizontal component are around 400, if that helps. The way things are set up in MatrixPilot, the actual units do not much matter, these days I normalize the magnetic vector to have a fixed value. In other words, I divide the vector by its magnitude.
2. Here is how the magnetic field is used to compensate the gyros: the measured magnetic field is transformed from the body frame to the earth frame using the rotation matrix. The convention for the rotation matrix is that true north is the reference. So, the rotation matrix will transform the magnetic field measurement from the body to the earth frame. The result that comes out will not be aligned to the north, but will be offset by the declination angle. What I do next is to take the cross product of the horizontal component of the measured magnetic field in the earth frame with the horizontal component of the known magnetic field in the earth frame of reference. The known magnetic field is computed from the known declination angle. When the rotation matrix is aligned correctly, the two horizontal magnetic vectors (measured and known) will be parallel, and the cross product will be zero. Both vectors will be rotated from north by the declination angle.
Note that this method is not the same as a tilt-compensated compass. It works no matter what the orientation of the aircraft is, it can even have a pitch angle of 90 degrees.
Best regards,
Bill
Permalink Reply by Andrew Zaborowski on April 28, 2012 at 4:08pm Hi Bill,
(Yes, replying in a two-year old thread because I have just found your document on the offset nulling. I had come to pretty much the same equation but my algebra being as bad as it is I didn't arrive at the final formula for the offset integration, so I'm trying to use yours.)
In the implementation you shift offsetSum to the right, but you shift magFieldEarth to the left, why's that? I understand the right shift is the implementation of the filter so that rare spikes from the magnetometer don't introduce too much error. But the left shift will cause the [b21 * b1 + b12 * b2] part to be 4 times too big. Or am I misreading?
Many thanks
Hi Andrew,
You are right, this is a stale thread. Since then, I came up with a better way to remove magnetometer offsets. Take a look at this discussion.
Best regards,
Bill
Season Two of the Trust Time Trial (T3) Contest has now begun. The fourth round is an accuracy round for multicopters, which requires contestants to fly a cube. The deadline is April 14th.24 members
207 members
58 members
1355 members
88 members
© 2013 Created by Chris Anderson.
Powered by
