Open obromios opened 3 years ago
This is not correct since this would apply the fuze calibration values twice. But you may do whatever you find to produce good results.
On Fri, Mar 19, 2021 at 8:54 PM Chris Drane @.***> wrote:
In magcalMPU9250(), are the following lines:
dest1[0] = (float) mag_bias[0]*mRes*magCalibration[0]; // save mag biases in G for main program dest1[1] = (float) mag_bias[1]*mRes*magCalibration[1]; dest1[2] = (float) mag_bias[2]*mRes*magCalibration[2]; // Get soft iron correction estimate mag_scale[0] = (mag_max[0] - mag_min[0])/2; // get average x axis max chord length in counts mag_scale[1] = (mag_max[1] - mag_min[1])/2; // get average y axis max chord length in counts mag_scale[2] = (mag_max[2] - mag_min[2])/2; // get average z axis max chord length in counts float avg_rad = mag_scale[0] + mag_scale[1] + mag_scale[2]; avg_rad /= 3.0; dest2[0] = avg_rad/((float)mag_scale[0]); dest2[1] = avg_rad/((float)mag_scale[1]); dest2[2] = avg_rad/((float)mag_scale[2]);
In order to be consistent, I believe the magCalibration values should also be used when calculating the mag_scale, so those three lines become:
mag_scale[0] = (mag_max[0] - mag_min[0])/2*magCalibration[0]; // get average x axis max chord length in counts mag_scale[1] = (mag_max[1] - mag_min[1])/2*magCalibration[1]; // get average y axis max chord length in counts mag_scale[2] = (mag_max[2] - mag_min[2])/2*magCalibration[2]; // get average z axis max chord length in counts
This then correctly accounts for the case when the magCalibration values differ. In the case of my MPU9250 device, the values are {1.19, 1.19, 1.14}, so they can be different.
— 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/456, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKUKLCSLFBRZNHHGHK3TEQMA5ANCNFSM4ZP7EYXA .
OK, above is not correct.
But I don't think this is right anyway since the point of the scaling is to equalize the response dynamic range for each axis. Including different axial response values (basically what the fuze ROM values are) defeats this purpose.
I suspect the difference is in the noise, at least for the MPU9250 though. Might be interesting to find a low-noise MPU9250 and test the sphericity of the response surface when the calibration is done both ways.
On Fri, Mar 19, 2021 at 10:09 PM Tlera Corporation @.***> wrote:
This is not correct since this would apply the fuze calibration values twice. But you may do whatever you find to produce good results.
On Fri, Mar 19, 2021 at 8:54 PM Chris Drane @.***> wrote:
In magcalMPU9250(), are the following lines:
dest1[0] = (float) mag_bias[0]*mRes*magCalibration[0]; // save mag biases in G for main program dest1[1] = (float) mag_bias[1]*mRes*magCalibration[1]; dest1[2] = (float) mag_bias[2]*mRes*magCalibration[2]; // Get soft iron correction estimate mag_scale[0] = (mag_max[0] - mag_min[0])/2; // get average x axis max chord length in counts mag_scale[1] = (mag_max[1] - mag_min[1])/2; // get average y axis max chord length in counts mag_scale[2] = (mag_max[2] - mag_min[2])/2; // get average z axis max chord length in counts float avg_rad = mag_scale[0] + mag_scale[1] + mag_scale[2]; avg_rad /= 3.0; dest2[0] = avg_rad/((float)mag_scale[0]); dest2[1] = avg_rad/((float)mag_scale[1]); dest2[2] = avg_rad/((float)mag_scale[2]);
In order to be consistent, I believe the magCalibration values should also be used when calculating the mag_scale, so those three lines become:
mag_scale[0] = (mag_max[0] - mag_min[0])/2*magCalibration[0]; // get average x axis max chord length in counts mag_scale[1] = (mag_max[1] - mag_min[1])/2*magCalibration[1]; // get average y axis max chord length in counts mag_scale[2] = (mag_max[2] - mag_min[2])/2*magCalibration[2]; // get average z axis max chord length in counts
This then correctly accounts for the case when the magCalibration values differ. In the case of my MPU9250 device, the values are {1.19, 1.19, 1.14}, so they can be different.
— 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/456, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKUKLCSLFBRZNHHGHK3TEQMA5ANCNFSM4ZP7EYXA .
Thank you for your prompt reply.
My very limited understanding is that when you do
mx = (float)magCount[0]*mRes*magCalibration[0] - magBias[0]
you are a adjusting the count with the fuse value because different axes can have different sensitivities.
So my suggestion of
mag_scale[0] = (mag_max[0] - mag_min[0])/2*magCalibration[0]
is just adjusting the count for the sensitivity in the same way. I would suggest if you do not do this, then the operation of
avg_rad/((float)mag_scale[0]
is not taking into account the differing sensitivities when calculating the scaling? In other words, only by using the fuse values can you see the true differences in dynamic range?
I think this is right, it is more consistent to use the fuse ROM value in the scale calculation.
But it defeats the purpose I think.
So best practice is probably to ignore the fuse ROM everywhere, since the scale operation accounts for different axes sensitivity, which is what the fuse ROM values are supposed to represent. This preserves consistency and improves efficiency.
On Sat, Mar 20, 2021 at 12:06 AM Chris Drane @.***> wrote:
Thank you for your prompt reply.
My very limited understanding is that when you do mx = (float)magCount[0]mResmagCalibration[0] - magBias[0] you are a adjusting the count with the fuse value because different axes can have different sensitivities.
So my suggestion of mag_scale[0] = (mag_max[0] - mag_min[0])/2*magCalibration[0] is just adjusting the count for the sensitivity in the same way. I would suggest if you do not do this, then the operation of avg_rad/((float)mag_scale[0] is not taking into account the differing sensitivities when calculating the scaling? In other words, only by using the fuse values can you see the true differences in dynamic range?
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/456#issuecomment-803263550, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKT6SJ6ONUE5DK7WL23TERCOTANCNFSM4ZP7EYXA .
I agree. Assuming you can do an accurate soft iron calibration, then the fuse values can be ignored, because the soft iron calibration will measure the combined effect of both. This would also simplify the code, which is always a good thing.
I note that If someone was just doing a hard iron calibration, then it might be useful to use the fuse values.
The reason I was looking at your code in detail is that I am working through Hideataki's MPU9250 library, which is encapsulates your code into a modular format. In doing so, I have found a number of issues. When I have finished the analysis, I plan to do a pull request to the library to fix the issues. I will add an issue concerning our discussion here, and will include removing the fuse values in my pull request.
Are then any other MPU9250 libraries I should be looking at?
Not sure why you are bothering at all, the MPU9250 has been out of production for more than a year now and there are better oavailable anyway. True, there are a lot of MPU9250 breakout boards around, but I am not sure a deep dive into an MPU9250 will repay the effort.
But none of the libraries are complete, in that there are a lot of configuration variables and the use cases are different, etc.
For your own benefit, you should be aware of this https://github.com/kriswiner/MPU9250/tree/master/Dual_MPU9250. It uses the fact that the embedded MPU6500 accel/gyro can be master to the embedded AK8963C magnetometer such that two or more MPU9250 can be I2C slaves on the same host master I2C bus and there will be no ambiguity as to which mag is being addressed. This was a nice feature of the MPU9250 that was rarely implemented or implemented correctly.
On Sat, Mar 20, 2021 at 4:47 PM Chris Drane @.***> wrote:
I agree. Assuming you can do an accurate soft iron calibration, then the fuse values can be ignored, because the soft iron calibration will measure the combined effect of both. This would also simplify the code, which is always a good thing.
I note that If someone was just doing a hard iron calibration, then it might be useful to use the fuse values.
The reason I was looking at your code in detail is that I am working through Hideataki's MPU9250 library, which is encapsulates your code into a modular format. In doing so, I have found a number of issues https://github.com/hideakitai/MPU9250/issues. When I have finished the analysis, I plan to do a pull request to the library to fix the issues. I will add an issue concerning our discussion here, and will include removing the fuse values in my pull request.
Are then any other MPU9250 libraries I should be looking at?
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/456#issuecomment-803479710, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKRYR6UCZ3T4HCCDWLLTEUXY7ANCNFSM4ZP7EYXA .
Hi Kris,
Not sure why you are bothering at all, the MPU9250 has been out of production for more than a year now and there are better oavailable anyway...
While we're on this subject, may I ask? Which currently available IMU solutions would you recommend for 9-DoF AHRS sensor fusion for new designs? Are there any good ones that are similar in design to the MPU9250, i.e., all three sensors in a single chip package? I've been eyeing the LSM9DS1, but it seems to be out of stock everywhere..
LSM6DS1 is obsolete.
You can try ICM20948, but this is a split rail design, so you will need 3V3-to-1V8 logic level translation unless you run your MCU at 1V8. ICN20948 is as good or better than the MPU9250.
But best sensor suite is LSM6DSM + MMC5983A.
On Sun, Mar 21, 2021 at 3:33 PM Basil @.***> wrote:
Hi Kris,
Not sure why you are bothering at all, the MPU9250 has been out of production for more than a year now and there are better oavailable anyway...
While we're on this subject, may I ask? Which currently available IMU solutions would you recommend for 9-DoF AHRS sensor fusion for new designs? Are there any good ones that are similar in design to the MPU9250, i.e., all three sensors in a single chip package? I've been eyeing the LSM9DS1, but it seems to be out of stock everywhere..
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/456#issuecomment-803671704, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKVV7CXJMT3SQKH6ZDDTEZX2PANCNFSM4ZP7EYXA .
I will keep in mind your sketch for two MPU9250s.
Is there a decent open source library for the ICM20948?
Your approach to calibration appears to be novel, and so I am considering doing a mathematical analysis of it, or has someone already done this?
Most people use TDK's code for the ICM20948. I have never used the sensor.
On Sun, Mar 21, 2021 at 4:27 PM Chris Drane @.***> wrote:
I will keep in mind your sketch for two MPU9250s.
Is there a decent open source library for the ICM20948?
Your approach to calibration appears to be novel, and so I am considering doing a mathematical analysis of it, or has someone already done this?
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/456#issuecomment-803679545, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKV4XZVLT5ZMH32PFTLTEZ6ERANCNFSM4ZP7EYXA .
I have done a first cut of my mathematical analysis, which currently indicates the fuse values are useful even if calibrating. My first cut is often wrong, but I hope to have something for you to inspect in a week or two.
Looking forward to seeing your results. Thanks.
On Thu, Mar 25, 2021 at 12:06 AM Chris Drane @.***> wrote:
I have done a first cut of my mathematical analysis, which currently indicates the fuse values are useful even if calibrating. My first cut is often wrong, but I hope to have something for you to inspect in a week or two.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/456#issuecomment-806416271, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKREU6Q3PIG6FDSSRULTFLOIXANCNFSM4ZP7EYXA .
I have written a technical note that describes a mathematical analysis of the calibration algorithm. The paper has not been refereed so comments are especially welcome.
The paper considers the fuse values and demonstrates that the magnetometer can be calibrated without knowledge of these values. This means that if the person doing the calibration is not confident that the fuse values are correct, then the values should be ignored, and the fuse values should not be applied to any subsequent measurements. In the context of this repository, it would mean removing any use of the fuse values or setting them all to one.
If the person doing the calibration is confident that that fuse values are correct, then they should be applied to every measurement. In the context of this repository it would mean implementing changes along the lines suggested in the opening post of this issue.
In the case of the MPU-9250, it seems that the MPU-9250 has been out of production for a year, so all MPU-9250 units are at least one year old. Given this, without assurances from the manufacturer, I would not be confident in the fuse values and so would lean to ignoring them.
The technical note also describes a simplistic error analysis of the calibration algorithm. It finds that if a Figure 8 maneuver is used for the calibration, it will at best produce estimates that are only slightly more accurate that the MPU-9250's magnetic field measurement error. Given the magnetic field measurements will be integrated in the quaternion filter (so improving the signal to noise ratio), this means that the calibration error could significantly degrade the angular accuracy. As well, it is found that the Figure 8 maneuver can introduce sampling errors whereby the actual maximum or minimum values are missed. The combination of sampling errors and measurement errors make the calibration difficult to perform in a repeatable fashion, i.e. each calibration could give significantly different results.
A careful operator could obtain repeatable results, especially if scatter plots of the response surface are used, as described by in this post by Kris Winers. However even a careful approach will still result in calibration errors that are only slightly better than the measurement errors.
My technical note suggests a calibration maneuver that should result in a much more accurate and repeatable calibration. The suggestion would only make three small changes to the calibration algorithm:
The main change is to use a different maneuver to the Figure 8. The recommended maneuver is a manual gradient ascent/descent to find the minima and maxima, guided by the print out of the averaged x,y, z field measurements. The procedure assumes the operator has a compass that is able to indicate the direction of Magentic North. Once the direction of North is known, then the operator knows that local magnetic vector points in that direction but is tilted upwards or downward depending on whether they located in the Northern or Southern hemisphere. The idea of the algorithm is align and anti-align the x-axis with the magnetic vector, and then do the same for the y-axis and the z-axis. The instructions are as follows:
This does somewhat increase the complexity of the calibration, but should provide a more accurate and repeatable outcome.
Here is the technical note.
Hi Chris,
Thank you for the detailed analysis. I haven't read the paper yet (this weekend) but based on your synopsis I have a few comments.
As mentioned before, I agree that the AK8963 fuse data needs to be treated consistently, that is, consistently applied to all mag data determinations or ignored in the same. So this is an error in the original sketches. It also partly explains why I was never satisfied with the results of applying axes scaling.
As for the mag calibrating motion, well, "figure eight" is meant as a shorthand for "move the magnetometer in 3D space such that every point on the response surface is sampled multiple times". You would be surprised by how many people interpret the last sentence as "put the sensor on the table and spin it around"
In fact, the best open-source mag calibration method is that originally from (Motorola) Freescale https://www.nxp.com/docs/en/application-note/AN4246.pdf which models the response surface as an ellipsoid and by a similar tumbling to sample all points on the response surface calculates the needed corrections to bring the response surface back to a sphere centered on the origin, which is the goal of all mag calibrations.
In our implementation of this calibration method, during the calibration we output some measures of "non-sphericity" and response surface coverage as well as have some criteria to be sure the points going into the calculation are sufficiently uniform and not bunched up in small areas, etc. This feedback aids the tumbling motion and ensures efficient calibration to within a user-set criterion. This sort of soft iron corrector is practical and can be quite accurate.
Also, we have found that the time and tumbling motion ("figure eighting") required is a function of the calibration environment (magnetically noisy?) as well as the specifics of the deviation of the magnetometer from sphericity. Some really bent mags cannot be well calibrated no matter what one does.
Lastly, while I appreciate your attempt to investigate and regularize magnetic calibration, this remains part art as well as science and here is no fool-proof recipe that works for all cases and all comers.
Greg Tomasch is the expert on this topic so I invite his participation for further discussion.
Kris
On Tue, Apr 13, 2021 at 12:47 AM Chris Drane @.***> wrote:
calibration.pdf https://github.com/kriswiner/MPU9250/files/6302044/calibration.pdf
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/456#issuecomment-818522797, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKV6LPSWK7LYCK6B6YLTIPZKPANCNFSM4ZP7EYXA .
I believe you when you state there is no fool proof recipe. I thought your algorithm interesting, so my major motivations were understanding it better and to understand the fuse issue.
It sounds like we have converged on the fuse issue.
I would be most interested if anyone can suggest a paper that derives the soft iron ellipsoid response surface and identifies the assumptions involved, and when those assumptions are violated.
I look forward to your comments on the paper.
Chris
I linked to such a paper, did I not?
On Tue, Apr 13, 2021 at 4:07 PM Chris Drane @.***> wrote:
I believe you when you state there is no fool proof recipe. I thought your algorithm interesting, so my major motivations was understanding it better and to understand the fuse issue. It sounds like we have converged on the fuse issue. I would be most interested if anyone can suggest a paper that derives the soft iron ellipsoid response surface and identifies the assumptions involved.
I look forward to your comments on the paper.
Chris
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/456#issuecomment-819108076, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKVCBPT6KPDJOB4RJ7DTITFEZANCNFSM4ZP7EYXA .
The paper looks useful, but just states that the soft iron causes a linear/affine transformation, except in the case where there is hysteresis. I am after an earlier paper or book that derives the linear transformation.
Here is an updated version of the paper that calculates the process gain for the estimators, so making it easier to compare different approaches. calibration.pdf
In
magcalMPU9250()
, are the following lines:In order to be consistent, I believe the magCalibration values should also be used when calculating the mag_scale, so those three lines become:
This then correctly accounts for the case when the magCalibration values differ. In the case of my MPU9250 device, the values are {1.19, 1.19, 1.14}, so they can be different.