-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Not able to read absolute orientation (tilt) using DMP #59
Comments
In an older version of this lib I remember using different formulas written by @PaulZC :
But these computations could also be false regarding #55 (q0) ? With my small tests (note: I'm quite a noob here between all of you) I didn't see some weird roll, pitch and yaw values Maybe @PaulZC is computing these angles in a different reference frame ? (This is example is from a Quat6 example) |
@Niv1900 To be honest, I completely overlooked that Example7 actually has code to compute the Euler angles. TLDR of my issue is two things:
Please let me know if I can investigate a different mode or setting. |
Hi Bernhard, Thank you for taking the time to study this - I appreciate the help. I know that the DMP requires calibration, like you used to have to do with the earlier Bosch devices, but, yes, I would expect it to be able to get the orientation correct using the accelerometer at power up. Sadly, I have no more information about the difference between ROTATION_VECTOR and GEOMAGNETIC_ROTATION_VECTOR. I assume the difference is the frame of reference, but I am not sure. The code which sets the magnetometer axes is here. I completely understand why you might think it has been set incorrectly, based on how the chip behaves, but, to me, the settings look completely correct. They match the settings I captured from the InvenSense Nucleo code (on the I2C bus) and the InvenSense code comments mention the same 'magic number' of 161061273 for the scaling. The minuses at MTX_11 and MTX_22 also look correct given the different orientation of the magnetometer vs the accel and gyro (mag Y and Z are inverted): The settings I am less confident in are these. I have used the values from the InvenSense application note but the I2C traffic I captured from the Nucleo example code showed them being set very differently:
Looking at the code, I am using the correct values for ALPHA_VAR and A_VAR. I am a little worried about the ACCEL_ONLY_GAIN but only a little. The I2C traffic suggests the Nucleo code was using 'default' values for ALPHA_VAR and A_VAR and ACCEL_ONLY_GAIN. While I was investigating the I2C Master ODR configuration issue, I noticed a setting called Good luck - and thanks again for the help, |
Hi Paul, thank you for all these references! Very useful to have it laid out like this. Best wishes, |
Hi @bernhardHartleb, Please keep us updated on your efforts. I am also very keen to know if absolute heading (tilt-compensated) can be obtained from the ICM-20948. In theory, we shouldn't actually need sensor fusion for this, though we do need to calibrate the magnetometer. Cheers, |
Hi Bernhard (@bernhardHartleb ), I have, I think, solved this issue. By going byte by byte through the SPI data from the InvenSense example, I found that: the I2C Master, accel and gyro were all being placed in low power mode initially (our library did the same thing); but that later the setting was changed leaving only the I2C Master in low power mode. Having the accel and gyro in low power mode was causing the erroneous behavior you were seeing. Using the Quat9 example, I can now power up the ICM-20948 in a random orientation and - after rotating it around all three axes and holding it stationary in all six orientations - the quaternions become well behaved, returning to the same absolute values on every occasion. If you are interested in the root cause, please see dmp.md and do a search on that page for Please try v1.2.6. I think you will be pleased! Best wishes, |
Hey Everyone, I figured I'd add my two cents to the discussion - I ran the 1.1.6 and 1.1.7 versions on three different chips, and unfortunately for me, those versions did not work on any of them. I was having the same problem (the sensors would respond beautifully to quicker rotations but then within about 3 seconds drift to a seemingly random yet consistent value that wasn't the actual orientation of the chip). This seems like a similar error to what the OP was having. What ended up fixing the problem for me was to set the Gyro offset registers (0x03-0x08) in User Bank 2. The formula for calculating these offset biases is to take the gyro offset for each axis (I got this by averaging 10 measurements for each gyro axis using the "Example 1: Basics" sketch included in the Sparkfun library) and divide this by the constant 0.031. Note that for this to work the chip has to be still. For me, the drift values I read were: The Corresponding biases were (drift/0.031) - rounded to nearest whole: And the corresponding (signed!) hex: I wrote those values into bank two and, after the mag calibration finished, the 9 axis magically worked. The thing that really puzzles me is that there are also bias registers in the DMP image/memory as well! So why the need for both? |
Hi @Eemac , This is great stuff - thank you! Just to be clear, did you mean v1.2.6 and v1.2.7? v1.2.7 is the latest and greatest. The previous versions were all flawed in one way or another. Would you like to submit a Pull Request to add a setGyroOffset function? Or are you happy for me to run with your idea and credit you in the release notes? Very best wishes, |
Hey Paul, Yes, I meant to say v1.2.6/7. Sorry about that! Unfortunately I'm going to be away for a while, so I don't think I'll be able to contribute much in the near future. Hopefully my "fix" works for you guys too! Cheers, |
Hey @PaulZC , Thank you for your excellent work on this library. I am using v 1.2.9. I don't see the gyro settling down to an inconsistent value(using quat9 RV). Has this issue been fixed or have I just been lucky with my testing so far? Cheers, |
It turns out that this problem can be avoided all together if the DMP calibration algorithms are enabled. If a no-movement state is detected (literally holding the chip still), the gyro will auto calibrate. The registers I was referring to are for external to the DMP and shouldn't be used if you want DMP functionality. Sorry about the confusion! |
@Eemac In the current Quat9 example are you able to get non-drifting quaternion values? And how do you enable these DMP calibration algorithms? Currently my issue is that I can place my IMU steady on all 3 axes (x pointing down, y pointing down, z pointing down), and then find a steady state (quaternion values stop changing) in any position. But when I move from position to position it always takes a handful of seconds for the quaternion to settle to concrete values. I could be doing something wrong. Do you know how you got your values to be accurate? |
Hi @joshgalvan - yes it is possible to get non-drifting values, but I've found that it takes a lot of finessing to get correct. A question: are you using SPI or I2C to communicate with the ICM20948? I've gotten I2C to work but am still trying to get SPI. To enable the mag/accel/gyro auto-calibration + 9-axis fusion algorithm, set the MOTION_EVENT_CTL register in the DMP to 0x03C0. Once the calibration algorithms are running, they will constantly update. There are flags (one each for accel/gyro/mag) that are set when the calibration filters have enough useful data (check the HEADER2 parameters in chip setup). 0x0000 means the algorithm is either not running or doesn't yet have enough data points. 0x0002 is only seen with the mag I think, and means that a magnetic disturbance has occurred (you can simulate this by placing a magnet close to the IMU). 0x0003 is awesome - it means that the calibration algorithm is working for that sensor and that data is clean enough to be used in the 9-axis fusion algorithm.
This seems like a mag calibration issue. Yaw orientation cannot be inferred from the other two sensors, and if you don't have mag data in the fusion algorithm, the mag portion of the algorithm will think it's facing north no matter what. The orientation output moves initially from position to position because the gyro and accel pick up on the movement in the short term (on the order of ms). The mag will correct in the long term (3-5 secs) - why you see movement for a couple of seconds after holding the chip steady in a new location. The magnetometer has been notoriously difficult for me to calibrate - sometimes it takes 5 mins of circling through every possible orientation, and sometimes it takes 5 seconds. It looks like you're calibrating the accel and gyro correctly (x/y/z down - no motion state), though. You can also check the values of your calibration algorithms by looking at: GYRO_BIAS_X, GYRO_BIAS_Y, GYRO_BIAS_Z, ACCEL_BIAS_X, ACCEL_BIAS_Y, ACCEL_BIAS_Z, CPASS_BIAS_X, CPASS_BIAS_Y, CPASS_BIAS_Z in the DMP while it is running. If the values for a sensor are 0x00000000 for X/Y/Z the chip isn't calibrated for that sensor. |
Thank you for all of the info! I will try out checking those registers. I am slightly confused though, are you saying that you don't have calibration issues over I2C? And that you're not able to get it to calibrate over SPI? Also, I just realized, in the datasheet I can't find any of the BIAS registers or the MOTION_EVENT_CTL register. And, do you have tips on the best way to calibrate the magnetometer? Again, thank you for the help! I really appreciate it. Edit: Edit: |
@Eemac - Thank you for your last post. It is super helpful. A really noob question - to set MOTION_EVENT_CTL is it simply a case of changing line 44 in ICM_20948_DMP.h to the correct value? I've done that and still get Header2 value of 0. Just wondering if I should be doing it in a different way? |
Hi Paul,
now that the compass data is available to the DMP, I tried to verify the output against a BNO055 board from production.
In modes ORIENTATION and ROTATION_VECTOR the heading (x-axis) will drift to the a magnetic direction, but roll and pitch axis always start at 0°. Even if the sensor is kept at a constant 90° tilt (vertical), the output stays permanently at the initial ~0° value in those modes.
Only the mode GEOMAGNETIC_ROTATION_VECTOR seems to give an absolute orientation and outputs the 90° tilt correctly.
However, for some reason this mode is extremely slow to update. A 90° change in tilt takes over 10sec to settle, even tough the DMP is supposed to run at 55Hz.
Other 9-axis modes show large rotations instantly + get the heel and pitch axis correct, but do not give absolute orientation. Even worse, if you tilt the sensor by only 45° the heading suddenly changes. It should be steady as long as it "points" in the same direction. This makes none of the modes very useful for real world applications where absolute orientation is important.
In summary, the following things do not work for me when using DMP results:
This leads me to believe that at least the axis configuration of of the magnetometer could be wrong.
For testing we have to be able to convert the Quaternion output into Euler angles.
I would like to contribute the following code for that:
Sorry for the bother with these issues, but I would really like to get some "truth" out of this sensor.
I know this IMU is especially difficult to configure, but I have a good reference, some experience, and would like to help :)
Best regards,
Bernhard
The text was updated successfully, but these errors were encountered: