Skip to main content
tkheang
Associate
Jul 6, 2021 10:34 PM UTC
Solved

MotionDI_update doesn't seem to be working

Hello,

I'm trying to use the MotionDI library for a dynamic inclinometer application. My IMU is the LSM9DS1. The returned data from MotionDI_update() is shown below:

0693W00000Bczh6QAB.pngThe values for rotation, quaternion, gravity, and linear acceleration never change, even when the IMU is moved. I initialized the MotionDI library according to the sample code in the documentation:

float freq = 100.0f;
MDI_knobs_t iKnobs;
MDI_knobs_t *ipKnobs = &iKnobs;
 
int main(void)
{
 HAL_Init();
 SystemClock_Config();
 MX_GPIO_Init();
 MX_USART2_UART_Init();
 MX_I2C1_Init();
 MX_CRC_Init();
 MX_NVIC_Init();
 
 MotionDI_Initialize(&freq);
 MotionDI_setKnobs(ipKnobs);
 
 while (1)
 {
 lsm9ds1_read_data_polling();
 }
}

The lsm9ds1_read_data_polling() function is from an LSM9DS1 driver sample code and handles the initialization and reading of data for the IMU. In that function's while loop I have the following:

while (1) {
 /* Read device status register */
 lsm9ds1_dev_status_get(&dev_ctx_mag, &dev_ctx_imu, &reg);
 
 if ( reg.status_imu.xlda && reg.status_imu.gda ) {
 /* Read imu data */
 memset(data_raw_acceleration, 0x00, 3 * sizeof(int16_t));
 memset(data_raw_angular_rate, 0x00, 3 * sizeof(int16_t));
 lsm9ds1_acceleration_raw_get(&dev_ctx_imu,data_raw_acceleration);
 lsm9ds1_angular_rate_raw_get(&dev_ctx_imu,data_raw_angular_rate);
 
 acceleration_mg[0] = lsm9ds1_from_fs2g_to_mg(data_raw_acceleration[0]);
 acceleration_mg[1] = lsm9ds1_from_fs2g_to_mg(data_raw_acceleration[1]);
 acceleration_mg[2] = lsm9ds1_from_fs2g_to_mg(data_raw_acceleration[2]);
 
 angular_rate_mdps[0] = lsm9ds1_from_fs2000dps_to_mdps(data_raw_angular_rate[0]);
 angular_rate_mdps[1] = lsm9ds1_from_fs2000dps_to_mdps(data_raw_angular_rate[1]);
 angular_rate_mdps[2] = lsm9ds1_from_fs2000dps_to_mdps(data_raw_angular_rate[2]);
 
 // Process MEMS data in MotionDI
 data_in.Acc[0] = acceleration_mg[0] / 1000;
 data_in.Acc[1] = acceleration_mg[1] / 1000;
 data_in.Acc[2] = acceleration_mg[2] / 1000;
 
 data_in.Gyro[0] = angular_rate_mdps[0] / 1000;
 data_in.Gyro[1] = angular_rate_mdps[1] / 1000;
 data_in.Gyro[2] = angular_rate_mdps[2] / 1000;
 
 data_in.Timestamp = HAL_GetTick() * 1000;
 
 MotionDI_update(&data_out, &data_in);
 
 sprintf((char *)tx_buffer, "Timestamp: %d us\r\n", data_in.Timestamp);
 tx_com(tx_buffer, strlen((char const *)tx_buffer));
 
 sprintf((char *)tx_buffer,
 "IMU (Raw) - [g]: %4.2f\t%4.2f\t%4.2f\t[dps]:%4.2f\t%4.2f\t%4.2f\r\n",
 data_in.Acc[0], data_in.Acc[1], data_in.Acc[2],
 data_in.Gyro[0], data_in.Gyro[1], data_in.Gyro[2]);
 tx_com(tx_buffer, strlen((char const *)tx_buffer));
 
 sprintf((char *)tx_buffer,
		"IMU (MotionDI) - [g]: %4.2f\t%4.2f\t%4.2f\t[dps]:%4.2f\t%4.2f\t%4.2f\r\n\n",
		data_out.linear_acceleration[0], data_out.linear_acceleration[1], 
 data_out.linear_acceleration[2],
	 data_out.rotation[0], data_out.rotation[1], data_out.rotation[2]);
 tx_com(tx_buffer, strlen((char const *)tx_buffer));
 }
 HAL_Delay(100);
}

