kriswiner / LSM9DS1

ST's new smaller, lower-power 9-axis motion sensor
40 stars 28 forks source link

Magnetometer calibration #10

Open gpgabriel opened 6 years ago

gpgabriel commented 6 years ago

Hi,

This is not an issue, it's more of a question, I spent a few good days on this.

I'm trying to calibrate the magnetometer inside LSM9DS1 and I'm not sure if my sensor is broken or if I get something wrong.

After I get the offset values and I apply them in the Madgwick filter, my yaw still drifts.

My guess is that the problem is related to the fact that no matter how slow or 'in a sphere' I move the sensor, the xy line never forms a circle, it's always a shaky line. Does anyone know why this happens?

Here's a video with the calibration attempt: https://youtu.be/C8gwi17Sdag (xy - blue; xz - pink; yz - yellow)

(No highlitht on the xy axis) https://youtu.be/bjhdq8AKYg4

Gabriel

kriswiner commented 6 years ago

Are you sure you are moving the sensor in three dimensions and that it is not sitting flat on a table or something? If you are moving it in all three dimensions in order to sample the entire 3D response surface then your mag is busted.

On Fri, Jan 5, 2018 at 6:53 AM, Gabriel Gabor notifications@github.com wrote:

Hi,

This is not an issue, it's more of a question, I spent a few good days on this.

I'm trying to calibrate the magnetometer inside LSM9DS1 and I'm not sure if my sensor is broken or if I get something wrong.

After I get the offset values and I apply them in the Madgwick filter, my yaw still drifts.

My guess is that the problem is related to the fact that no matter how slow or 'in a sphere' I move the sensor, the xy line never forms a circle, it's always a shaky line. Does anyone know why this happens?

Here's a video with the calibration attempt: https://youtu.be/C8gwi17Sdag (xy - blue; xz - pink; yz - yellow)

Gabriel

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/kriswiner/LSM9DS1/issues/10, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qpXVp-cgyWJmzsUZetX6pITALhE-ks5tHjdSgaJpZM4RUiSt .

gpgabriel commented 6 years ago

Thanks for you're reply.

I do move the sensor, it's not on a flat surface: https://www.youtube.com/watch?v=pki_M7tG-tc https://www.youtube.com/watch?v=NJShln7A4iQ

A bit more context: the sensor is connected to a nrf52832 and the data is sent over serial to a node app which then displays the graphics. There's nothing else running on the nrf52832.

kriswiner commented 6 years ago

Turn it upside down and in every possible orientation.

In the videos you are just turning it left and right. There is one more dimension you need to sample!

On Fri, Jan 5, 2018 at 10:08 AM, Gabriel Gabor notifications@github.com wrote:

Thank you for being so fast with the reply.

I do move the sensor while doing the test: https://www.youtube.com/watch?v=pki_M7tG-tc https://www.youtube.com/watch?v=NJShln7A4iQ

A bit more context: the sensor is connected to a nrf52832 and the data is sent over serial to a node app which then displays the graphics. There's nothing else running on the nrf52832.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/LSM9DS1/issues/10#issuecomment-355624306, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qm195Oz8MS7SOmoq5ODPVoZ87qqhks5tHmU0gaJpZM4RUiSt .

gpgabriel commented 6 years ago

Hi, sorry for my late reply. I went through a lot of options and learned a lot.

@kriswiner Thank you for the good advice.

The magnetometer calibration is not an issue anymore, I was able to calibrate it and it looks ok (the problem from the previous video was they way I was rotating the sensor). After that, I applied the Madgwick filter to get the Euler variables. I had to also calibrate the gyroscope to get good results. I have one more issue which I'm trying to solve. You can see it in this video at the second 20. For some reason it flips pretty bad. I spent a few good hours trying to solve this. I tried fixing the descent algorithm (as described here), tried to put a better invSqrt algorithm (as described here), tried to change the computeAngles method with this one and still the flip happens.

