MarkSherstan / MPU-6050-9250-I2C-CompFilter

MPU6050/9250 I2C and SPI interface. Sensor fusion using a complementary filter yields sensor Euler angles and is implemented in five different languages.
GNU General Public License v3.0
94 stars 24 forks source link

bias applied incorrectly in magCalSlider and magCalVisualizer #15

Open WillemD61 opened 2 years ago

WillemD61 commented 2 years ago

In the main program magnetometer calibration routine the RAW magnetometer values are captured and the bias and scale factors are calculated. The instructions say that the RAW values should be stored in data.txt and the bias and scale factor should then be defined in the two visualization programs. These will then display raw and corrected graphs.

In the main program : bias = RAWbias scaleFactor factorycalibration and scale=avgrange/axis-range (where RAWbias=(maxRAW+minRAW)/2)

In the visualization programs however you are applying the bias to the RAW magnetometer values (retrieved from data.txt) So you are subtracting a bias that is alread corrected with scalefactor and factorycalibration values from a RAW magnetometer value. I think you should either subtract a raw bias from raw values or corrected bias from corrected values.

Also note that the scalefactor is calculated from RAW values but applied on corrected values. Since these are close to 1 anyway the impact is small.

That is why currently the magCalSlider each time requires further manual adjustment.

(notes : 1) in the explanation of calibration by Kris Winer and the example routine he provides, you can see the variables mag_bias[ ] and dest1[ ] for the raw and corrected values respectively. 2) also note that you bias correction in the main program (in the processvalues function) is correct. The error only exists in the visualization programs magCalSlider and magCalVisualizer

MarkSherstan commented 2 years ago

If I understand correctly, the mag calibration routine must also return: magScaleFactor and magXcal magYcal magZcal so that I can mimic the below logic?

self.mx = self.mx * self.magScaleFactor * self.magXcal - self.magXbias
self.my = self.my * self.magScaleFactor * self.magYcal - self.magYbias
self.mz = self.mz * self.magScaleFactor * self.magZcal - self.magZbias

self.mx *= self.magXscale
self.my *= self.magYscale
self.mz *= self.magZscale

As the current implementation in magCalSlider.py and magCalVisualizer.py is limited to:

self.mx -= self.magXbias
self.my -= self.magYbias
self.mz -= self.magZbias

self.mx *= self.magXscale
self.my *= self.magYscale
self.mz *= self.magZscale
WillemD61 commented 2 years ago

The current calibration routine calculates the bias and scale as follows:

    self.magXbias = ((magMax[0] + magMin[0])/2) * self.magScaleFactor * self.magXcal
    self.magYbias = ((magMax[1] + magMin[1])/2) * self.magScaleFactor * self.magYcal
    self.magZbias = ((magMax[2] + magMin[2])/2) * self.magScaleFactor * self.magZcal

    # Get soft iron correction estimate
    magXchord = (magMax[0] - magMin[0])/2
    magYchord = (magMax[1] - magMin[1])/2
    magZchord = (magMax[2] - magMin[2])/2

    avgChord = (magXchord + magYchord + magZchord)/3

    self.magXscale = avgChord/magXchord
    self.magYscale = avgChord/magYchord
    self.magZscale = avgChord/magZchord

so this bias is already scaled for the sensor range and corrected with the factory stored calibration values. It can be directly used in the program

self.mx = self.mx * self.magScaleFactor * self.magXcal - self.magXbias
self.my = self.my * self.magScaleFactor * self.magYcal - self.magYbias
self.mz = self.mz * self.magScaleFactor * self.magZcal - self.magZbias

However, it cannot be used in the current for of magCalSlider or magCalVisualizer since in those programs it is used as

self.mx -= self.magXbias
self.my -= self.magYbias
self.mz -= self.magZbias

So a scaled and calibrated bias is subtracted from a raw (unscaled and uncalibrated) measurement. In making this calculation and displaying the result, you will see that the circles/blobs are never centered around (0,0,0) and always require further manual adjustment because the bias is just too large.

In the visulation program you can 1) first convert raw values by multiplication with scale factor and factory calibration and only thereafter subtract the bias and make the display 2) or make sure that the calibration routine also outputs the raw bias (next to the scaled bias) and use that raw bias in the current visulation routines, so neither the raw value nor the bias is scaled during visualisation. If you choose this option, then after finalisation of these visualisation routines, you still need to make sure that the final bias output is scaled and directly usable in the main program.

MarkSherstan commented 1 year ago

Sorry I have been very busy; if you still require this fix I recommend you make a PR.