IMU学名惯性测量单元,所有的运动都可以分解为一个直线运动和一个旋转运动,故这个惯性测量单元就是测量这两种运动,直线运动通过加速度计可以测量,旋转运动则通过陀螺。

void IMUupdate(float gx, float gy, float gz, float ax,float ay, float az)
{
    float norm;
    float vx, vy, vz;
    float ex, ey, ez;

    float q0q0 = q0*q0;
    float q0q1 = q0*q1;
    float q0q2 = q0*q2;
    float q1q1 = q1*q1;
    float q1q3 = q1*q3;
    float q2q2 = q2*q2;
    float q2q3 = q2*q3;
    float q3q3 = q3*q3;

    if(ax*ay*az==0)
        return;

    // 第一步:对加速度数据进行归一化
    norm = sqrt(ax*ax + ay*ay + az*az);
    ax = ax / norm;
    ay = ay / norm;
    az = az / norm;



    // 第二步:DCM矩阵旋转

    vx = 2*(q1q3 - q0q2);
    vy = 2*(q0q1 + q2q3);
    vz = q0q0 - q1q1 - q2q2 + q3q3 ;


    // 第三步:在机体坐标系下做向量叉积得到补偿数据

    ex = ay*vz - az*vy ;
    ey = az*vx - ax*vz ;
    ez = ax*vy - ay*vx ;


    // 第四步:对误差进行PI计算,补偿角速度
    exInt = exInt + ex * Ki;
    eyInt = eyInt + ey * Ki;
    ezInt = ezInt + ez * Ki;

    gx = gx + Kp*ex + exInt;
    gy = gy + Kp*ey + eyInt;
    gz = gz + Kp*ez + ezInt;


    // 第五步:按照四元数微分公式进行四元数更新
    q0 = q0 + (-q1*gx - q2*gy - q3*gz)*halfT;
    q1 = q1 + (q0*gx + q2*gz - q3*gy)*halfT;
    q2 = q2 + (q0*gy - q1*gz + q3*gx)*halfT;
    q3 = q3 + (q0*gz + q1*gy - q2*gx)*halfT;

}

​​​​​​​1. 数据规范化

在使用一个算法之前首先要弄清楚数据数据的单位是什么,在互补滤波算法中,角速度的单位是“弧度每秒”,加速度是数据是归一化后的数据,无单位。

2. DCM旋转矩阵

通过旋转矩阵计算标准加速度在当前姿态下的理论加速度分量,其中旋转矩阵通过四元素得到。(四元数,欧拉角,和旋转矩阵之间可以相互转换)。

IMU 互补滤波-LMLPHP

3. 通过向量叉积得到误差

这个误差指的是两个向量的不平行程度,和夹角的正弦成正比,叉乘=a*b*sin(角度),二两个向量又归一化了,所以就和sin(角度成正比),进而反应了陀螺仪估计的姿态和加速度计测量的姿态误差。Mahony那篇论文用叉乘来表示误差是有其物理意义的。一般来说向量的误差不是用叉乘来表示,直接作减法会更合适。而单位向量的向量叉积在物理意义上在小角度意义就是轴角,轴角本身就刻画了旋转,也就是叉乘的结果可以看成是旋转误差,在这个物理意义下比任何误差表示都要合理和切合实际系统。

4. PID调节

5. 四元素微分公式

IMU 互补滤波-LMLPHP

利用PID补偿后的角速度对四元数进行更新。

07-02 17:49