第1章:IMU测量模型与误差分析
大家好,我是你们这门课的主讲。做惯导这么多年,我最大的体会就是:搞懂IMU的误差模型,比学会融合算法更重要。为什么?因为你的算法再牛,输入的数据是垃圾,输出也一定是垃圾。今天我们就来把IMU的底裤扒干净。
1.1 加速度计测量模型
先看加速度计。理想情况下,加速度计输出的是比力——也就是物体受到的惯性力与重力的合力。但现实嘛,总是不完美的。
我习惯把加速度计的测量模型写成这样:
a_m = S_a * (a_true + b_a + n_a) + 其他误差
其中:
- a_m:测量值,你从芯片读到的那个数
- a_true:真实比力,我们想要的东西
- S_a:尺度因子矩阵,包含尺度误差和交轴耦合
- b_a:零偏,随时间缓慢变化
- n_a:白噪声,高频随机波动
说白了,你读到的加速度 = 真实值经过缩放、旋转、加偏置、再加噪声。每一步都是坑。
核心要点:加速度计的误差主要分两类——确定性误差(可以标定补偿的)和随机误差(只能建模的)。零偏和尺度因子属于前者,白噪声属于后者。
1.2 陀螺仪测量模型
陀螺仪的原理类似,但更敏感。我做过一个项目,陀螺仪零偏漂移了0.1°/s,积分10分钟,姿态就偏了60度。你说可怕不可怕?
陀螺仪的模型:
ω_m = S_g * (ω_true + b_g + n_g) + 其他
参数含义和加速度计基本一致:
- ω_m:角速度测量值
- ω_true:真实角速度
- S_g:尺度因子矩阵
- b_g:陀螺零偏
- n_g:陀螺白噪声
个人经验:陀螺仪的零偏稳定性比加速度计差一个数量级。我建议你在选型时,重点关注陀螺仪的零偏稳定性指标,而不是只看量程。
1.3 误差来源深度解析
好,我们来逐个拆解这些误差。你想想看,一个IMU芯片内部,微米级的结构,温度一变、电压一抖,输出就变了。
1.3.1 零偏(Bias)
零偏就是IMU静止时,输出不为0的那个值。比如加速度计平放着,理论上应该输出[0, 0, g],但实际可能是[0.02, -0.01, 9.81]。这0.02就是零偏。
零偏又分两种:
- 常值零偏:上电后基本固定,可以通过标定去掉
- 零偏稳定性:随时间缓慢变化,是VIO系统最大的敌人
避坑指南:我曾经在一个项目中,忽略了零偏的温度效应。结果IMU在阳光下晒了10分钟,零偏漂了3倍,整个定位系统直接崩了。后来我学乖了,每次做实验前先让IMU预热5分钟。
1.3.2 尺度因子(Scale Factor)
尺度因子说白了就是增益误差。你输入1g,它输出0.98g,那尺度因子就是0.98。这个误差通常是非线性的,跟输入大小有关。
1.3.3 交轴耦合(Cross-axis Coupling)
这个比较隐蔽。理想情况下,IMU的三个轴应该是完全正交的。但制造工艺嘛,总有偏差。X轴感受到的加速度,可能会串到Y轴上去。这就是交轴耦合。
我习惯用矩阵来表示:
S = [s_xx, s_xy, s_xz;
s_yx, s_yy, s_yz;
s_zx, s_zy, s_zz]
对角线是尺度因子,非对角线是交轴耦合系数。好的IMU,非对角线系数一般在1%以内。便宜的MEMS,可能到5%。
1.4 Allan方差分析实战
好了,理论说完了,我们来点实际的。Allan方差是分析IMU随机误差的利器。我当年第一次用Allan方差时,觉得这东西太神奇了——它能从一段静态数据里,把各种噪声成分分离出来。
1.4.1 基本原理
Allan方差的思路很简单:对一段静态数据,取不同时间长度的子段,计算每个子段的均值,再求这些均值的方差。随着子段长度变化,方差曲线会呈现不同的斜率,对应不同的噪声源。
1.4.2 代码实战
下面是我常用的Allan方差计算代码,你们可以直接拿去用:
import numpy as np
import matplotlib.pyplot as plt
def allan_variance(data, fs):
"""
计算Allan方差
data: 输入数据(一维)
fs: 采样频率(Hz)
"""
N = len(data)
max_m = int(np.log2(N)) - 1
tau = np.zeros(max_m)
adev = np.zeros(max_m)
for m in range(1, max_m + 1):
# 计算子段长度
L = 2**m
tau[m-1] = L / fs
# 计算每个子段的均值
num_clusters = N // L
cluster_means = np.zeros(num_clusters)
for i in range(num_clusters):
cluster_means[i] = np.mean(data[i*L:(i+1)*L])
# 计算Allan方差
if num_clusters > 1:
adev[m-1] = np.sqrt(0.5 * np.mean(
(cluster_means[1:] - cluster_means[:-1])**2
))
return tau, adev
# 使用示例
# 假设你有一段静态IMU数据
# tau, adev = allan_variance(gyro_data, 100)
# plt.loglog(tau, adev)
# plt.xlabel('时间 (s)')
# plt.ylabel('Allan标准差')
# plt.grid(True)
# plt.show()
我的习惯:Allan方差分析至少需要1小时以上的静态数据。数据太短,长周期噪声看不出来。我一般会采集2-3小时,然后取中间最稳定的一段。
1.4.3 结果解读
Allan方差曲线通常呈现这样的特征:
- 斜率-1/2段:对应白噪声,也就是角度随机游走(ARW)或速度随机游走(VRW)
- 斜率0段(平坦区):对应零偏稳定性
- 斜率+1/2段:对应速率斜坡(Rate Ramp),通常是温度漂移
从曲线上,我们可以提取三个关键指标:
| 指标 | 含义 | 单位 |
|---|---|---|
| 角度随机游走 | 白噪声强度 | °/√h |
| 零偏稳定性 | 曲线最低点 | °/h |
| 速率斜坡 | 长周期漂移 | °/h² |
实战经验:我见过很多同学拿到Allan方差曲线后,不知道怎么看。记住一句话:曲线的最低点就是你的零偏稳定性。这个值决定了你的VIO系统能维持多久不飘。
1.5 本章知识体系
为了让大家更直观地理解本章的知识结构,我画了一张图:
这张图把本章的知识脉络串起来了。从上到下,从IMU到具体传感器,再到测量模型、误差来源,最后用Allan方差做分析,提取关键指标。你把这个图记在脑子里,后面学融合算法时就会清晰很多。
最后说一句:IMU误差分析是VIO系统的基石。我见过太多人一上来就调融合参数,结果定位精度上不去,最后发现是IMU标定没做好。所以,先把IMU的脾气摸透,再谈算法优化。