AnsweredAssumed Answered

Inertial Sensor - How to correctly use Motion librarys

Question asked by Jonattan Carvalho on Feb 23, 2018
Latest reply on Feb 27, 2018 by Miroslav B

Hello.

 

I am trying to build a full motion sensor software. I am using the NUCLEO-F411RE with STM32F411RE, SW4STM IDE, LSM9DS1 sensor with gyroscope, accelerometer and magnetometer. For this, I implemented the X-CUBE-MEMS1 library with MotionAC, MotionGC and MotionMC for sensor calibration.

 

I performed the gyroscope calibration successfully, but I could not calibrate the accelerometer and magnetometer. The MotionMC library never gives me results. The MotionAC gives me results sometimes, but only in "Dynamic Calibration" mode and they are not very accurate. I am doing circular motions trying to cover to the maximum all the points with all the axes.

 

Defines:

#define ADJUST_ACC_MG          0.061f //2range:0.061mg/LSB   //VALUES FROM DATASHEET
#define ADJUST_ACC_G             0.000061f //2range:0.000061g/LSB
#define ADJUST_GYR_MDPS      8.75f //245range:8.75mdps/LSB
#define ADJUST_GYR_DPS          0.00875f //245range:0.00875dps/LSB
#define ADJUST_MAG_MGAUSS    0.14f //4range:0.14mgauss/LSB
#define ADJUST_MAG_UT             0.014f //4range:0.014uT/LSB

#define REPORT_INTERVAL 10
#define SAMPLE_FREQUENCY_F 100.0f

Variables:

SensorAxes_t ACC_Brute; // Data from sensor

SensorAxes_t GYR_Brute; // Data from sensor
SensorAxes_t MAG_Brute; // Data from sensor
SensorAxesFloat_t ACC_Cal; // Calibrated data
SensorAxesFloat_t GYR_Cal; // Calibrated data
SensorAxesFloat_t MAG_Cal; // Calibrated data

uint32_t CounterStamp;

//MotionAC
MAC_input_t MAC_Input_Brute;
MAC_output_t MAC_Params;

 

//MotionMC
MMC_Input_t MMC_Input_Brute;
MMC_Output_t MMC_Params;

Initialization:

void Motion_Lib_Init()
{

//MotionAC
#define MOVE_THR_G 0.3f // Recommended between 0.15 - 0.30 g, higher value will relax condition but reduce the accuracy (moveThresh_g / 10)
MAC_calibration_mode_t CalibrationMode = DYNAMIC_CALIBRATION; // DYNAMIC_CALIBRATION or SIX_POINT_CALIBRATION
MAC_knobs_t KnobsAC;
MotionAC_Initialize(MAC_ENABLE_LIB);
MotionAC_GetKnobs(&KnobsAC);
KnobsAC.MoveThresh_g = MOVE_THR_G;
KnobsAC.Run6PointCal = (uint8_t) CalibrationMode;
KnobsAC.Sample_ms = REPORT_INTERVAL;
MotionAC_SetKnobs(&KnobsAC);

//MotionMC
MotionMC_Initialize(REPORT_INTERVAL, 1);
}

 

Called by timer every 10ms:

CounterStamp++;

 

//MotionAC

uint8_t is_calibrated = 0;
MAC_Input_Brute.TimeStamp = CounterStamp * REPORT_INTERVAL;
MAC_Input_Brute.Acc[0] = ACC_Brute.AXIS_X * ADJUST_ACC_G;
MAC_Input_Brute.Acc[1] = ACC_Brute.AXIS_Y * ADJUST_ACC_G;
MAC_Input_Brute.Acc[2] = ACC_Brute.AXIS_Z * ADJUST_ACC_G;
MotionAC_Update(&MAC_Input_Brute, &is_calibrated);
MotionAC_GetCalParams(&MAC_Params);
ACC_Cal.X = (MAC_Input_Brute.Acc[0] - MAC_Params.AccBias[0]) * MAC_Params.SF_Matrix[0][0];
ACC_Cal.Y = (MAC_Input_Brute.Acc[1] - MAC_Params.AccBias[1]) * MAC_Params.SF_Matrix[1][1];
ACC_Cal.Z = (MAC_Input_Brute.Acc[2] - MAC_Params.AccBias[2]) * MAC_Params.SF_Matrix[2][2];

 

//MotionMC

MMC_Input_Brute.TimeStamp = CounterStamp * REPORT_INTERVAL;
MMC_Input_Brute.Mag[0] = (float)MAG_Brute.AXIS_X * ADJUST_MAG_UT;
MMC_Input_Brute.Mag[1] = (float)MAG_Brute.AXIS_Y * ADJUST_MAG_UT;
MMC_Input_Brute.Mag[2] = (float)MAG_Brute.AXIS_Z * ADJUST_MAG_UT;
MotionMC_Update(&MMC_Input_Brute);
MotionMC_GetCalParams(&MMC_Params);

MAG_Cal.X = ((MMC_Input_Brute.Mag[0] - MMC_Params.HI_Bias[0]) * MMC_Params.SF_Matrix[0][0])
+ ((MMC_Input_Brute.Mag[1] - MMC_Params.HI_Bias[1]) * MMC_Params.SF_Matrix[0][1])
+ ((MMC_Input_Brute.Mag[2] - MMC_Params.HI_Bias[2]) * MMC_Params.SF_Matrix[0][2]);
MAG_Cal.Y = ((MMC_Input_Brute.Mag[0] - MMC_Params.HI_Bias[0]) * MMC_Params.SF_Matrix[1][0])
+ ((MMC_Input_Brute.Mag[1] - MMC_Params.HI_Bias[1]) * MMC_Params.SF_Matrix[1][1])
+ ((MMC_Input_Brute.Mag[2] - MMC_Params.HI_Bias[2]) * MMC_Params.SF_Matrix[1][2]);
MAG_Cal.Z = ((MMC_Input_Brute.Mag[0] - MMC_Params.HI_Bias[0]) * MMC_Params.SF_Matrix[2][0])
+ ((MMC_Input_Brute.Mag[1] - MMC_Params.HI_Bias[1]) * MMC_Params.SF_Matrix[2][1])
+ ((MMC_Input_Brute.Mag[2] - MMC_Params.HI_Bias[2]) * MMC_Params.SF_Matrix[2][2]);

}

 

What is necessary to perform this calibration? I plan to implement MotionTL, MotionEC and MotionFX too.

 

Kind regards,

Jonattan

Outcomes