kriswiner / MPU9250

Arduino sketches for MPU9250 9DoF with AHRS sensor fusion
1.03k stars 471 forks source link

Magnetometer Calibration #376

Open Qammar-25 opened 5 years ago

Qammar-25 commented 5 years ago

Hi Kris,

I have been following your sketch for calibrating the magnetometer. My method is given as:

1- Move the MPU9250 in a figure 8 pattern 2- Take 50 samples of magnetometer's data 3- Plotting axial raw data against each axis 4- Subtracting the calculated bias value & multiplying the calculated scale factor 5- Replot the data (with bias and scale applied)

However, the later plot is not much different from the former even after calibration. How can i get a perfect spherical shape? Attached are the two plots for reference. Magnetometer_data_plot Magnetometer_corrected_data

Here is the piece of code for applying corrections

*mxc = magx_scale(mx - magx_bias); myc = magy_scale(my - magy_bias); mzc = magz_scale(mz - magz_bias);**

Qammar-25 commented 5 years ago

I believe i have found the issue. The 'mx', 'my' and 'mz' terms in the above equations were not scaled and thus these plots. The data has now been properly scaled and the results are attached. I have used only 50 samples for plotting. Uncalibrated_magnetometer Calibrated_magnetometer

Is this calibration acceptable?

kriswiner commented 5 years ago

Acceptable is determined by the accuracy required of your absolute orientation solution.

Are you calibrating with the 100 Hz rate? You will need more than 50 samples then. Try 500...

Also, there are simple tests which you can perform to test mag calibration.

Is the z-axis magnetic field the same magnitude and opposite sign when the board is laying flat and motionless facing up versus facing down? Does the z-axis magmentic field change if you rotate the board?

On Wed, May 29, 2019 at 12:58 AM Qammar-25 notifications@github.com wrote:

I believe i have found the issue. The 'mx', 'my' and 'mz' terms in the above equations were not scaled and thus these plots. The data has now been properly scaled and the results are attached. I have used only 50 samples for plotting. [image: Uncalibrated_magnetometer] https://user-images.githubusercontent.com/50173062/58539641-3367b400-8211-11e9-95e5-1364a563b79b.jpg [image: Calibrated_magnetometer] https://user-images.githubusercontent.com/50173062/58539657-3c588580-8211-11e9-8eeb-916bfe653d2c.jpg

Is this calibration acceptable?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/376?email_source=notifications&email_token=ABTDLKVG6ZQPOKVZFLTZEHLPXYZR7A5CNFSM4HQJMCUKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODWOQARY#issuecomment-496828487, or mute the thread https://github.com/notifications/unsubscribe-auth/ABTDLKTMURMO7KF4DEXS46TPXYZR7ANCNFSM4HQJMCUA .

Qammar-25 commented 5 years ago

Yes, i am using the 100Hz rate.

Raw data (x, y & z axis) when z axis is pointing upward: -74 172 -374

Raw data (x, y & z axis) when z axis is pointing downward: -67 5 47

Data (x, y & z axis) for z upward with scaling and biasing applied: -23.8 24.22 -35.22 (uT)

Data (x, y & z axis) for z downward with scaling and biasing applied: -22.5 -9.8 32.5 (uT)

Is this the expected result? Moreover the z axis magnetic field changes as i rotate the board.

kriswiner commented 5 years ago

You are mot sampling all of the response surface, or not sampling enough time, or have another error in applying the calibration etc

On Thu, May 30, 2019 at 12:10 AM Qammar-25 notifications@github.com wrote:

Yes, i am using the 100Hz rate.

Raw data (x, y & z axis) when z axis is pointing upward: -74 172 -374

Raw data (x, y & z axis) when z axis is pointing downward: -67 5 47

The z axis magnetic field changes as i rotate the board. However, my z axis values are different when the board is held stationary facing up and down respectively as shown above. What is going wrong?

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/376?email_source=notifications&email_token=ABTDLKTLXFWLGHUXOV2ADF3PX54UTA5CNFSM4HQJMCUKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODWRR7YI#issuecomment-497229793, or mute the thread https://github.com/notifications/unsubscribe-auth/ABTDLKV64KZMNXKNN3IN4RDPX54UTANCNFSM4HQJMCUA .

