传感器原理与误差分析:从物理到算法的第一道坎
做飞控这些年,我越来越觉得——传感器是姿态控制的“地基”。地基没打好,上面算法再花哨也白搭。今天咱们就聊聊陀螺仪、加速度计、磁力计这些核心传感器,以及它们身上那些让人头疼的误差。
陀螺仪工作原理与零偏
陀螺仪测的是角速度,单位是 °/s 或 rad/s。MEMS 陀螺仪内部有个振动的质量块,当载体旋转时,科里奥利力会让质量块产生位移,电容变化就能读出角速度。原理不复杂,但实际用起来坑不少。
最大的坑就是零偏(Bias)。理想情况下,陀螺仪静止时输出应该是 0,但实际总有那么个固定偏移。比如某款 IMU 的零偏可能是 0.1°/s,积分 10 秒就偏了 1°,这谁能忍?
- 静态零偏:上电后固定不变的偏移,可以通过静态采集取平均扣除
- 动态零偏:随温度、时间缓慢漂移,这才是真正头疼的
我个人习惯的做法是:每次上电后先让飞控静止 5 秒,采集 500 个样本取平均,作为本次飞行的零偏补偿值。但注意,这只能对付静态零偏。
零偏的建模可以用一阶马尔可夫过程,也可以用随机游走模型。实际工程中,我更喜欢用互补滤波的思路——把陀螺仪短期精度和加速度计长期稳定性结合起来,而不是死磕零偏估计。
加速度计标定与噪声
加速度计测的是比力(Specific Force),包含重力加速度和运动加速度。它的误差主要来自三个方面:
| 误差类型 | 来源 | 典型量级 |
|---|---|---|
| 零偏 | 制造工艺、温度 | 10~50 mg |
| 比例因子 | 灵敏度不一致 | 0.1%~1% |
| 交叉轴耦合 | 安装误差 | 0.1°~1° |
| 噪声 | 电路热噪声、量化噪声 | 0.01~0.1 m/s²/√Hz |
标定加速度计,说白了就是找出这些误差参数。最常用的方法是六位置法——把 IMU 分别朝六个方向静止,利用重力作为参考。
// 六位置法标定加速度计(简化版)
// 采集六个方向的均值:ax_up, ax_down, ay_up, ay_down, az_up, az_down
// 零偏 = (正向均值 + 负向均值) / 2
// 比例因子 = (正向均值 - 负向均值) / (2 * g)
float bias_x = (ax_up + ax_down) / 2.0f;
float scale_x = (ax_up - ax_down) / (2.0f * GRAVITY);
// 补偿
float acc_x_comp = (acc_x_raw - bias_x) / scale_x;
加速度计的噪声,我一般用 Allan 方差来分析。说白了就是看不同时间尺度下的噪声特性。对于飞控来说,我们更关心的是高频噪声——它会影响姿态估计的瞬态响应。
降噪的方法有很多:滑动平均、低通滤波、卡尔曼滤波。我个人习惯用二阶巴特沃斯低通滤波器,截止频率设在 20~30 Hz,既能滤掉高频噪声,又不会引入太大延迟。
磁力计硬铁软铁校准
磁力计测的是地磁场,但实际环境中到处都是干扰。硬铁干扰来自永磁体或带磁金属,会产生一个固定的偏置磁场。软铁干扰来自铁磁性材料,会扭曲和缩放地磁场。
硬铁校准相对简单。把飞控水平旋转 360°,采集的数据点会形成一个圆,圆心偏移就是硬铁干扰。
- 水平旋转飞控至少一圈,采集磁力计数据
- 计算 X 轴和 Y 轴的最大最小值
- 硬铁偏移 = (max + min) / 2
- 从原始数据中减去偏移
软铁校准就复杂一些。它会让圆形变成椭圆,需要做椭球拟合。我常用的方法是最小二乘椭球拟合,解出 3x3 的软铁矩阵和 3x1 的硬铁向量。
// 椭球拟合校准(伪代码)
// 采集 N 组磁力计数据 [mx, my, mz]
// 构建椭球方程:A*x^2 + B*y^2 + C*z^2 + D*x*y + E*x*z + F*y*z + G*x + H*y + I*z = 1
// 用最小二乘法解出参数 A~I
// 从参数中提取硬铁偏移和软铁矩阵
// 校准后的磁场 = soft_iron_matrix * (raw - hard_iron_offset)
校准完成后,怎么判断效果?看总磁场强度。校准后的总磁场应该接近当地地磁场强度(比如 0.45~0.55 Gauss),而且不管飞控怎么转,总磁场变化不超过 5%。
IMU 温度补偿策略
温度对 IMU 的影响,说实话比很多人想象的要大。MEMS 陀螺仪的零偏随温度变化可能达到 0.01°/s/°C,加速度计零偏也有 0.1 mg/°C。如果飞控从 25°C 的室内飞到 50°C 的户外,光温度漂移就能让姿态误差累积到不可接受的程度。
温度补偿有三种常见策略:
| 策略 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| 查表法 | 预先标定不同温度下的零偏,存成表格 | 实现简单,计算量小 | 需要大量标定数据,温度点有限 |
| 多项式拟合 | 用多项式拟合零偏-温度曲线 | 连续补偿,精度较高 | 需要确定多项式阶数 |
| 在线估计 | 在卡尔曼滤波中把温度作为状态量估计 | 自适应,无需离线标定 | 实现复杂,收敛慢 |
我个人最常用的是多项式拟合。先做温箱实验,采集 -20°C 到 60°C 范围内的零偏数据,然后用三阶多项式拟合。
// 三阶多项式温度补偿
// 假设已经拟合出系数:p0, p1, p2, p3
float temp = get_temperature(); // 单位 °C
float bias_comp = p0 + p1*temp + p2*temp*temp + p3*temp*temp*temp;
// 补偿后的角速度
float gyro_comp = gyro_raw - bias_comp;
还有一个容易被忽略的点——温度变化率。快速升温时,IMU 内部温度梯度会导致瞬态误差,这时候静态补偿模型就不太准了。我的做法是在卡尔曼滤波中增加一个温度变化率的观测,动态调整补偿参数。
- 温箱标定时,每个温度点至少稳定 10 分钟再采集数据
- 多项式阶数不要超过四阶,否则容易过拟合
- 实际飞行中,如果温度变化超过 10°C,建议重新标定
- 把温度数据记录到日志里,方便事后分析
嗯,传感器这块内容确实不少。但说白了,误差分析就是搞清楚“传感器告诉我的数据到底有多可信”。搞明白了这个,后面的姿态估计算法才能有的放矢。