3. 惯性导航基础(二)
各位同学,欢迎来到惯性导航的第二讲。上一节我们聊了聊惯性导航的基本概念和坐标系。今天,我们要深入IMU的内部,看看它到底是怎么工作的,以及它为什么会有误差。
说实话,IMU这东西,看着简单,用起来全是坑。我刚开始做融合定位那会儿,拿到一个IMU数据就直接往算法里灌,结果定位结果飘得亲妈都不认识。后来才明白,不把IMU的“脾气”摸透,融合定位就是空中楼阁。
好,我们正式开始。
3.1 IMU测量模型
IMU输出的,说白了就是两个东西:加速度和角速度。但这两个值,并不是理想值,而是被各种误差污染过的。
我们先看加速度计的测量模型。一个三轴加速度计,它的输出可以写成这样:
a_m = a_t + b_a + s_a * a_t + n_a
这里:
a_m是测量值,也就是你从芯片读出来的数。a_t是真实值,你想知道的那个。b_a是零偏(bias),一个缓慢变化的量。s_a是比例因子误差(scale factor),说白了就是放大或缩小的倍数不准。n_a是随机噪声,白噪声为主。
陀螺仪的模型也类似:
ω_m = ω_t + b_g + s_g * ω_t + n_g
符号含义跟上面一一对应。你想想看,如果这些误差项不处理,积分出来的姿态和位置,那误差会像滚雪球一样,越来越大。
核心要点:IMU的测量模型,本质上就是“真实值 + 确定性误差 + 随机误差”。我们做算法,就是要从测量值中,尽可能地把真实值“捞”出来。
3.2 加速度计与陀螺仪原理
搞懂原理,你才能理解误差的来源。我建议你至少要知道它们是怎么工作的,哪怕只是概念层面。
3.2.1 加速度计原理
最常见的MEMS加速度计,用的是电容式原理。内部有一个微小的质量块,被弹簧悬挂着。当有加速度时,质量块会移动,导致电容变化。通过测量电容,就能反推出加速度。
嗯,这里要注意:加速度计测量的是“比力”,不是重力。它测的是物体受到的惯性力与重力的合力。所以,当加速度计静止放在桌面上时,它测到的是1g的重力加速度,而不是0。
我在项目中遇到过一个问题:有人把加速度计竖直安装,结果静态时Z轴输出是0,他以为坏了。其实不是,那是因为重力被X或Y轴分担了。所以,安装方向一定要搞清楚。
3.2.2 陀螺仪原理
MEMS陀螺仪的原理稍微复杂一点,用的是科里奥利效应。简单说,就是一个振动的质量块,当它旋转时,会受到一个垂直于振动方向的力,这个力的大小与角速度成正比。
你想想看,这个力非常微弱,所以陀螺仪对温度、振动都很敏感。这也是为什么陀螺仪的零偏稳定性通常比加速度计差的原因。
个人经验:选型时,我一般会先看陀螺仪的零偏稳定性指标。如果这个值太大,后面做零偏估计会非常痛苦。
3.3 误差模型与Allan方差分析
好,原理讲完了,我们来看看怎么分析误差。这是我最想跟你分享的部分。
IMU的误差,可以分为两类:确定性误差和随机误差。
- 确定性误差:包括零偏、比例因子、安装误差、交叉耦合等。这些可以通过标定来补偿。
- 随机误差:包括白噪声、随机游走、零偏不稳定性等。这些需要用随机模型来描述。
怎么分析随机误差?最经典的工具就是Allan方差。
3.3.1 什么是Allan方差?
Allan方差,说白了就是一种时域分析方法。它通过计算不同时间尺度上的方差,来揭示噪声的组成。
具体做法是:
- 采集一段长时间的静态数据(比如1小时以上)。
- 将数据按不同的时间长度(τ)分段。
- 计算每段数据的平均值,然后求相邻段平均值的差的方差。
这个方差就是Allan方差。它跟τ的关系,可以画成一条曲线。不同的噪声类型,在曲线上有不同的斜率。
3.3.2 如何解读Allan方差曲线?
我直接给你一个典型的曲线解读方法:
| 噪声类型 | Allan方差斜率 | 物理意义 |
|---|---|---|
| 量化噪声 | -1 | ADC分辨率不够 |
| 角度/速度随机游走 | -1/2 | 白噪声积分的结果 |
| 零偏不稳定性 | 0 | 曲线的最低点,代表零偏稳定性 |
| 角速率/加速度随机游走 | +1/2 | 低频漂移 |
| 速率斜坡 | +1 | 温度引起的线性漂移 |
我曾经用Allan方差分析过一个国产IMU,发现它的零偏不稳定性指标标称是10°/h,但实际曲线最低点对应的值却是15°/h。嗯,这就是典型的参数虚标。所以,拿到IMU后,我建议你自己跑一遍Allan方差分析,心里才有底。
3.3.3 代码实现
下面是一个简单的Allan方差计算代码,用Python写的。你可以直接拿去用。
import numpy as np
import matplotlib.pyplot as plt
def allan_variance(data, max_tau):
"""
计算Allan方差
:param data: 一维数组,静态IMU数据
:param max_tau: 最大时间尺度(点数)
:return: tau列表, allan方差列表
"""
n = len(data)
taus = []
allan_vars = []
for tau in range(1, max_tau + 1):
# 分段
m = n // tau
if m < 2:
break
# 计算每段均值
means = np.mean(data[:m*tau].reshape(m, tau), axis=1)
# 计算相邻均值的差
diff = np.diff(means)
# 计算Allan方差
var = 0.5 * np.mean(diff**2)
taus.append(tau)
allan_vars.append(var)
return np.array(taus), np.array(allan_vars)
# 使用示例
# 假设 gyro_data 是你的陀螺仪静态数据
# taus, avars = allan_variance(gyro_data, 1000)
# plt.loglog(taus, np.sqrt(avars))
# plt.xlabel('Tau (samples)')
# plt.ylabel('Allan Deviation')
# plt.grid(True)
# plt.show()
避坑指南:我曾经犯过一个错误,就是采集数据时间不够长。Allan方差分析需要足够长的数据才能看到低频噪声的特征。一般来说,至少需要采集1小时以上的数据。如果只采集几分钟,你只能看到白噪声部分,零偏不稳定性根本看不出来。
3.4 本章知识体系
为了让你更直观地理解本章的内容,我画了一张图,把核心逻辑串起来。
这张图把本章的核心内容串起来了。从IMU测量模型出发,理解加速度计和陀螺仪的原理,然后分析误差模型,最后用Allan方差来量化随机误差。每一步都是环环相扣的。
好,今天就到这里。记住,IMU的误差分析是融合定位的基石。这块搞不明白,后面做卡尔曼滤波、做松紧耦合,都会很吃力。建议你找个IMU,自己跑一遍Allan方差分析,感受一下。