Qammar-25 commented 5 years ago

What else i can do other then moving the board in a single 8 pattern? What about the scaled data? Isn't it as per expectation?

kriswiner commented 5 years ago

Not a single 8 pattern, you have to move the board to sample every point on the 3D response surface multiple times.

On Thu, May 30, 2019 at 2:40 AM Qammar-25 notifications@github.com wrote:

What else i can do other then moving the board in a single 8 pattern? What about the scaled data? Isn't it as per expectation?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/376?email_source=notifications&email_token=ABTDLKVMKSEH5HFLI6SWYPTPX6OKNA5CNFSM4HQJMCUKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODWR37VQ#issuecomment-497270742, or mute the thread https://github.com/notifications/unsubscribe-auth/ABTDLKT5GEQE62OE55S6FDTPX6OKNANCNFSM4HQJMCUA .

rob-meiner commented 3 years ago

Hi Kris, First, thanks for the excellent resource on IMUs. I've read a lot about calibrating the magnetometer, but somehow can't get this to work on my device. Here's output from my initial calibration. I have increased my sample size to 5000, since I can't seem to get any results that make sense.

My IMU is mounted subflush in a 40 x 40 x 40 mm PLA plastic cube, so I can measure its actual pitch, roll, yaw with tools.

I am moving the IMU in large "figure 8s", as I rotate slowly in a circle. I do this with each of the six sides facing up in turn, first with x up, then x down, then y up, then y down, then z up and then z down. Also a whole bunch of wild waving around of the IMU to get as much random information as possible. Samples are taken at approx. 100 Hz. Here's the output of that calibration dance:

('maximum magnetometer readings ', [54.6, 72.0, 155.54999999999998])
('minimum magnetometer readings ', [-80.1, -79.64999999999999, 34.35])
('Hard iron bias ', array([-12.75 ,  -3.825,  94.95 ]))
('average of deltas for soft iron correction (scalar) ', 67.925)
('Soft Iron Bias rescaling array ', array([1.00853749, 0.89581273, 1.12087459]))
('raw magnetometer reading ', (-49.05, -19.2, 111.75))
('Current hard iron corrected magnetometer reading ', array([-36.3  , -15.375,  16.8  ]))
('Current magnetometer reading with hard and soft iron corrections ', array([-36.60991091, -13.77312067,  18.83069307]))

The soft iron rescaling array shows fairly large differences in the scale between each axis: x = 0.9%, y = 10.4%, z = 12.1% This indicates to me that the sensitivity between the axes is very different. I tried another IMU and got similar-ish numbers. If that's all there was, I wouldn't be writing. Anyway, now the weird part starts...

Now I have placed the IMU cube on a leveled wooden workbench in my lab. I see that the IMU should be using Z positive down (as indicated by a symbol on the PCBA). In these first data samples, Z is pointing down and the sensor is level. The sensor is held down with a wooden block and is immobile. I have not implemented a filter, so there is noise in the signal:

('raw magnetometer reading ', (10.95, 4.95, 49.8))
('hard iron correction bias ', array([-12.75 ,  -3.825,  94.95 ]))
('magnetormeter reading with hard iron bias subtracted ', array([ 23.7  ,   8.775, -45.15 ]))
('magnetometer reading corrected for hard and soft iron scaling ', array([ 23.90233853,   7.86075668, -50.60748762]))

('raw magnetometer reading ', (12.0, 4.5, 47.699999999999996))
('hard iron correction bias ', array([-12.75 ,  -3.825,  94.95 ]))
('magnetormeter reading with hard iron bias subtracted ', array([ 24.75 ,   8.325, -47.25 ]))
('magnetometer reading corrected for hard and soft iron scaling ', array([ 24.9613029 ,   7.45764095, -52.96132426]))

('raw magnetometer reading ', (11.4, 3.9, 49.5))
('hard iron correction bias ', array([-12.75 ,  -3.825,  94.95 ]))
('magnetormeter reading with hard iron bias subtracted ', array([ 24.15 ,   7.725, -45.45 ]))
('magnetometer reading corrected for hard and soft iron scaling ', array([ 24.3561804 ,   6.92015331, -50.94375   ]))

