代码中的 sampleFreq 即执行姿态解算的频率,这里用定时器,以500HZ的频率调用get_angle();
- void MahonyAHRSupdateIMU(float gx, float gy, float gz, float ax, float ay, float az) {
- float recipNorm;
- float halfvx, halfvy, halfvz; //1/2 重力分量
- float halfex, halfey, halfez; //1/2 重力误差
- float qa, qb, qc;
- //对加速度数据归一化
- recipNorm = invSqrt(ax * ax + ay * ay + az * az);
- ax *= recipNorm;
- ay *= recipNorm;
- az *= recipNorm;
- // 由四元数计算重力分量
- halfvx = q1 * q3 - q0 * q2;
- halfvy = q0 * q1 + q2 * q3;
- halfvz = q0 * q0 - 0.5f + q3 * q3;
- // 将四元数重力分量 与 加速度计重力分量 作叉积 得到误差
- halfex = (ay * halfvz - az * halfvy);
- halfey = (az * halfvx - ax * halfvz);
- halfez = (ax * halfvy - ay * halfvx);
- //对误差作积分
- integralFBx += twoKi * halfex * (1.0f / sampleFreq);
- integralFBy += twoKi * halfey * (1.0f / sampleFreq);
- integralFBz += twoKi * halfez * (1.0f / sampleFreq);
- //反馈到角速度
- gx += integralFBx; gy += integralFBy; gz += integralFBz;
- // 对误差作比例运算并反馈
- gx += twoKp * halfex; gy += twoKp * halfey; gz += twoKp * halfez;
- // 计算1/2 dt
- gx *= (0.5f * (1.0f / sampleFreq));
- gy *= (0.5f * (1.0f / sampleFreq));
- gz *= (0.5f * (1.0f / sampleFreq));
- qa = q0; qb = q1; qc = q2;
- // 更新四元数
- q0 += (-qb * gx - qc * gy - q3 * gz);
- q1 += (qa * gx + qc * gz - q3 * gy);
- q2 += (qa * gy - qb * gz + q3 * gx);
- q3 += (qa * gz + qb * gy - qc * gx);
- // 四元数归一化
- recipNorm = invSqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);
- q0 *= recipNorm; q1 *= recipNorm; q2 *= recipNorm; q3 *= recipNorm;
- }
|