大疆开发型c板BMI088-IMU零漂问题优化解决(1)

在基于clion开发大疆开发型c板STM32F407IG过程中出现的零点漂移严重情况的解决

1.首先我们先了解一下IMU零漂

校准IMU数据的目的是消除传感器本身固有的偏差和不确定性,使得测量数据更加准确和可靠。在这个函数中,校准过程主要是通过乘以比例因子和加上偏移量来实现的,具体步骤如下:首先需要进行传感器的零偏校准(offset calibration)。这一步骤的目的是测量出传感器在静止状态下的输出,以便消除偏差。在实际应用中,可以将传感器放置在静止的水平面上,记录下此时的输出值,然后将这些输出值的平均值作为传感器的零偏。

在大疆开发型c板的代码中,传感器的零偏值存储在gyro_offsetaccel_offsetmag_offset这三个数组中,分别对应陀螺仪、加速度计和磁力计。

/**
  * @brief          计算陀螺仪零漂
  * @param[out]     gyro_offset:计算零漂
  * @param[in]      gyro:角速度数据
  * @param[out]     offset_time_count: 自动加1
  * @retval         无
  */
void gyro_offset_calc(fp32 gyro_offset[3], fp32 gyro[3], uint16_t *offset_time_count)
{
    if (gyro_offset == NULL || gyro == NULL || offset_time_count == NULL)
        return;

    gyro_offset[0] = gyro_offset[0] - 0.0003f * gyro[0];
    gyro_offset[1] = gyro_offset[1] - 0.0003f * gyro[1];
    gyro_offset[2] = gyro_offset[2] - 0.0003f * gyro[2];

    (*offset_time_count)++;
}
/**
  * @brief          校准陀螺仪
  * @param[out]     陀螺仪的比例因子,1.0f为默认值,不修改
  * @param[out]     陀螺仪的零漂,采集陀螺仪的静止的输出作为offset
  * @param[out]     陀螺仪的时刻,每次在gyro_offset调用会加1,
  * @retval         无
  */
void INS_cali_gyro(fp32 cali_scale[3], fp32 cali_offset[3], uint16_t *time_count)
{
    if( *time_count == 0)
    {
        gyro_offset[0] = gyro_cali_offset[0];
        gyro_offset[1] = gyro_cali_offset[1];
        gyro_offset[2] = gyro_cali_offset[2];
    }
    gyro_offset_calc(gyro_offset, INS_gyro, time_count);

    cali_offset[0] = gyro_offset[0];
    cali_offset[1] = gyro_offset[1];
    cali_offset[2] = gyro_offset[2];
    cali_scale[0] = 1.0f;
    cali_scale[1] = 1.0f;
    cali_scale[2] = 1.0f;
}

2.接下来需要进行传感器的比例因子校准(scale factor calibration)。这一步骤的目的是测量出传感器的输出与实际值之间的比例关系,以便消除比例误差。在实际应用中,可以使用标准的参考值(例如重力加速度、磁场强度等)来测量传感器的输出,并根据这些数据计算出比例因子。

在代码中,传感器的比例因子存储在gyro_scale_factoraccel_scale_factormag_scale_factor这三个二维数组中,其中每行对应传感器的一个轴,每列对应比例因子。将计算出的偏移量和比例因子应用到原始传感器数据上,得到校准后的数据。具体地,对于每个传感器的每个轴,将原始数据乘以相应的比例因子,再加上相应的偏移量,即可得到校准后的数据。

/**
  * @brief          旋转陀螺仪,加速度计和磁力计,并计算零漂,因为设备有不同安装方式
  * @param[out]     gyro: 加上零漂和旋转
  * @param[out]     accel: 加上零漂和旋转
  * @param[out]     mag: 加上零漂和旋转
  * @param[in]      bmi088: 陀螺仪和加速度计数据
  * @param[in]      ist8310: 磁力计数据
  * @retval         无
  */
static void imu_cali_slove(fp32 gyro[3], fp32 accel[3], fp32 mag[3], bmi088_real_data_t *bmi088, ist8310_real_data_t *ist8310)
{
    for (uint8_t i = 0; i < 3; i++)
    {
        gyro[i] = bmi088->gyro[0] * gyro_scale_factor[i][0] + bmi088->gyro[1] * gyro_scale_factor[i][1] + bmi088->gyro[2] * gyro_scale_factor[i][2] + gyro_offset[i];
        accel[i] = bmi088->accel[0] * accel_scale_factor[i][0] + bmi088->accel[1] * accel_scale_factor[i][1] + bmi088->accel[2] * accel_scale_factor[i][2] + accel_offset[i];
        mag[i] = ist8310->mag[0] * mag_scale_factor[i][0] + ist8310->mag[1] * mag_scale_factor[i][1] + ist8310->mag[2] * mag_scale_factor[i][2] + mag_offset[i];
    }
}

在代码中,这一步骤通过循环遍历每个数组元素来实现。对于陀螺仪、加速度计和磁力计的每个轴,分别使用对应的比例因子和偏移量对原始数据进行校准,并将结果存储在对应的输出数组中。

综上,这个函数通过零偏校准和比例因子校准来消除传感器的偏差和比例误差,从而得到更加准确和可靠的IMU数据。

传感器的三个轴指的是传感器所处的三个空间维度的方向,通常包括X、Y、Z三个轴。具体地,对于陀螺仪、加速度计和磁力计等惯性传感器,三个轴的定义通常如下:

  • X轴:指向传感器的右侧(正方向);
  • Y轴:指向传感器的前方(正方向);
  • Z轴:指向传感器的顶部(正方向)。

需要注意的是,不同的传感器可能存在一定的轴向约定,因此具体定义需要参考传感器的数据手册或者文档。同时,由于IMU系统通常包含多个传感器,每个传感器的轴向可能不同,因此在进行数据融合时需要进行坐标系变换,使得所有传感器的数据处于同一个坐标系下。

此时的imu零漂非常严重,每秒有近0.001的零漂

imu

此时的imu使用起来精度非常低,大疆官方给了我们一个解决办法:

大疆开发型c板BMI088-IMU零漂问题优化解决(1)_第1张图片

这一章在大疆的开发型C板嵌入式软件教程文档中有提及:

 等有时间了写一下(2)calibrate_task的任务,主要是给自己一个提醒,自己理一理思路

 
  

你可能感兴趣的:(单片机,stm32,嵌入式硬件)