四元数在无人机姿态解算中的实战应用:从理论到代码实现
·
四元数在无人机姿态解算中的实战应用:从理论到代码实现
当你的无人机在强风中突然倾斜30度时,飞控系统如何在0.01秒内完成姿态修正?这个看似神奇的过程,核心秘密就藏在四元数这个数学工具里。不同于传统欧拉角会遇到的"万向节死锁"问题,四元数通过四个维度的数值就能完整描述三维空间中的任意旋转,这正是现代无人机飞控的首选方案。
1. 四元数基础与无人机姿态的数学表达
四元数由数学家哈密顿在1843年提出,形式上可以记作Q = q0 + q1i + q2j + q3*k。对于无人机应用,我们通常使用单位四元数(满足q0²+q1²+q2²+q3²=1),其中:
- 实部q0表示旋转角度
- 虚部(q1,q2,q3)构成旋转轴向量
在STM32飞控开发中,常用以下结构体存储四元数:
typedef struct {
float q0; // 实部
float q1; // i分量
float q2; // j分量
float q3; // k分量
} Quaternion;
四元数相比欧拉角的优势主要体现在:
| 特性 | 欧拉角 | 四元数 |
|---|---|---|
| 维度 | 3个参数 | 4个参数 |
| 奇异点 | 存在(万向节锁) | 无 |
| 计算效率 | 中等 | 高(仅乘法运算) |
| 插值平滑度 | 差 | 优秀(SLERP) |
提示:当无人机做90度俯仰时,欧拉角会出现万向节锁导致姿态解算失效,而四元数则完全不受影响。
2. 传感器数据到四元数的转换实战
MPU6050输出的原始数据包含三轴加速度计和三轴陀螺仪数据,我们需要通过传感器融合算法得到四元数。Mahony滤波算法因其在STM32上的高效实现而被广泛采用:
void MahonyUpdate(float gx, float gy, float gz, float ax, float ay, float az, Quaternion *q) {
float recipNorm;
float vx, vy, vz;
float ex, ey, ez; // 误差项
// 标准化加速度计测量值
recipNorm = 1.0f / sqrt(ax * ax + ay * ay + az * az);
ax *= recipNorm;
ay *= recipNorm;
az *= recipNorm;
// 估计重力方向
vx = 2.0f * (q->q1 * q->q3 - q->q0 * q->q2);
vy = 2.0f * (q->q0 * q->q1 + q->q2 * q->q3);
vz = q->q0 * q->q0 - q->q1 * q->q1 - q->q2 * q->q2 + q->q3 * q->q3;
// 计算误差
ex = (ay * vz - az * vy);
ey = (az * vx - ax * vz);
ez = (ax * vy - ay * vx);
// 积分误差
integralFBx += Ki * ex * dt;
integralFBy += Ki * ey * dt;
integralFBz += Ki * ez * dt;
// 应用反馈
gx += Kp * ex + integralFBx;
gy += Kp * ey + integralFBy;
gz += Kp * ez + integralFBz;
// 四元数积分
q->q0 += (-q->q1 * gx - q->q2 * gy - q->q3 * gz) * 0.5f * dt;
q->q1 += (q->q0 * gx + q->q2 * gz - q->q3 * gy) * 0.5f * dt;
q->q2 += (q->q0 * gy - q->q1 * gz + q->q3 * gx) * 0.5f * dt;
q->q3 += (q->q0 * gz + q->q1 * gy - q->q2 * gx) * 0.5f * dt;
// 归一化
recipNorm = 1.0f / sqrt(q->q0 * q->q0 + q->q1 * q->q1 +
q->q2 * q->q2 + q->q3 * q->q3);
q->q0 *= recipNorm;
q->q1 *= recipNorm;
q->q2 *= recipNorm;
q->q3 *= recipNorm;
}
实际工程中需要注意的几个关键点:
- 采样时间dt:必须精确测量,建议使用STM32的硬件定时器
- 滤波器参数:
- Kp:比例增益,典型值0.5-2.0
- Ki:积分增益,典型值0.001-0.005
- 传感器校准:
- 陀螺仪零偏校准
- 加速度计坐标系对齐
3. 从四元数到欧拉角的实用转换
虽然飞控内部使用四元数计算,但最终控制需要转换为更直观的俯仰(pitch)、横滚(roll)、偏航(yaw)角度。转换公式如下:
roll = atan2(2*(q0*q1 + q2*q3), 1 - 2*(q1² + q2²))
pitch = asin(2*(q0*q2 - q3*q1))
yaw = atan2(2*(q0*q3 + q1*q2), 1 - 2*(q2² + q3²))
对应的C语言实现需要考虑计算效率和精度平衡:
void QuaternionToEuler(const Quaternion *q, float *roll, float *pitch, float *yaw) {
// 横滚角(绕X轴旋转)
float sinr_cosp = 2.0f * (q->q0 * q->q1 + q->q2 * q->q3);
float cosr_cosp = 1.0f - 2.0f * (q->q1 * q->q1 + q->q2 * q->q2);
*roll = atan2f(sinr_cosp, cosr_cosp);
// 俯仰角(绕Y轴旋转)
float sinp = 2.0f * (q->q0 * q->q2 - q->q3 * q->q1);
if (fabs(sinp) >= 1)
*pitch = copysign(M_PI / 2, sinp); // 使用90度极值
else
*pitch = asinf(sinp);
// 偏航角(绕Z轴旋转)
float siny_cosp = 2.0f * (q->q0 * q->q3 + q->q1 * q->q2);
float cosy_cosp = 1.0f - 2.0f * (q->q2 * q->q2 + q->q3 * q->q3);
*yaw = atan2f(siny_cosp, cosy_cosp);
}
注意:当俯仰角接近±90度时,虽然四元数本身不会出现奇异点,但欧拉角转换会出现计算不稳定性,这是所有欧拉角表示法的固有缺陷。
4. 工程实践中的常见问题与优化方案
4.1 数据漂移问题解决方案
即使经过精心校准,长时间运行后四元数仍可能出现漂移。我们采用多传感器融合策略:
-
加速度计补偿:
- 在静止状态下,加速度计测量值应与重力方向一致
- 通过比较实际测量值与重力向量的偏差来修正陀螺仪漂移
-
磁力计辅助(如HMC5883L):
void ApplyMagCorrection(float mx, float my, float mz, Quaternion *q) { // 计算预期磁场方向 float hx = 2.0f * (mx * (0.5f - q->q2*q->q2 - q->q3*q->q3) + my * (q->q1*q->q2 - q->q0*q->q3) + mz * (q->q1*q->q3 + q->q0*q->q2)); float hy = 2.0f * (mx * (q->q1*q->q2 + q->q0*q->q3) + my * (0.5f - q->q1*q->q1 - q->q3*q->q3) + mz * (q->q2*q->q3 - q->q0*q->q1)); // 计算误差并应用修正 float bx = sqrt(hx * hx + hy * hy); float bz = 2.0f * (mx * (q->q1*q->q3 - q->q0*q->q2) + my * (q->q2*q->q3 + q->q0*q->q1) + mz * (0.5f - q->q1*q->q1 - q->q2*q->q2)); float ex = (my * bz - mz * hy); float ey = (mz * hx - mx * bz); // ... 类似加速度计补偿的处理 }
4.2 计算效率优化技巧
在STM32F4系列上,通过以下方法可将四元数更新耗时从200μs降至50μs:
- 使用硬件FPU:确保编译器开启-mfloat-abi=hard选项
- 查表法:预先计算三角函数值
- 汇编优化:关键循环使用CMSIS-DSP库
#include "arm_math.h" void QuaternionMultiply(Quaternion *a, Quaternion *b, Quaternion *out) { arm_quaternion_product_f32(a, b, out); }
4.3 实际飞行测试中的参数整定
通过实际飞行日志分析,我们发现不同飞行模式需要调整滤波器参数:
| 飞行模式 | 推荐Kp值 | 推荐Ki值 | 适用场景 |
|---|---|---|---|
| 平稳模式 | 0.8 | 0.003 | 航拍、巡检 |
| 运动模式 | 1.5 | 0.001 | 竞速、特技飞行 |
| 强风模式 | 2.0 | 0.005 | 恶劣天气条件 |
调试时建议按照以下步骤:
- 先设置Ki=0,逐渐增大Kp直到出现高频振荡
- 取振荡临界值的60%作为Kp最终值
- 缓慢增加Ki直到静态姿态误差消除
- 室外实际飞行验证,微调参数
更多推荐
所有评论(0)