I would have expected that the corrected z would remain a positive number, since it's facing down. Also, we see that even though it is pointing straight down, it's value is very far from the maximum measured during calibration. This could mean that there's some sort of iron anomaly in my house, or there is some sort of off-axis magnetic phenomenon that's pretty strong.

Now I turn the cube over, with z facing up. The block has rotated slightly, so x and y differ from the three 'z down' samples. Again, a wooden block has been placed on top of the cube that the IMU is mounted in, and the cube is motionless:

('raw magnetometer reading ', (5.55, 19.05, -22.65))
('hard iron correction bias ', array([-12.75 ,  -3.825,  94.95 ]))
('magnetormeter reading with hard iron bias subtracted ', array([  18.3  ,   22.875, -117.6  ]))
('magnetometer reading corrected for hard and soft iron scaling ', array([  18.45623608,   20.49171612, -131.81485149]))

('raw magnetometer reading ', (5.1, 19.8, -21.15))
('hard iron correction bias ', array([-12.75 ,  -3.825,  94.95 ]))
('magnetormeter reading with hard iron bias subtracted ', array([  17.85 ,   23.625, -116.1  ]))
('magnetometer reading corrected for hard and soft iron scaling ', array([  18.00239421,   21.16357567, -130.1335396 ]))

('raw magnetometer reading ', (4.8, 18.3, -20.849999999999998))
('hard iron correction bias ', array([-12.75 ,  -3.825,  94.95 ]))
('magnetormeter reading with hard iron bias subtracted ', array([  17.55 ,   22.125, -115.8  ]))
('magnetometer reading corrected for hard and soft iron scaling ', array([  17.69983296,   19.81985658, -129.79727723]))

Strangely, the raw data for the 'z facing up' samples shows negative numbers for the z value, even though the minimum for z measured in calibration was a positive number! I can verify that a large number of samples were taken with z pointed in the straight down and straight up directions. I also would have expected the raw magnetometer reading to be the opposite of what it was in the previous data. Obviously, I can't compute a heading with this kind of behaviour...

I have tried this in a variety of rooms in my home. At first, I thought I was getting a lot of magnetic information from equipment in my lab, so I moved to my dining room to take the calibration samples. This room is large, with a very high ceiling and almost no ferrous metal in sight. No differences were observed.

Any ideas?

Thank you, Mark

kriswiner commented 3 years ago

Hi Mark,

There is something seriously wrong with your results.

What MCU are you using? What MPU9250 board? ARe you using I2C or SPI? Which sketch (link if possible).

You should be able to use a basic sketch that reads and scales the sensor data without calibration and demonstrate that the mag values you are getting are reasonable. Reasonable means total magnitude SQRT(mx^2 + my^2 + mz^2) should be ~0.5 Gauss. The z-component should be ~0.4 Gauss when the board is flat and motionless with z-axis pointed up and about -0.4 Gauss when pointed down.

Until you have obtained this result, calibration is irrelevant.

Kris

On Thu, Sep 10, 2020 at 7:32 AM rob-meiner notifications@github.com wrote:

Hi Kris, First, thanks for the excellent resource on IMUs. I've read a lot about calibrating the magnetometer, but somehow can't get this to work on my device. Here's output from my initial calibration. I have increased my sample size to 5000, since I can't seem to get any results that make sense.

My IMU is mounted in a cube, so I can measure its actual pitch, roll, yaw with tools.

I am moving the IMU in large "figure 8s", as I rotate slowly in a circle. I do this with each of the six sides facing up in turn, first with x up, then x down, then y up, then y down, then z up and then z down. Also a whole bunch of wild waving around of the IMU to get as much random information as possible. Samples are taken at approx. 100 Hz. Here's the output of that calibration dance:

('maximum magnetometer readings ', [54.6, 72.0, 155.54999999999998]) ('minimum magnetometer readings ', [-80.1, -79.64999999999999, 34.35]) ('Hard iron bias ', array([-12.75 , -3.825, 94.95 ])) ('average of deltas for soft iron correction (scalar) ', 67.925) ('Soft Iron Bias rescaling array ', array([1.00853749, 0.89581273, 1.12087459])) ('raw magnetometer reading ', (-49.05, -19.2, 111.75)) ('Current hard iron corrected magnetometer reading ', array([-36.3 , -15.375, 16.8 ])) ('Current magnetometer reading with hard and soft iron corrections ', array([-36.60991091, -13.77312067, 18.83069307]))

