2021-07-06 03:34 PM
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:
The 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, ®);
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.
Solved! Go to Solution.
2021-07-26 01:25 AM
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);
2021-07-15 01:59 AM
Hello,
can you please share datalog with accelerometer and gyroscope data which you pass to the library?
2021-07-15 12:33 PM
Hi Miroslav,
By datalog do you mean the output on the serial monitor? If so here it is, with the IMU tilted 45 degrees:
2021-07-16 12:17 AM
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.
2021-07-16 01:48 PM
2021-07-19 01:06 AM
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.
2021-07-22 01:01 PM
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].
2021-07-26 01:25 AM
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);
2021-08-02 11:51 AM
After setting the knobs parameters, the MotionDI library works. Thank you!