2. IMU误差模型与标定:确定性误差与随机误差、Allan方差分析、六面法标定与温漂补偿
IMU这东西,说白了就是自动驾驶的「内耳前庭」。你想想看,车在隧道里、高架桥下,GPS信号一丢,全靠它撑着。但IMU有个毛病——它天生就是个「说谎精」。我做了这么多年定位,见过太多被IMU坑惨的项目。所以今天咱们就来扒一扒,怎么让这个说谎精说实话。
2.1 误差从哪来?先分个类
IMU的误差,我习惯分成两大类:确定性误差和随机误差。这俩性质完全不同,处理手段也天差地别。
2.1.1 确定性误差
这类误差是「有规律」的,说白了就是可以建模、可以补偿的。主要包括:
- 零偏(Bias):静止时输出不为零。比如陀螺仪,你把它放桌上不动,它却告诉你「我在转」。我见过最离谱的MEMS陀螺,零偏能到每秒好几度。
- 尺度因子(Scale Factor):输入和输出不成比例。你转10度,它告诉你转了10.5度。
- 交轴耦合(Misalignment):三个轴没装正。X轴转动时,Y轴也有输出。嗯,这就是机械装配的锅。
核心公式:
ω_measured = S * ω_true + b + n
其中S是尺度因子矩阵,b是零偏,n是噪声。这个公式,我建议你刻在脑子里。
2.1.2 随机误差
这类误差是「没规律」的,只能用统计方法描述。我在项目中遇到过最头疼的就是它——你永远不知道下一秒的噪声长什么样。
- 白噪声(White Noise):高频随机波动,像收音机的沙沙声。
- 随机游走(Random Walk):零偏随时间缓慢漂移。你今天标定好的零偏,明天可能就变了。
- 量化噪声(Quantization Noise):ADC采样精度不够导致的。
我的经验: 随机误差才是IMU标定的真正难点。确定性误差一次标定就能搞定,但随机误差需要长期观测和在线估计。
2.2 Allan方差分析——给IMU做「体检」
Allan方差,说白了就是给IMU做一次全面体检。它能告诉你:你的IMU到底有多烂,烂在哪个频段。
2.2.1 基本原理
为什么要用Allan方差?因为普通的方差会随着采样时间变化。你取1秒的数据算方差,和取100秒的数据算方差,结果完全不一样。Allan方差解决了这个问题——它把数据切成不同长度的块,分别算方差。
具体做法很简单:
- 采集一段长时间的静态数据(至少1小时,我建议2小时以上)
- 把数据按不同时间长度τ切成若干段
- 对每个τ,计算所有段的方差
- 画出log(τ) vs log(Allan方差)的曲线
2.2.2 怎么看这条曲线?
Allan方差曲线有典型的形状,不同斜率对应不同误差源:
| 斜率 | 对应误差 | 物理意义 |
|---|---|---|
| -1/2 | 白噪声(角度/速度随机游走) | 高频抖动,取平均就能抑制 |
| 0 | 零偏不稳定性(Bias Instability) | IMU的「底噪」,这是最重要的指标 |
| +1/2 | 速率随机游走 | 零偏的长期漂移 |
| +1 | 速率斜坡 | 温度引起的确定性漂移 |
关键点: 曲线的最低点对应的τ值,就是你的IMU「最佳积分时间」。低于这个时间,白噪声主导;高于这个时间,零偏漂移主导。我选IMU时,第一件事就是看这个最低点。
2.2.3 代码实现
嗯,这里给个Python实现,我项目里一直在用:
def allan_variance(data, fs):
"""
data: 静态IMU数据
fs: 采样率
"""
N = len(data)
max_pow = int(np.log2(N)) - 1
tau = []
avar = []
for i in range(1, max_pow):
m = 2**i
tau.append(m / fs)
# 分成不重叠的段
num_segments = N // m
segments = data[:num_segments*m].reshape(num_segments, m)
# 每段取平均
means = np.mean(segments, axis=1)
# 计算方差
avar.append(0.5 * np.var(means[1:] - means[:-1]))
return np.array(tau), np.array(avar)
避坑指南: 我曾经因为数据采集时间不够长,Allan方差曲线在长τ段全是噪声。后来养成了习惯——静态数据至少采2小时,最好过夜采集。
2.3 六面法标定——给IMU「对表」
六面法,说白了就是把IMU放在6个不同的姿态,利用重力作为参考,反算出零偏和尺度因子。这个方法简单粗暴,但非常有效。
2.3.1 标定流程
你需要一个三轴转台,或者至少一个水平台面。我早期在实验室里,就用一个精密水平仪加一个直角块,也能凑合用。
- 水平放置:Z轴朝上,采集30秒
- 翻转180°:Z轴朝下,采集30秒
- 侧放:X轴朝上,采集30秒
- 侧放翻转:X轴朝下,采集30秒
- 侧放:Y轴朝上,采集30秒
- 侧放翻转:Y轴朝下,采集30秒
2.3.2 数学模型
对于加速度计,每个轴的理论输出应该是±g(重力加速度)。实际输出和理论值的关系是:
a_measured = S * a_true + b
写成矩阵形式:
[a_x] [s_xx s_xy s_xz] [a_x_true] [b_x]
[a_y] = [s_yx s_yy s_yz] [a_y_true] + [b_y]
[a_z] [s_zx s_zy s_zz] [a_z_true] [b_z]
6个姿态,每个姿态提供3个方程,一共18个方程。用最小二乘法就能解出12个未知数(3个零偏 + 9个尺度因子)。
注意: 六面法假设转台或台面绝对水平。我曾经在一个不平的台面上标定,结果零偏误差大了3倍。后来我学乖了——每次标定前先用水平仪校准台面。
2.4 温漂补偿——IMU的「体温计」
温度对IMU的影响,比你想象的大得多。我记得有一次冬天做路测,早上零下10度标定的IMU,中午太阳一晒,零偏直接漂了20%。从那以后,温漂补偿就成了我的必修课。
2.4.1 温漂特性
IMU的零偏和尺度因子,随温度变化呈非线性关系。典型的温漂曲线是这样的:
- MEMS IMU:温度每变化1°C,零偏变化约0.01~0.1°/s
- 光纤陀螺:温漂小一些,但启动阶段变化剧烈
- 激光陀螺:温漂最小,但价格感人
2.4.2 补偿方法
我常用的方法是多项式拟合:
b(T) = c0 + c1*T + c2*T^2 + c3*T^3
标定步骤:
- 把IMU放进温箱,从-40°C到85°C,每5°C一个点
- 每个温度点保持30分钟,让IMU充分热平衡
- 记录每个温度下的零偏和尺度因子
- 用最小二乘法拟合多项式系数
我的经验: 3阶多项式通常就够了,阶数太高反而容易过拟合。另外,温箱的升降温速率要慢,我一般控制在1°C/min,太快了热应力会影响结果。
2.5 本章小结
IMU标定这件事,说难不难,说简单也不简单。你想想看,一个没标定好的IMU,就像一块不准的表——你越依赖它,它越坑你。我见过太多项目,算法调得天花乱坠,结果IMU本身就有问题,白费功夫。
核心就三点:
- 确定性误差用六面法搞定,一次标定管半年
- 随机误差用Allan方差摸清底细,指导滤波器设计
- 温漂必须补偿,尤其是车规级应用,温度范围宽
嗯,标定做好了,后面的融合定位才能站得住脚。否则,再好的算法也是空中楼阁。