The soft iron rescaling array shows fairly large differences in the scale between each axis: x = 0.9%, y = 10.4%, z = 12.1% This indicates to me that there is some kind of iron anomy somewhere in my home, or the sensitivity between the axes is very different. I tried another IMU and got similar-ish numbers, so there's probably a lodestone buried around here somewhere... Anyway, now the weird part starts...

Now I have placed the IMU cube on a leveled wooden workbench in my lab. I see that the IMU should be using Z positive down (as indicated by a symbol on the PCBA). In these first data samples, Z is pointing down and the sensor is level. The sensor is held down with a wooden block and is immobile:

('raw magnetometer reading ', (10.95, 4.95, 49.8)) ('hard iron correction bias ', array([-12.75 , -3.825, 94.95 ])) ('magnetormeter reading with hard iron bias subtracted ', array([ 23.7 , 8.775, -45.15 ])) ('magnetometer reading corrected for hard and soft iron scaling ', array([ 23.90233853, 7.86075668, -50.60748762]))

('raw magnetometer reading ', (12.0, 4.5, 47.699999999999996)) ('hard iron correction bias ', array([-12.75 , -3.825, 94.95 ])) ('magnetormeter reading with hard iron bias subtracted ', array([ 24.75 , 8.325, -47.25 ])) ('magnetometer reading corrected for hard and soft iron scaling ', array([ 24.9613029 , 7.45764095, -52.96132426]))

('raw magnetometer reading ', (11.4, 3.9, 49.5)) ('hard iron correction bias ', array([-12.75 , -3.825, 94.95 ])) ('magnetormeter reading with hard iron bias subtracted ', array([ 24.15 , 7.725, -45.45 ])) ('magnetometer reading corrected for hard and soft iron scaling ', array([ 24.3561804 , 6.92015331, -50.94375 ]))

I would have expected that z would show a positive number, since it's facing down. Also, we see that even though it is pointing straight down, it's value is very far from the maximum measured during calibration.

Now I turn the cube over, with z facing up. The block has rotated slightly, so x and y differ from the three 'z down' samples. Again, a wooden block has been placed on top of the cube that the IMU is mounted in, and the cube is motionless:

('raw magnetometer reading ', (5.55, 19.05, -22.65)) ('hard iron correction bias ', array([-12.75 , -3.825, 94.95 ])) ('magnetormeter reading with hard iron bias subtracted ', array([ 18.3 , 22.875, -117.6 ])) ('magnetometer reading corrected for hard and soft iron scaling ', array([ 18.45623608, 20.49171612, -131.81485149]))

('raw magnetometer reading ', (5.1, 19.8, -21.15)) ('hard iron correction bias ', array([-12.75 , -3.825, 94.95 ])) ('magnetormeter reading with hard iron bias subtracted ', array([ 17.85 , 23.625, -116.1 ])) ('magnetometer reading corrected for hard and soft iron scaling ', array([ 18.00239421, 21.16357567, -130.1335396 ]))

('raw magnetometer reading ', (4.8, 18.3, -20.849999999999998)) ('hard iron correction bias ', array([-12.75 , -3.825, 94.95 ])) ('magnetormeter reading with hard iron bias subtracted ', array([ 17.55 , 22.125, -115.8 ])) ('magnetometer reading corrected for hard and soft iron scaling ', array([ 17.69983296, 19.81985658, -129.79727723]))

Strangely, the raw data for the 'z facing up' samples shows negative numbers for the z value, even though the minimum for z measured in calibration was a positive number! I can verify that a large number of samples were taken with z pointed in the straight down and straight up directions. I also would have expected the raw magnetometer reading to be the opposite of what it was in the previous data. Obviously, I can't compute a heading with this kind of behaviour...

Any ideas?

Thank you, Mark

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/376#issuecomment-690329012, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKTBM62TZM2CYFFNQYDSFDPONANCNFSM4HQJMCUA .