Shop OBEX P1 Docs P2 Docs Learn Events
Tilt Compensation Magnetometer ( HMC5883L) — Parallax Forums

Tilt Compensation Magnetometer ( HMC5883L)

ShawnaShawna Posts: 508
edited 2013-12-22 07:19 in Propeller 1
So, I have been trying to figure out this tilt compensation problem with magnetometers for a long time now. I thought that I had the problem figured out last summer and I am afraid I may have given some bad advice in a thread on the forum. I feel bad about this and I tried IMing the individual that started the thread and have got no reply. Anyways, I wanted to start this thread to get the problem resolved and when it is resolved I will post back to the other thread. I didn't want to hijack the other thread.

I have searched a lot on the internet and in the forums here and have found little info that I could understand. I want to do this without using a rotation matrix for the time being. Most tutorials on the net dive into some pretty heavy math to accomplish this. And I am afraid that in most of the equations I do understand, at the same time I do not understand what format the input values from the sensors have to be in (degrees, radians, raw).

Step 1.
Align the axis of the accelerometer and the magnetometer.

The imu board I have is the sparkfun 9DOF board. https://www.sparkfun.com/products/10724
This board has a HMC5883L Magnetometer, ADXL345 Accelerometer, and a ITG-3200 Gyroscope.
The sensors are already mounted on the board so if the alignment of the axis needs to be altered it will have to be done in software.

This is the tutorial I am using to verify proper alignment.
http://circuitcellar.com/tag/magnetometer/
The last article on the page is about tilt compensation of a mag. It has what I believe to be, a good section on how to verify alignment.
I am also using this one.
http://www.freescale.com/files/sensors/doc/app_note/AN4248.pdf

Let me know if I am wrong here, but here goes my understanding of checking alignment of the magnetometer.

Take the mag and face it north, the x axis on the mag should be at its maximum value. Now rotate the mag so that it is facing south, now the x axis on the compass should be at its minimum value. While checking this, the mag should be as level as possible and not near any metal. Also the z axis on the mag should not change much as long as the mag has been kept level throughout the rotation.

Next is to check the y axis of the mag. If the mag is rotated 90 degrees from north so that it is pointing east, the y axis should be at its maximum value. Now rotate the board so that it is pointing west. The mag y axis should now be at its minimum value. The z axis still shouldn't have changed much as long as the board was kept level during this rotation.

If these two checks were successful, then the mags orientation has been verified.

Also, when rotated cw the degrees should count up and when rotated ccw the degrees should get smaller. This equation should give you an angle of azimuth.

Azimuth = atan2(mY,mX)

Where mY and mX are the x and y axis raw readings from the mag.

Note that this will not be real accurate without calibrating the mag first, but it should help with verifying the orientation of the mag.

Correct me if I am wrong up to this point guys.


Next, making sure the acc is aligned properly with the mag.

This is where it gets a little sketchy for me but I think I understand it, so lets see if I can explain it. Then you guys can tell me if I am right or not.