At the moment I call the Madgwick update function as bellow: MadgwickAHRSupdate((-1) * gx, (-1) * gy, (-1) * gz, ax, ay, az, mx, (-1) * my, (-1) * mz) where gx is the calibrated value in radians per second, ax is the accelerometer in G and mx is the magnetometer is Gs.

I feel like I tried everything and I'm running out of ideas.

kriswiner commented 6 years ago

MadgwickAHRSupdate((-1) gx, (-1) gy, (-1) gz, ax, ay, az, mx, (-1) my, (-1) * mz)

This filter expects accel, gyro, mag

Also, it expect NED, so An, Ae, Ad, Gn, Ge, Gd, Mn, Me, Md

You have the order worng.

On Wed, Feb 28, 2018 at 11:13 AM, Gabriel Gabor notifications@github.com wrote:

Hi, sorry for my late reply. I went through a lot of options and learned a lot.

The magnetometer calibration is not an issue anymore, I was able to calibrate it and it looks ok (the problem from the previous video was they way I was rotating the sensor). After that, I applied the Madgwick filter to get the Euler variables. I had to also calibrate the gyroscope to get good results. I have one more issue which I'm trying to solve. You can see it in this video https://youtu.be/XddDi61QL6Q at the second 20. For some reason it flips pretty bad. I spent a few good hours trying to solve this. I tried fixing the descent algorithm (as described here https://diydrones.com/forum/topics/madgwick-imu-ahrs-and-fast-inverse-square-root?id=705844%3ATopic%3A1018435&page=4#comments), tried to put a better invSqrt algorithm (as described here https://diydrones.com/forum/topics/madgwick-imu-ahrs-and-fast-inverse-square-root?id=705844%3ATopic%3A1018435&page=6#comments), tried to change the computeAngles method with this one https://github.com/PenguPilot/PenguPilot/blob/master/autopilot/service/util/math/quat.c#L103 and still the flip happens.

At the moment I call the Madgwick update function as bellow: MadgwickAHRSupdate((-1) gx, (-1) gy, (-1) gz, ax, ay, az, mx, (-1) my, (-1) * mz) where gx is the calibrated value in radians per second, ax is the accelerometer in G and mx is the magnetometer is Gs.

I feel like I tried everything and I'm running out of ideas.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/LSM9DS1/issues/10#issuecomment-369349923, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qlL62JM-xwntpPtXKdzdsvuOWHJvks5tZaVsgaJpZM4RUiSt .

gpgabriel commented 6 years ago

I'm using an identical version of the filter but with a different function definition void MadgwickAHRSupdate(float gx, float gy, float gz, float ax, float ay, float az, float mx, float my, float mz)

Also, it expect NED, so An, Ae, Ad, Gn, Ge, Gd, Mn, Me, Md - I'm not sure what to modify about this. I checked the datasheet (pag. 10) and I suppose that NED (north-east-down) should be the mapping to xyz but I'm not sure if I'm right. Given the new info, I tried: MadgwickAHRSupdate(gx, gy, (-1) * gz, ax, ay, (-1) * az, (-1) * mx, (-1) * my, (-1) * mz) but it's still flipping. Thanks for the quick reply!

kriswiner commented 6 years ago

If you modified the madgwick filter to accept gyro data first this is fine. But could confuse others.

Which direction do you want to be North on the board? Then which axis of the accel is pointing in that direction? Once this is established, the rest follows. Which accel axis is pointing East, Down. The gyro, then mag. If you look at the data sheet the mag is oriented differently from the accel and gyro so your function above will yield non-sense results (i.e., "flipping"). The axiaal alignments in the filter function must be consistent. NED ordering is the way to enforce consistency.

On Wed, Feb 28, 2018 at 11:34 AM, Gabriel Gabor notifications@github.com wrote:

I'm using an identical version of the filter but with a different function definition void MadgwickAHRSupdate(float gx, float gy, float gz, float ax, float ay, float az, float mx, float my, float mz)