Is there anything that could be the problem? Thanks.

This topic has been closed for replies.
Miroslav BATEKBest answer
ST Employee
Jul 26, 2021 8:25 AM UTC

OK, the data are OK. I'm able to get correct output values from MotionDI library using your data.

I checked you code and I see you call MotionDI_setKnobs(ipKnobs); function without settings the knobs parameters.

You can check application example in X_CUBE-MEMS1 package.

You should read the default knobs settings and the modify the only settings you need.

 MotionDI_getKnobs(ipKnobs);

 ipKnobs->AccKnob.CalType = MDI_CAL_CONTINUOUS;

 ipKnobs->GyrKnob.CalType = MDI_CAL_CONTINUOUS;

 BSP_SENSOR_ACC_GetOrientation(ipKnobs->AccOrientation);

 BSP_SENSOR_GYR_GetOrientation(ipKnobs->GyroOrientation);

 ipKnobs->SFKnob.output_type = MDI_ENGINE_OUTPUT_ENU;

 ipKnobs->SFKnob.modx = DECIMATION;

 MotionDI_setKnobs(ipKnobs);

8 replies

ST Employee
Jul 15, 2021 8:59 AM UTC

Hello,

can you please share datalog with accelerometer and gyroscope data which you pass to the library?

tkheang
tkheangAuthor
Associate
Jul 15, 2021 7:33 PM UTC

Hi Miroslav,

By datalog do you mean the output on the serial monitor? If so here it is, with the IMU tilted 45 degrees:

0693W00000CzkRrQAJ.png

ST Employee
Jul 16, 2021 7:17 AM UTC

By datalog, I mean text file (ideally csv) in which you record like 30 seconds of the accelerometer and gyroscope data which you pass to the library.

tkheang
tkheangAuthor
Associate
Jul 16, 2021 8:48 PM UTC

Here is the datalog. Each row has data_in.Timestamp, data_in.Acc[0], data_in.Acc[1], data_in.Acc[2], data_in.Gyro[0], data_in.Gyro[1], data_in.Gyro[2] in that order. The IMU is laid flat on a vibrating surface with the Z axis pointing up.

ST Employee
Jul 19, 2021 8:06 AM UTC

Thank you for the datalog, the data from accelerometer and gyroscope looks good, but your update data rate is low. I see the update data period is about 115ms.

Can you please update your code to increase the speed so the period is ideally 10ms.

tkheang
tkheangAuthor
Associate
Jul 22, 2021 8:01 PM UTC

I increased the speed to 10ms but the output still hasn't changed. I've attached another datalog, this time with the outputs in addition to the inputs. Each row is data_in.Timestamp, data_in.Acc[0], data_in.Acc[1], data_in.Acc[2], data_in.Gyro[0], data_in.Gyro[1], data_in.Gyro[2], data_out.linear_acceleration[0], data_out.linear_acceleration[1], data_out.linear_acceleration[2], data_out.rotation[0], data_out.rotation[1], data_out.rotation[2].

Miroslav BATEKBest answer
ST Employee
Jul 26, 2021 8:25 AM UTC

OK, the data are OK. I'm able to get correct output values from MotionDI library using your data.

I checked you code and I see you call MotionDI_setKnobs(ipKnobs); function without settings the knobs parameters.

You can check application example in X_CUBE-MEMS1 package.

You should read the default knobs settings and the modify the only settings you need.

 MotionDI_getKnobs(ipKnobs);

 ipKnobs->AccKnob.CalType = MDI_CAL_CONTINUOUS;

 ipKnobs->GyrKnob.CalType = MDI_CAL_CONTINUOUS;

 BSP_SENSOR_ACC_GetOrientation(ipKnobs->AccOrientation);

 BSP_SENSOR_GYR_GetOrientation(ipKnobs->GyroOrientation);

 ipKnobs->SFKnob.output_type = MDI_ENGINE_OUTPUT_ENU;

 ipKnobs->SFKnob.modx = DECIMATION;

 MotionDI_setKnobs(ipKnobs);