So lets start with the orientation of the mag. From the origins which is where mX, mY, and mZ start(mag axis's). Pointing mX North should cause mY to point East and mZ t point down. With the mag aligned like this, the acc's roll axis should rotate around the mag's mX axis and the acc's yaw axis should rotate around the mag's mY axis. With the viewpoint starting at the origins and looking down each the mX axis and the mY axis if you roll or pitch cw the value should increase on the acc axis's values. Rotating the X or y axis of the acc ccw around the mags axis's should cause the acc values to decrease.

At least this is how I precive the alignment from reading the 2 links above.

What do you guys think so far am I right or wrong.

Comments

  • ShawnaShawna Posts: 508
    edited 2013-12-19 18:59
    Step 2.

    Hard Iron Calibration.

    I think I have this part down also, or at least a basic version.
    If the mag is rotated in every possible orientation and the max and min value of the x,y,z axis are collected, 0 should be the the result if you sum the min and max of any of the axis. For example my Xmin tonight when I did the test was -177 and my Xmax was 257. 257 + -177 is not 0, it is 80. So I divide the sum by 2 and subtract it from my raw mX reading. Now you do this for all 3 mag axis's. If I am not mistaken this is how to calibrate for hard iron error.

    After you have applied the offsets, collect the min and max for each axis again and see if the sum is 0 or close to 0.
  • ShawnaShawna Posts: 508
    edited 2013-12-19 19:19
    Step 3.

    This is the third step I'm taking.
    Calculate the pitch and roll from my acc.

    This is the simple way I am calculating pitch and roll to start with, I think it should be sufficent to test the tilt compensation.
    'Calculates Pitch and Roll in Radians PI to -PI
         Roll    := F32.ATan2(F32.FFloat(aX),F32.FFloat(aZ))
         Pitch  := F32.ATan2(F32.FFloat(aY),F32.FFloat(aZ))
    
    
    
  • shimniokshimniok Posts: 177
    edited 2013-12-20 01:16
    In case it helps, here's a writeup I did to quickly get the magnetometer calibrated into the 'ballpark' via hard iron calibration:
    http://www.bot-thoughts.com/2011/04/quick-and-dirty-compass-calibration-in.html

    The accelerometer will also have offsets and scaling errors. I would also capture accelerometer values while you rotate the device around to calibrate the compass. That would give you the maximum and minimum values for each axis and, I think, the scaling and offsets for them as well.

    I haven't looked at pitch compensation in some time so I'll have to think about the roll, pitch calculations.

    Since you have a 9DOF board, you might consider running ArduIMU code to also take advantage of the gyros, turning the whole thing into an attitude heading refernce system (AHRS). The Gyros, too, will need to be calibrated. That's a bit more involved than the accelerometers or magnetometers.
  • ShawnaShawna Posts: 508
    edited 2013-12-21 12:34
    Since you have a 9DOF board, you might consider running ArduIMU code to also take advantage of the gyros, turning the whole thing into an attitude heading refernce system (AHRS).

    This is my end game plan, actually I want to have a DCM running on the prop. I think the AHRS is the same thing. Actually I do have Jason's DCM code running on my prop and if I can get this tilt equation to work I will use the pitch and roll angle from that. I need to get the mag part running before I complicate things further.

    I hope to have some time to play with the setup tonight, I will try and post some code later.
  • ShawnaShawna Posts: 508
    edited 2013-12-22 07:19
    Well this tilt compensation doesn't seem to work for Smile. I'm not sure what I am doing wrong. I am pretty sure I have the axis's aligned properly. I am feeding the Pitch and Roll value into my tilt equation as radians I believe using the Atan2 function. The mag values that I am putting into the equation are filtered and hard iron compensated.

    Here is the tilt portion of my code if anyone would like to look at it and give me some advice.

    Roll   := F32.ATan2(F32.FFloat(aX),F32.FFloat(aZ))
    
    Pitch  := F32.ATan2(F32.FFloat(aY),F32.FFloat(aZ)
    
    '------------------------------------------------------------------------------ 
    PUB Mag_Tilt_Compensation
    
      'Scales mag values to finish hard iron calibration
      mXscaled := (mX * 10000) / 10000
      mYscaled := (mY * 10458) / 10000
      mZscaled := (mZ * 11357) / 10000
    
      CosP     := F32.Cos(Pitch)
      CosR     := F32.Cos(Roll)
      SinP     := F32.Sin(Pitch)
      SinR     := F32.Sin(Roll)
      CosRSinR := F32.FMul(CosR,SinR)
      
    'Horizontal Vector xH = x * cosRoll + y * sinPitch - z * cosRoll*sinRoll
      
      Temp1 := F32.FMul(F32.FFloat(mZ),CosrSinR)
      Temp2 := F32.FMul(F32.FFloat(mY),SinP)
      Temp3 := F32.FMul(F32.FFloat(mX),CosR)
    
      Temp1 := F32.FSub(Temp2,Temp1)
    
      xh    := F32.FAdd(Temp3,Temp1)
    
    'Vertical Vector yH = y * cosPich + z * sinPitch
    
      Temp1 := F32.FMul(F32.FFloat(mZ),SinP)
      Temp2 := F32.FMul(F32.FFloat(mY),CosP)
    
      yh    := F32.FAdd(Temp2,Temp1)
    
      Azmith := F32.Degrees(F32.ATan2(yh, xh))
    
    '------------------------------------------------------------------------------
    

    Thanks
    Shawn
Sign In or Register to comment.