Also, it expect NED, so An, Ae, Ad, Gn, Ge, Gd, Mn, Me, Md - I'm not sure what to modify about this. I checked the datasheet http://www.st.com/content/ccc/resource/technical/document/datasheet/1e/3f/2a/d6/25/eb/48/46/DM00103319.pdf/files/DM00103319.pdf/jcr:content/translations/en.DM00103319.pdf (pag. 10) and I suppose that NED (north-east-down) should be the mapping to xyz but I'm not sure if I'm right. Given the new info, I tried: MadgwickAHRSupdate(gx, gy, (-1) gz, ax, ay, (-1) az, (-1) mx, (-1) my, (-1) * mz) but it's still flipping. Thanks for the quick reply!

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/kriswiner/LSM9DS1/issues/10#issuecomment-369356462, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qnSrRhmi7syEUUEPzULz49J5gMypks5tZapPgaJpZM4RUiSt .

gpgabriel commented 6 years ago

Maybe I understand this wrong. For accel it looks like Z is pointing up, hence the (-1) * az, the x is pointing north which fine, same for y. The gyro looks identical so I applied the same rule. For the magnetometer, the white dot is in the other corner so I considered that x is pointing opposite, same for y and z is pointing up, hence the (-1) * for all the points. It looks to me accel, gyro and magn are all aligned after I apply the above changes. Still unclear why it flips.

kriswiner commented 6 years ago

How can the accel/gyro and max z-axes be pointing in the same direction?

On Wed, Feb 28, 2018 at 11:54 AM, Gabriel Gabor notifications@github.com wrote:

Maybe I understand this wrong. For accel it looks like Z is pointing up, hence the (-1) az, the x is pointing north which fine, same for y. The gyro looks identical so I applied the same rule. For the magnetometer, the white dot is in the other corner so I considered that x is pointing opposite, same for y and z is pointing up, hence the (-1) for all the points. It looks to me accel, gyro and magn are all aligned after I apply the above changes. Still unclear why it flips.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/kriswiner/LSM9DS1/issues/10#issuecomment-369362609, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qhdfa9_EWBPB6G5hp_SxvZR5GxxBks5tZa8TgaJpZM4RUiSt .

gpgabriel commented 6 years ago

This is what the datasheet looks like. By default, accel/gyro and mag are all pointing up, I'm adding (-1) * to all of them to comply with NED.

kriswiner commented 6 years ago

Sorry, I was thinking MPU9250, too many e-mail discussions.

Now on the flipping, the roll goes from -90 to +90, pitch -180, 180 (or mabe the names are reversed) and headion 0 to 360. So in your plotting code you might just be encountering a switch from -180 to +180...

On Wed, Feb 28, 2018 at 12:10 PM, Gabriel Gabor notifications@github.com wrote:

This is what the datasheet looks like. By default, accel/gyro and mag are all pointing up, I'm adding (-1) * to all of them to make comply with NED.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/kriswiner/LSM9DS1/issues/10#issuecomment-369367117, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qp3dGTwN19I3186ikMUo9pAH3jjaks5tZbK7gaJpZM4RUiSt .

kriswiner commented 6 years ago

This is what I am using for the LSM9DS1:

MadgwickQuaternionUpdate(ax, ay, az, gxPI/180.0f, gyPI/180.0f, gz*PI/180.0f, -mx, my, mz);

On Wed, Feb 28, 2018 at 12:14 PM, Tlera Corporation tleracorp@gmail.com wrote:

Sorry, I was thinking MPU9250, too many e-mail discussions.

Now on the flipping, the roll goes from -90 to +90, pitch -180, 180 (or mabe the names are reversed) and headion 0 to 360. So in your plotting code you might just be encountering a switch from -180 to +180...

On Wed, Feb 28, 2018 at 12:10 PM, Gabriel Gabor notifications@github.com wrote:

This is what the datasheet looks like. By default, accel/gyro and mag are all pointing up, I'm adding (-1) * to all of them to make comply with NED .

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/kriswiner/LSM9DS1/issues/10#issuecomment-369367117, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qp3dGTwN19I3186ikMUo9pAH3jjaks5tZbK7gaJpZM4RUiSt .

