3. IMU 数据预处理:加速度计校准、陀螺仪零偏补偿、温度补偿、低通滤波
IMU 是飞控的「眼睛」和「内耳」。它告诉你飞机现在是什么姿态、在往哪个方向转。但说实话,刚出厂的 IMU 数据根本没法直接用——噪声大、有偏置、还受温度影响。我早年调一架六轴的时候,就因为没做温度补偿,冬天试飞时悬停姿态直接漂了 5 度,差点炸机。
所以这一章,咱们把 IMU 数据预处理的四个核心环节掰开揉碎讲清楚。你想想看,如果原始数据是脏的,后面再好的滤波算法也是白搭。
核心原则:预处理的目标是把「能用但不准」的原始 IMU 数据,变成「准且稳」的可用数据。四个步骤缺一不可。
3.1 加速度计校准:把「歪」的掰正
加速度计测量的是比力,也就是重力加上运动加速度。但 MEMS 加速度计天生有三大毛病:零偏、刻度因子误差、轴间非正交。说白了,你把它平放,它读出来的三个轴不一定是 (0, 0, 9.81)。
我习惯用六位置法做校准。把 IMU 分别朝六个方向静止放置,采集数据,然后解算出零偏和刻度因子。具体步骤是这样的:
- 静止采集:每个方向保持 2-3 秒,采样率 100Hz 以上。
- 取均值:去掉头尾各 0.5 秒,取中间稳定段均值。
- 构建方程:每个方向的理论值已知,实测值已知,解最小二乘。
- 写入参数:把零偏和刻度因子存到参数文件里。
我的小技巧:六位置法不需要转台,手动翻转就行。但一定要保证每个方向静止时没有振动。我曾经在水泥地上做校准,旁边有人走路,数据全废了。
校准模型长这样:
// 加速度计校准模型
// raw: 原始读数, bias: 零偏, scale: 刻度因子, misalign: 非正交矩阵
calib_acc[3] = misalign_matrix * (raw[3] - bias[3]) / scale[3];
校准完成后,验证方法很简单:把 IMU 平放,看 Z 轴读数是不是接近 9.81,X 和 Y 轴接近 0。误差在 ±0.05 m/s² 以内就算合格。
3.2 陀螺仪零偏补偿:静止时不能「转」
陀螺仪测角速度。理想情况下,静止时三个轴输出都是 0。但实际总有零偏,而且这个零偏还会随时间缓慢变化。嗯,这里要注意:陀螺仪的零偏是温度敏感型,也是时间敏感型。
我常用的方法是启动时做一次静态零偏采集:
- 上电后保持无人机绝对静止 5-10 秒。
- 采集这段时间的陀螺仪数据,取均值作为零偏。
- 飞行过程中,用这个零偏做实时扣除。
注意:启动时采集的零偏只在当前温度下有效。如果飞行中温度变化超过 10°C,零偏可能漂移。这时候就需要温度补偿上场了。
零偏补偿的代码实现很简单:
// 陀螺仪零偏补偿
// gyro_bias 在启动时静态采集得到
gyro_compensated[0] = gyro_raw[0] - gyro_bias[0];
gyro_compensated[1] = gyro_raw[1] - gyro_bias[1];
gyro_compensated[2] = gyro_raw[2] - gyro_bias[2];
3.3 温度补偿:别让天气影响你的判断
MEMS 器件的温度特性很明显。我测过一款常见的 IMU,从 0°C 到 60°C,陀螺仪零偏能漂移 0.5 °/s。你想想看,0.5 °/s 的零偏在积分 10 秒后就是 5 度的姿态误差,这谁能忍?
温度补偿的做法分两步:
- 标定阶段:把 IMU 放进温箱,从 -20°C 到 70°C 每 5°C 记录一次零偏,拟合出一条曲线。
- 运行阶段:根据当前温度,查表或计算对应的零偏修正值。
| 温度 (°C) | 陀螺仪 X 轴零偏 (°/s) | 陀螺仪 Y 轴零偏 (°/s) | 陀螺仪 Z 轴零偏 (°/s) |
|---|---|---|---|
| -10 | 0.32 | -0.28 | 0.15 |
| 25 | 0.05 | -0.03 | 0.02 |
| 60 | -0.21 | 0.18 | -0.10 |
实际工程中,大多数飞控不会做完整的温箱标定,太贵了。折中方案是:在启动时采集零偏,然后根据内置温度传感器的读数,用预设的温漂系数做线性修正。虽然精度差一些,但够用。
我的经验:如果你用的是消费级 IMU(比如 MPU6000、ICM-20602),温漂系数可以从 datasheet 里查到。但 datasheet 给的是典型值,每颗芯片都不一样。预算允许的话,还是建议做单颗标定。
3.4 低通滤波:把高频噪声「掐掉」
经过前三步,数据已经准了,但还不够稳。MEMS 传感器的高频噪声很厉害,尤其是陀螺仪,在 100Hz 以上频段噪声能量很大。如果不滤波,这些噪声会直接进入姿态解算,导致控制量抖动。
我常用的滤波器是二阶巴特沃斯低通滤波器。为什么不用一阶?一阶衰减太慢,截止频率附近效果不好。为什么不用高阶?计算量太大,飞控的 MCU 资源有限。
滤波器设计参数:
- 截止频率:加速度计 20-30 Hz,陀螺仪 40-60 Hz。
- 采样频率:通常 200-1000 Hz,根据 MCU 性能定。
- 滤波器阶数:二阶足够,四阶是上限。
// 二阶低通滤波器实现(直接 II 型)
// b0, b1, b2, a1, a2 由截止频率和采样率计算得到
static float x1 = 0, x2 = 0, y1 = 0, y2 = 0;
float lowpass_filter(float input) {
float output = b0 * input + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2;
x2 = x1;
x1 = input;
y2 = y1;
y1 = output;
return output;
}
避坑指南:我曾经把截止频率设得太低(10 Hz),结果飞机快速机动时姿态响应滞后,飞起来像「喝醉了」。后来改成 40 Hz,才恢复正常。记住:滤波是去掉噪声,不是去掉信号。
3.5 预处理流程总结
把四个步骤串起来,完整的预处理流程是这样的:
- 读取原始 IMU 数据(加速度计 + 陀螺仪 + 温度)。
- 对加速度计做六位置法校准,得到校准后的加速度值。
- 对陀螺仪做零偏补偿(启动时静态采集 + 实时扣除)。
- 根据当前温度,查温漂曲线,修正陀螺仪零偏。
- 分别对加速度计和陀螺仪做低通滤波。
- 输出干净的 IMU 数据给姿态解算模块。
这个流程看起来简单,但每一步都有坑。我见过不少新手,上来就调姿态 PID,结果发现飞机乱晃,最后查出来是加速度计没校准。所以,别跳过预处理,它值得你花时间。