4. 误差模型与标定
IMU这东西,说白了就是个“积分器”。你给它一个加速度,它积分出速度;你给它一个角速度,它积分出姿态。但问题是——它积分出来的东西,准不准?
我做了这么多年融合定位,最深的体会就是:IMU的精度,七分靠标定,三分靠算法。你想想看,如果传感器本身就有偏差,后面再怎么滤波、怎么融合,都是“垃圾进,垃圾出”。
这一章,我们就来聊聊IMU的误差到底从哪来,怎么建模,以及——怎么把它标定掉。
4.1 确定性误差:那些“固定”的偏差
确定性误差,顾名思义,就是每次开机都差不多的那类误差。它们有规律可循,所以我们可以通过标定来补偿。
4.1.1 零偏(Bias)
零偏是最直观的误差。你把IMU放在桌面上不动,理论上加速度计应该输出[0, 0, g],陀螺仪应该输出[0, 0, 0]。但实际呢?
我见过最离谱的一次,某款MEMS陀螺仪静态输出竟然有0.5°/s的零偏。这意味着什么?你静止放10秒,姿态就偏了5度。这还怎么玩?
零偏的数学模型很简单:
ω_measured = ω_true + b_g + n_g
a_measured = a_true + b_a + n_a
其中b_g和b_a就是陀螺仪和加速度计的零偏。注意,零偏不是一成不变的——它随温度漂移,随上电时间变化。所以,每次开机后做静态初始化,就是为了估计当前的零偏。
4.1.2 比例因子(Scale Factor)
比例因子,说白了就是“输入输出之间的斜率偏差”。理想情况下,你转1°/s,陀螺仪输出1°/s。但实际可能是0.98或者1.02。
比例因子误差的模型:
ω_measured = (1 + s_g) · ω_true + b_g
a_measured = (1 + s_a) · a_true + b_a
s_g和s_a就是比例因子误差。这个误差在高速运动时特别明显。我记得有一次做车载测试,车辆急转弯时角速度达到100°/s,比例因子误差1%就意味着1°/s的偏差——这已经不可忽略了。
4.1.3 交轴耦合(Cross-axis Sensitivity)
交轴耦合,是IMU内部三个轴不完全正交导致的。你只绕X轴旋转,Y轴和Z轴也会“感应”到信号。
这个误差在廉价MEMS里特别常见。我拆过一款消费级IMU,交轴耦合系数竟然有2%。这意味着什么?你绕Z轴转100°/s,X轴会“看到”2°/s的假信号。
完整的确定性误差模型,其实是一个矩阵:
ω_measured = M_g · ω_true + b_g
a_measured = M_a · a_true + b_a
其中M_g和M_a是3x3矩阵,对角线是比例因子,非对角线是交轴耦合系数。
4.2 随机误差:那些“飘忽不定”的噪声
确定性误差标定完了,IMU就准了吗?
远没有。你还会发现,即使标定完,静态输出仍然在“抖动”。这就是随机误差——它没有固定规律,只能用统计方法描述。
4.2.1 角度随机游走(Angle Random Walk, ARW)
陀螺仪的输出噪声,积分后会导致角度误差随时间累积。这个累积过程,就像随机游走一样——所以叫“角度随机游走”。
单位通常是 °/√h。数值越小越好。高精度光纤陀螺能做到0.001°/√h以下,而MEMS一般在0.1~1°/√h之间。
4.2.2 速率随机游走(Rate Random Walk, RRW)
这个更隐蔽。它描述的是零偏本身在缓慢漂移。你开机时零偏是0.1°/s,过一小时可能变成了0.15°/s。
为什么会这样?温度变化、器件老化、电源波动……原因很多。所以,长时间导航时,必须在线估计零偏,这就是后面章节要讲的“在线标定”。
4.2.3 Allan方差分析:给噪声“拍X光片”
Allan方差,是分析IMU随机误差的“金标准”。它能帮你把不同噪声成分分离出来。
做法很简单:采集长时间静态数据(至少2小时),然后计算不同时间尺度下的方差。结果画成log-log图,你会看到一条曲线——不同斜率对应不同噪声类型。
Allan方差曲线解读:
| 斜率 | 对应噪声 | 物理含义 |
|---|---|---|
| -1/2 | 角度随机游走 | 白噪声积分 |
| 0 | 零偏稳定性 | 零偏的长期波动 |
| +1/2 | 速率随机游走 | 零偏的缓慢漂移 |
| +1 | 量化噪声 | AD转换精度限制 |
下面这张图,是我用Python画的一个典型Allan方差曲线。你可以看到不同时间尺度下,主导噪声的变化:
4.3 实验室标定流程:一步一步来
好了,理论讲完了。现在说说实际怎么做标定。我总结了一套“六步法”,在多个项目中验证过:
- 静态采集:IMU水平放置,采集30分钟静态数据。用于估计零偏和Allan方差。
- 六位置法:将IMU分别朝6个方向(±X, ±Y, ±Z)静止放置。每个位置采集2分钟。用于标定加速度计的比例因子和零偏。
- 速率测试:在转台上以不同角速度旋转(如±10°/s, ±50°/s, ±100°/s)。用于标定陀螺仪的比例因子。
- 多姿态测试:将IMU倾斜不同角度(如30°, 45°, 60°)。用于标定交轴耦合系数。
- 温度循环:在温箱中从-40°C到85°C循环。用于建立温度补偿模型。
- 验证测试:用一组独立数据验证标定效果。计算残差,确认是否满足精度要求。
4.4 标定结果怎么用?
标定完成后,你会得到一组参数。在代码里,补偿逻辑大概是这样的:
// 原始数据
float gx_raw, gy_raw, gz_raw;
float ax_raw, ay_raw, az_raw;
// 标定参数
float bias_g[3] = {0.02, -0.01, 0.03}; // 陀螺零偏 (°/s)
float scale_g[3] = {0.998, 1.002, 0.999}; // 陀螺比例因子
float cross_g[3][3] = { // 陀螺交轴耦合矩阵
{1.000, 0.002, -0.001},
{-0.001, 1.000, 0.003},
{0.002, -0.001, 1.000}
};
// 补偿
float gx_corrected = cross_g[0][0] * (gx_raw - bias_g[0]) / scale_g[0]
+ cross_g[0][1] * (gy_raw - bias_g[1]) / scale_g[1]
+ cross_g[0][2] * (gz_raw - bias_g[2]) / scale_g[2];
// ... 类似处理Y轴和Z轴
嗯,代码看着有点繁琐,但这是必须的。我见过有人偷懒只补偿零偏,结果在高动态场景下轨迹完全跑飞。
好了,这一章的内容就到这里。标定这件事,说起来简单,做起来全是细节。希望我的这些经验能帮你少走一些弯路。
可可精品资料库