gpgabriel commented 6 years ago

It looks like when I move on the pitch rotation, the roll doesn't stay fixed. Once I get close to 80-90 degrees, the roll grows quickly to 180 degrees. Thanks a lot for the quick responses!

kriswiner commented 6 years ago

I think you still have am error in your sensor order. Can you try mine (maybe with accel and gyro interchanged to match your changes) and see if you still have this problem?

On Wed, Feb 28, 2018 at 12:23 PM, Gabriel Gabor notifications@github.com wrote:

It looks like when I move on the pitch rotation, the roll doesn't stay fixed. Once I get close to 80-90 degrees, the roll grows quickly to 180 degrees.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/kriswiner/LSM9DS1/issues/10#issuecomment-369370678, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qtiIpUkxfbyqrBtqpqf-a7ZCKqMGks5tZbXKgaJpZM4RUiSt .

kriswiner commented 6 years ago

You can see that if Ax in North, Ay is East, -Az is Down, same with gyro.

But mag North is -Mx, East is My, Down is -Mz

So Madgwick(Ax, Ay, -Az, Gx, Gy, -Gz, -Mx, My, -Mz) should work.

Negating the z-axis components switch the polarity and might be correct if the board is mounted upside down. Down in the algorithm refers to the direction of Gravity.

On Wed, Feb 28, 2018 at 12:27 PM, Tlera Corporation tleracorp@gmail.com wrote:

I think you still have am error in your sensor order. Can you try mine (maybe with accel and gyro interchanged to match your changes) and see if you still have this problem?

On Wed, Feb 28, 2018 at 12:23 PM, Gabriel Gabor notifications@github.com wrote:

It looks like when I move on the pitch rotation, the roll doesn't stay fixed. Once I get close to 80-90 degrees, the roll grows quickly to 180 degrees.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/kriswiner/LSM9DS1/issues/10#issuecomment-369370678, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qtiIpUkxfbyqrBtqpqf-a7ZCKqMGks5tZbXKgaJpZM4RUiSt .

kriswiner commented 6 years ago

Forgot to attach.

On Wed, Feb 28, 2018 at 12:34 PM, Tlera Corporation tleracorp@gmail.com wrote:

You can see that if Ax in North, Ay is East, -Az is Down, same with gyro.

But mag North is -Mx, East is My, Down is -Mz

So Madgwick(Ax, Ay, -Az, Gx, Gy, -Gz, -Mx, My, -Mz) should work.

Negating the z-axis components switch the polarity and might be correct if the board is mounted upside down. Down in the algorithm refers to the direction of Gravity.

On Wed, Feb 28, 2018 at 12:27 PM, Tlera Corporation tleracorp@gmail.com wrote:

I think you still have am error in your sensor order. Can you try mine (maybe with accel and gyro interchanged to match your changes) and see if you still have this problem?

On Wed, Feb 28, 2018 at 12:23 PM, Gabriel Gabor <notifications@github.com

wrote:

It looks like when I move on the pitch rotation, the roll doesn't stay fixed. Once I get close to 80-90 degrees, the roll grows quickly to 180 degrees.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/kriswiner/LSM9DS1/issues/10#issuecomment-369370678, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qtiIpUkxfbyqrBtqpqf-a7ZCKqMGks5tZbXKgaJpZM4RUiSt .

gpgabriel commented 6 years ago

I tried Madgwick(Ax, Ay, -Az, Gx, Gy, -Gz, -Mx, My, -Mz) and unfortunately it's still flipping. I'm replacing the Madgwick function now with exactly the one from this repo, I'll be back with the results.

gpgabriel commented 6 years ago

Just copy pasted your algorithm and it still flips. Here is the call:

#define FROM_DEGREE_TO_RAD                          0.0174533f
MadgwickQuaternionUpdate(
                calcAccel(ax),
                calcAccel(ay),
                calcAccel(az),
                (calcGyro(gx) - gyroOffset[0]) * FROM_DEGREE_TO_RAD, 
                (calcGyro(gy) - gyroOffset[1]) * FROM_DEGREE_TO_RAD, 
                (calcGyro(gz) - gyroOffset[2]) * FROM_DEGREE_TO_RAD,
                (-1) * (calcMag(mx) - magnOffset[0]), 
                (calcMag(my) - magnOffset[1]),
                (calcMag(mz) - magnOffset[2])
            );

