Magnetometer Soft- and Hard-Iron Calibration

I'm using an LSM303DLM on a Pololu MinIMU-9 board as part of an AHRS. The software is ported to mbed from Pololu's example code which is in turn ported from ArduPilot 1.5. But that's no what this is about.

This is a saga of one man... with meager math skills... in a desperate fight to calibrate his compass... it's a timeless tale of truimph and defeat...ahem.

Actually, this is mainly a story about soft-iron calibration.

I'm curious to see how accurate the magnetometer can be if properly calibrated since it'll be a primary source of heading reference for my AHRS due to the very short distances, high speeds, and poor GPS reception in the area of operation. So, rather anal proper calibration seems like the right path.

In attempting to calibrate my compass, plain hard iron (offset) and gain calibration didn't help as much as it has on other sensors in other configurations. I wondered why.

I've captured and saved data from the sensor using Hon Bo Xuan's 3D Scatter Processing script (download

And am using Yury Petrov's Ellipsoid_fit (download) in Octave to attempt to figure out how to calibrate for hard and soft iron offsets. The hard iron offsets are ridiculously easy of course. It's the soft-iron stuff that's frying my feeble mind. :)

Both the ellipsoid fit and a gnuplot rendering of the XY and YZ plots show minimal 'tilt' of the ellipsoid about 2-5 degrees.

gnuplot%2520graph%2520212012%252084924%2520AM.jpg?width=400

gnuplot%2520graph%2520212012%252084831%2520AM.jpg?width=400

The XZ axis is another story. And yes, I've removed nearby ferrous objects to no avail. 

gnuplot%2520graph%2520212012%252083830%2520AM.jpg?width=400

Ellipsoid_fit says the eigenvectors (apparently these are the 3 axes of the ellipsoid) reported are:

Ex = -0.471 0.095 0.877

Ey = -0.865 0.145 -0.481

Ez = -0.173 -0.985 0.014

I'm still working out how to figure out the tilt of the x-z ellipse.

Another script, fit_ellipse by Ohad Gal (download) -- it's a 2d fit -- reports approximately -25 degree tilt (for some reason I had to correct x axis mirrored between the two plots; stretched out to resemble the x-z plot above) I don't think the tilt estimate is accurate.

The tilt estimation at least for this latter script is quite sensitive to axis gain. Hm.

Figure%25201%2520212012%2520102134%2520AM.jpg?width=400

I've been trying to wrap my head around the math involved in soft-iron calibration and found a few particularly good articles (several more that are, I think, difficult). I guess the main point is to have a soft-iron compensation matrix involved. Calculating the matrix eludes me as yet.

Freescale AN4246.pdf

MEMSense Compensating for Tilt, Hard Iron and Soft Iron Effects.pdf

LSM303DLM App Note.pdf

I've also read a paper or two on swinging a compass (as done in the airline industry) and I'm keeping that approach in my back pocket.

I'd happily ignore soft-iron as I've done in the past but even with offset and gain calibration the sensor is pretty clearly inaccurate at various orientations and I have convinced myself that it's due to soft iron distortion.

If you skip ahead to this reply, it talks about the approach used for soft-iron calibration and shows that, yes indeedy, it seems to be working at least on paper.

You need to be a member of diydrones to add comments!

Join diydrones

Email me when people reply –

Replies

  • Here is the results of the calibration with using my program.

    Calibrated magnetometer data:

    3689598230?profile=original

  • See my version of the soft and hard iron magnetometer calibration:

    http://diydrones.com/profiles/blogs/advanced-hard-and-soft-iron-mag...

  • Thank you for sharing your work.  I have some hardware with extreme magnetic errors and also wrote some code using the linked ellipsoid fit in an attempt to make the magnetometer usable.  I thought it would be worth sharing these results in this thread.

    This first plot shows the uncalibrated data.  The grey line is arbitrary rotations and the red, green and blue lines are rotations on a flat level surface around x, y and z (axis pointing down each time).  You can see that this is an extreme situation, I found the magnetometer data was useless with hard-iron calibration only.
    3692502736?profile=original
    This next plot shows the measurements calibrated using the ellipsoid method.  The ellipsoid fit has left the magnetometer axes at an incorrect orientation. The plot also shows additional RGB vectors drawn to the centroid of each x, y and z rotation dataset.  These vectors represent a a non-orthogonal rotation matrix would use to correct for this orientation error.
    3692502784?profile=original
    This final plot shows the calibrated measurements corrected for the orientation error. The x, y and z rotation datasets are now concentric with the principle axes.  The plot looks as if a high level of accuracy has been achieved.  However, I implemented this within the AHRS hardware and found errors of up to 20 degrees.  I wonder if the extreme initial magnetic distortions are too much for this calibration model.
    3692502749?profile=original

    For reference, the calibration parameters for the above data are:

    softIronMatrix =

        1.2475   -0.0470    0.0429

        0.0309    0.8271   -0.0291

       -0.1009   -0.6458    0.7490

    hardIronVector =

     -388.0255

      178.5560

     -305.9703

     Where:
    calibrated  = softIronMatrix * uncalibrated - hardIronVector

  • I have just started working on to calibrate my magnetometer. I used magnetometer for my heading correction using extended kalman filter. I see that the errors are coming to around 20 deg, and I am very unhappy with this large errors. I considered only the offsets/bias during my simulations. To improve my heading accuracy, I am looking info soft iron and scaling effects.

    What is the heading accuracy you have obtained after the corrections? Is your approach working well?

    Thanks & Regards,

    Mohan

  • So what *should* I be seeing?  

    Suppose I create a series of samples that fell exactly on a sphere of radius 1. It simulates a perfect magnetometer with zero noise and magnitude 1. Turns out the eigenvectors exx/exy and eyx eyy are all over the place. exz, eyz and ez are all locked in. As I generate more and more points, the eigenvectors converge to ex=[0 0 1] ey=[0 1 0] ez=[1 0 0]. I need 10,000 or more points before it starts to look close which is utterly impractical for manual calibration. So, guess I cannot  trust the estimated eigenvectors for this situation.

    Next I created a 1000 simulated magnetometer samples with magnitude noise but 0 offset and 0 tilt and ran it through Ellipsoid_fit and got:

    offset = [1.6196e-004 -2.5503e-003 -7.0838e-004]

    radii = [ 1.00560 1.00101 0.99894 ]

    Fullscreen%2520capture%2520212012%252025713%2520PM.jpg?width=400

    I haven't quantified the relationship between offset/magnitude error and number of points and noise. For now I'll assume that with a few hundred points and typical sensor noise it'll be "close enough".

    I wanted to look at magnitude values versus x, y, and z values respectively. With the perfect sphere I get a line from (-x,1) through (x,1) as one might expect. Same for y vs. magnitude and z vs. magnitude. In a perfect sphere, magnitude is 1. As you might imagine, a noisy magnitude produces a noisy plot, not a clean line.

    Fullscreen%2520capture%2520212012%252030617%2520PM.jpg?width=400

    I wonder what my real magnetometer's plots will look like? I did offset correction and scaling based on Ellipsoid_fit. I ran into some problems. The offset and radii were incorrect. The error was particularly bad for the z axis.

    Fullscreen%2520capture%2520212012%252035140%2520PM.jpg?width=400

    Under these conditions the x,y,z vs magnitude plots are a disaster so can't tell what's going on I don't think. More later.

This reply was deleted.

Activity

Jose Araujo liked Jose Araujo's profile
Aug 29
spencer harvey liked spencer harvey's profile
Jul 9
More…