I'm running the update at 64Hz so I defined #define deltat 0.0156f

Here's a video with the result.

kriswiner commented 6 years ago

This is a very inefficient way to handle this because of the latency embedded in the separate reads and will introduce large errors in the results at all but the smallest data rates.

Much better is to read all of the sensor data in one I2C read operation and store the data in a buffer. Then scale as necessary, then pass the data into the fusion filter. Otherwise there could be several milliseconds difference between the data times, time misaligned, etc

I doubt this will affect the flipping you are seeing. This probably has to do with the ambiguity at the poles. Not sure there is anything you can do about this..

On Wed, Feb 28, 2018 at 1:08 PM, Gabriel Gabor notifications@github.com wrote:

Just copy pasted your algorithm and it still flips. Here is the call:

define FROM_DEGREE_TO_RAD 0.0174533f

MadgwickQuaternionUpdate( calcAccel(ax), calcAccel(ay), calcAccel(az), (calcGyro(gx) - gyroOffset[0]) FROM_DEGREE_TO_RAD, (calcGyro(gy) - gyroOffset[1]) FROM_DEGREE_TO_RAD, (calcGyro(gz) - gyroOffset[2]) FROM_DEGREE_TO_RAD, (-1) (calcMag(mx) - magnOffset[0]), (calcMag(my) - magnOffset[1]), (calcMag(mz) - magnOffset[2]) );

Here's a video https://youtu.be/4dZgdn6eyss with the result.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/kriswiner/LSM9DS1/issues/10#issuecomment-369383174, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qhAoo-IXnHggRAwuivkKwZz4JRswks5tZcA2gaJpZM4RUiSt .

gpgabriel commented 6 years ago

Thank you for all the details and patience with this! I will refactor the driver to read the data in one I2C operation but first I would try to get a proof of concept if that's not the reason for the flip.

This probably has to do with the ambiguity at the poles. Not sure there is anything you can do about this..

I've seen multiple examples with the same set up working (I'm using nrf52832 as the micro controller). I'll have to read a bit more about ambiguity at the poles, is this related to my location? Do you think I'll get better results with the MPU9250?

kriswiner commented 6 years ago

Nothing to do with location, has to do with ambiguity at the poles in the sense of orientation estimation. Meaning, when you are standing at the North pole, which way is South? All of them...

nRF52832 should have enough horsepower to run the fusion algorithm at a fast enough rate to give a good orientation estimation.

MPU9250 works well but I doubt this would give any different result. I expect the problem is with the plotting routine. But if others get an acceptable result you might ask them how.

On Wed, Feb 28, 2018 at 4:47 PM, Gabriel Gabor notifications@github.com wrote:

Thank you for all the details and patience with this! I will refactor the driver to read the data in one I2C operation but first I would try to get a proof of concept if that's not the reason for the flip.

This probably has to do with the ambiguity at the poles. Not sure there is anything you can do about this..

I've seen multiple examples with the same set up working (I'm using nrf52832 as the micro controller). I'll have to read a bit more about ambiguity at the poles, is this related to my location? Do you think I'll get better results with the MPU9250?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/kriswiner/LSM9DS1/issues/10#issuecomment-369435612, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qoPbTs6twXJn-kzr3ZAT4rIePSUfks5tZ0UdgaJpZM4RUiSt .

gpgabriel commented 6 years ago

I finally got a good (slightly drifting) version. The flip was caused by the way I was computing the Euler variables. Now I'm sending the quaternions and compute the Euler variables on the client and it seems to work. Many thanks to @kriswiner for all the good advice posted here.

glucee commented 6 years ago

@gpgabriel I have similar problem with you, could you also upload you modified code ? And by the way, how do you do the calibration ?