首页 / 资讯中心 / 文章详情

IMU标定怎么做?多位置任意姿态静止标定法详解

IMU标定怎么做?多位置任意姿态静止标定法详解 ★ FEATURED ARTICLE
做机器人、无人机或者自动驾驶的朋友对IMU应该都不陌生。但真正上手做过SLAM、组合导航或者位姿估计的人迟早都会撞上一堵墙IMU的原始数据直接拿来用效果惨不忍睹。零偏、尺度误差、安装轴偏差这些看不见摸不着的家伙会把你的积分结果一点点带偏最后轨迹歪到姥姥家。而大多数人卡住的第一道坎就是标定。市面上主流的IMU标定方案无非两条路要么买高精度转台把IMU固定在转台上做精密角速度激励成本高、操作繁琐要么用所谓的“六面静止法”把IMU摆成六个特定姿态靠重力作为参考来标定加速度计。前者贵后者对摆放精度要求极高稍有不慎姿态没放正标出来的参数反而更差。所以很多人标完发现怎么比不标还飘这篇文章要聊的就是那个在论文和工程社区里被反复验证过的、不需要任何外部设备、对摆放精度不敏感、实现起来又很友好的方法——多位置任意姿态静止标定法。它的核心思路很简单IMU静止时加速度计测量到的比力的大小理论上一定等于当地重力加速度。不管你怎么摆、摆成什么奇怪的角度这个约束永远成立。利用这个物理约束配合一批任意姿态下的静止观测数据就能用最小二乘把加速度计的零偏、尺度因子和轴间非正交误差一并解出来。陀螺仪的零偏也可以通过静止数据的均值直接估计。整个过程不需要转台、不需要水平仪、不需要任何外部基准只需要一个能采集数据的开发板或者机载电脑就能完成。这套方法做下来我实测过多次标定后的加速度计残差能压到0.001 g以内对大多数SLAM和组合导航场景已经非常够用。这篇文章适合谁如果你是做LIOLiDAR-Inertial Odometry、VIOVisual-Inertial Odometry、行人导航或者位姿解算的工程师或研究生正在为IMU数据质量发愁这篇文章可以给你一套完整可复现的标定流程从原理到代码到坑点全覆盖。哪怕你只是刚接触IMU的小白只要照着步骤走一遍也能拿到一份显著改善的数据。1. 为什么必须做IMU标定误差从哪来、不标的后果很多初学者会有一个错觉IMU芯片出厂前不是校准过的吗为什么拿到的数据还是不准这个问题我当年也困惑过。后来拆了几颗MEMS IMU的Datasheet才搞清楚芯片厂出厂时的“校准”其实只做了非常基础的电气校准和温度补偿真正决定传感器精度的机械安装误差、刻度非线性误差尤其是三轴之间的非正交误差通常不会在出厂时被充分修正。而且这些误差参数还会随温度、焊接应力、结构形变而改变你每次重新打板、重新装配i这些参数都要重新标。1.1 零偏、尺度因子和轴偏差三个绕不开的误差源把IMU的误差模型拆开看对纯惯性导航和融合定位影响最大的就三类零偏Bias、尺度因子Scale Factor和轴间非正交误差Misalignment。零偏最好理解就是IMU静止时输出并不归零而是有一个恒定的偏置。对加速度计来说这个偏置直接叠加在重力测量上会导致水平姿态角出现倾斜误差。对陀螺仪来说零偏更是致命因为角速度积分一次就是角度哪怕只有0.01 rad/s约0.57°/s的零偏100秒后姿态就偏了57度。这就是很多人做完纯积分位姿解算后发现角度疯狂漂移、尤其是yaw方向慢漂的头号原因——不是算法不对是陀螺零偏没标干净。尺度因子是测量值与真实值之间的比例关系误差。比如你真实转了1 rad/s传感器输出是0.98 rad/s那尺度因子就是0.98。这个误差源在加速度计上通常表现为三个轴各自不统一导致静止时合成矢量的大小虽然是g但方向会偏。在陀螺仪上则表现为转动量测偏大或偏小积分的总角度不对。轴间非正交误差是最容易被忽略、但影响非常大的一项。理论上IMU的三轴应该是两两正交的但实际封装和焊接过程中Z轴与XY平面的垂直度很难保证X和Y轴之间的直角也可能偏离90度。这个偏差会导致一个轴在旋转时会在另外两个轴上产生串扰信号比如你绕Z轴转X轴陀螺却读到了角速度分量。这种串扰在融合算法里很难被在线估计掉必须靠标定来补偿。1.2 不标定的实际危害轨迹畸形、外参失效、融合崩溃不标定就直接用最直观的后果是积分轨迹畸变。加速度计零偏会让速度持续累积即使静止状态速度也会随时间线性增长陀螺仪零偏会让姿态缓慢旋转导致后续所有坐标变换全部出错。做过纯IMU积分的人应该都有这种体验静止放置几秒钟位置就“飞”出去了姿态角也在慢慢旋转这就是所有误差源叠加的直观表现。更隐蔽的危害体现在多传感器融合系统里。比如做LiDAR-Inertial或者Camera-Inertial系统IMU内参零偏、尺度、轴偏差不准会直接影响IMU与外传感器之间的外参标定结果。很多人做相机IMU联合标定或者LiDAR-IMU外参标定时发现结果要么收敛很慢要么反复横跳最后查来查去问题出在IMU内参压根没标好。外参标定本质上是在估计两个传感器坐标系之间的变换如果IMU本身的观测数据就带系统误差那么等价于把一个不确定的变换也丢进了优化问题里整条链路都会被拉歪。所以我的建议一直很明确无论做什么上层算法IMU内参标定一定要放在最前面这属于“脏活累活”但绕不开而且一次标定做好后续能省下无数调试时间。2. 不靠外部设备的标定原理重力就是唯一的基准这个方法的魅力就在于它把复杂的标定问题变成了一个几乎零成本的数据拟合问题。不需要转台不需要光学平台不需要水平仪唯一依赖的物理基准就是重力。有人可能会问重力会不会因为经纬度和海拔不同而变化会但变化幅度极小。青岛的重力和西藏的重力也就差0.5%左右做标定这种精度需求直接取9.81 m/s² 或者用当地理论重力值都可以影响在可接受范围内。2.1 静止观测的物理本质加速度计测的是比力要理解这个标定方法首先得把一个概念搞明白加速度计在静止状态下测量的不是“加速度”而是比力Specific Force也就是支撑力产生的反作用力。放在桌面上静止时加速度计测量到的不是0而是向上的1 g。因为加速度计里的质量块被重力往下拉却被外壳的机械约束推着保持静止这个机械约束施加的力在加速度计坐标系里是竖直向上的。这意味着什么意味着当你把IMU以任意姿态静止放置时加速度计三轴输出的矢量和的大小模长严格等于当地重力加速度值。矢量方向随姿态变化但模长永远是g。这就是整个标定方法最核心的物理依据不管你怎么放只要静止输出矢量的模长不变恒等于g。这跟拿一把尺子去量物体一样重力就是一个“标准尺”。你的IMU姿态千变万化但尺子的长度永远不变。如果我们能测出大量不同姿态下加速度计的原始输出就能通过这些“长度恒定”的约束反推出加速度计三轴各自的零偏、尺度因子和轴间非正交角度。2.2 多位置法为什么能用最小二乘解参数把误差模型写成数学形式。设加速度计真实比力在IMU坐标系下投影为 a_true测量输出为 a_meas常用的线性误差模型可以写成a_meas S * K * (a_true b)展开写就是[ax_m] [sx mxy mxz] [ax_t bx] [ay_m] [myx sy myz] * [ay_t by] [az_m] [mzx mzy sz ] [az_t bz]其中 sx、sy、sz 是三个轴的尺度因子mxy 等六个参数表示轴间非正交耦合bx、by、bz 是零偏。我们做标定就是要估计出这九个参数。现在问题是我们不知道 a_true 的真实方向只知道它的模长是 g。所以把等式两边取模长平方就得到一个关于九个未知参数的约束方程|a_meas|² g²把误差模型代入这个约束展开之后是一个包含九个未知参数的非线性方程。针对每一个静止姿态我们采集一组 a_meas就能列出一个这样的方程。理论上9个方程就能解9个未知数但这里存在一个工程常识解非线性方程组的数值稳定性极差而且对初始值非常敏感。更稳妥的做法是采集几十组甚至上百组不同姿态下的静止数据把问题转化成一个最小二乘优化问题让所有姿态下的残差平方和最小。为什么这里能用最小二乘而不是更复杂的算法因为问题天然满足最小二乘的两个前提一是约束方程连续可导二是误差近似服从高斯分布且独立同分布。采集的数据量足够大时随机噪声会被平均掉系统误差则会被拟合出来。这也是这个“任意姿态法”比传统“六面法”更稳健的原因——六面法要求每个面都精准对齐水平/垂直摆放误差会直接带入解算而任意姿态法采集大量位姿单个身位的摆放误差只会贡献一个噪声样本对整体拟合结果几乎无影响。2.3 陀螺仪标定的边界能标什么、不能标什么这里必须泼一盆冷水标题说的“无需外部设备的鲁棒标定”主要针对的是加速度计内参和陀螺仪零偏。陀螺仪的尺度因子和轴间非正交误差靠静止多位置法是标不出来的。因为陀螺仪测量的是角速度静止时角速度恒为零只有地球自转分量约15°/小时这个量级对消费级MEMS陀螺来说完全淹没在噪声里根本无法作为基准。那陀螺仪的尺度因子和非正交误差怎么办在实际工程里有两种常见处理方式。一种是借助外部设备比如转台或者机械臂施加已知角速度激励通过对比输出反推参数。另一种就是依靠多传感器融合系统在线估计比如LIO和VIO系统在优化过程中通常会把陀螺仪零偏和尺度因子作为状态量的一部分随着系统运行不断更新。所以我的建议是如果你只做纯IMU航位推算至少要把零偏标干净这是投资回报率最高的一步。如果你做的是带有视觉或激光雷达的融合系统靠在线估计把其余参数慢慢学出来也是一种可行路径但内参标定作为初值仍然非常重要。3. 实操流程从数据采集到参数求解的完整步骤原理聊完了下面是实操部分。这一套流程我在多个IMU型号上都验证过包括MPU6050、ICM20602、BMI088、ADIS16470等流程基本通用只要你的IMU能输出原始加速度计三轴数据和陀螺仪三轴数据即可。3.1 数据采集的姿势设计和时长建议采集数据的核心要求是在足够多的不同姿态下每个姿态保持静止足够长的时间。具体做法是把IMU模组固定在手机、木板或者任何你觉得顺手的小平台上让平台可以自由放在桌上、墙上、斜面上。每摆放好一个姿态等待传感器读数稳定后连续采集5到10秒的数据建议至少3秒以上。然后换一个完全不同的姿态再采集5秒。如此反复采集30个以上不同姿态的数据。这里有几个关键细节要特别提醒。第一每个姿态之间最好尽量拉开差异比如绕三个轴旋转覆盖不同的俯仰、横滚、航向角组合尽量让加速度计三个轴的读数组合覆盖更大的球面区域。如果采集的姿态都集中在某个平面附近参数的条件数会比较差解出来的结果也不稳定。第二数据采集过程中务必确保设备真正静止如果采集时手还在抖、数据还在晃这些样本会直接影响拟合质量。建议每次换姿后停留1到2秒等晃动衰减后再开始采集。第三采集环境要避开明显的振动源比如不要放在运行的电机旁边不要放在桌子上有人在敲键盘的抖动环境中。按每个姿态10秒、30个姿态来算整个采集过程大约5到6分钟从工程角度来说完全不算负担。这比转台标定动辄几个小时的流程要轻量太多了。3.2 数据处理与参数求解附Python实现数据采集完成后先把每个静止段内的数据做平均处理得到一组代表该姿态的加速度计三轴测量值 a_meas。这一步能有效去除传感器的高频随机噪声。然后把所有姿态的平均值按行堆叠成一个矩阵进行参数求解。我自己常用的是Python NumPy直接写核心思路是用SciPy的优化工具做最小二乘拟合。下面这个代码可以直接拿来改改用。import numpy as np from scipy.optimize import least_squares # data: shape (N, 3)每一行是一个姿态下加速度计三轴平均输出单位 m/s^2 # G: 当地重力加速度值一般取 9.81 def imu_acc_calib(data, G9.81): n data.shape[0] # 初始化尺度默认1非正交耦合默认0零偏默认0 x0 np.array([1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]) def residual(x): sx, sy, sz, mxy, mxz, myx, myz, mzx, mzy x bx, by, bz x[6], x[7], x[8] # 补偿后的真实比力估计 a_pred np.zeros((n, 3)) a_pred[:, 0] (data[:, 0] - bx) / sx a_pred[:, 1] (data[:, 1] - by) / sy a_pred[:, 2] (data[:, 2] - bz) / sz # 模型里把非正交耦合近似为小角度旋转补偿 # 这里采用简化模型非正交项作为交叉轴比例耦合 a_real np.zeros((n, 3)) a_real[:, 0] a_pred[:, 0] mxy * a_pred[:, 1] mxz * a_pred[:, 2] a_real[:, 1] myx * a_pred[:, 0] a_pred[:, 1] myz * a_pred[:, 2] a_real[:, 2] mzx * a_pred[:, 0] mzy * a_pred[:, 1] a_pred[:, 2] # 约束模长等于 G return np.linalg.norm(a_real, axis1) - G res least_squares(residual, x0, methodlm) return res.x # 使用示例 # x imu_acc_calib(acc_data) # sx, sy, sz, mxy, mxz, myx, myz, mzx, mzy, bx, by, bz ...这个实现里我用了简化模型把非正交耦合表达为交叉轴的比例项好处是初值好给、收敛快、代码短。真正严格的误差模型应该用旋转矩阵表示非正交性但工程上这两种表达在小角度假设下结果差异极小完全够用。陀螺仪零偏的估计就更简单了。同样利用静止段数据但取的是陀螺仪三轴输出的平均值即bias_gyro mean(gyro_data, axis0)也就是把所有静止段的陀螺仪原始角速度输出求平均。这个平均结果就是陀螺仪的常值零偏估计。静止时间越长、累积的姿态越多平均下来零偏估计越精确。3.3 标定结果验证残差分析和重复性测试参数解出来了很多人就直接用了这其实是个坑。标定结果必须经过验证否则参数收敛到局部最优而你毫不知情直接跑上层系统的时候才会发现问题那时候排查成本就高了。第一个验证指标是拟合残差。把标定后的参数代回误差模型反算出每个姿态下补偿后的比力矢量的模长算一下与G的差值。如果平均残差在0.001 g到0.005 g这个量级说明模型拟合得不错。如果残差到0.05 g甚至更高说明采集数据里有异常姿态或者模型本身不适配需要重新采集。第二个验证指标是重复性测试。把IMU重新摆放姿态采集一组和标定时完全不同的静止数据用刚才标定的参数做补偿看看补偿后的模长与G的偏差。如果前一组残差很小、这组测试数据却很拉胯说明标定过拟合了通常是因为采集姿态分布不够广或者采集数据量太少。再一个非常实用的验证方式是直接观察静止时IMU经过标定补偿后的输出稳定性。把IMU放平采集补偿后的加速度计三轴数据和陀螺仪三轴数据观察一段时间好的标定结果会让加速度计X/Y轴读数趋近0、Z轴读数趋近G陀螺仪三轴读数趋近0且波动很小。这一条每个人都能直观感受不需要任何额外工具。4. 常见问题与排查技巧实录标定流程本身不复杂但我在实际使用中确实踩过不少坑也在各种社区交流群里看到过不少同行踩坑后一头雾水。下面这些问题是我遇到过的或者被问过很多次的统一整理出来希望能帮你少走弯路。4.1 标定后yaw依然缓慢漂移是正常现象这个问题在标题相关热词里出现了说明很多人标完IMU之后发现yaw还是慢慢在飘于是怀疑标定流程有问题。但我必须说清楚这是正常现象别慌。yaw方向的持续慢漂本质上是航向角不可观导致的。在没有外部参考的情况下纯IMU的yaw只能靠陀螺仪积分获得陀螺仪的零偏确实会被标定掉大部分但残留下来的零偏残差和随机游走依然存在积分到一定时间就会导致yaw漂移。这不是标定能解决的是纯惯性导航的通病。可以说哪怕你用了转台把陀螺仪尺度因子标得再精准纯积分250秒后yaw照样漂只是漂多漂少的问题。解决yaw漂移的正确思路是引入外部观测约束比如磁力计、视觉、激光点云匹配或者GPS航向。这也解释了为什么LiDAR-IMU、Camera-IMU这套组合在业界会这么流行——它们本质上就是在用外部传感器持续修正IMU的积分漂移其中yaw方向的修正尤为关键。如果你在做纯IMU位姿解算建议先降低对yaw精度的预期把精力放在短期姿态稳定性和高频响应的优化上。4.2 重力对齐、外参标定和IMU内参标定的执行顺序“IMU重力对齐”是热词里另一个高频出现的概念。很多人会把重力对齐和内参标定混为一谈其实这是两件事。重力对齐Gravity Alignment通常指在系统启动阶段通过加速度计静止时的输出来估计当前姿态相对于重力方向的初始横滚角和俯仰角也就是常说的“初始姿态对准”。它依赖的是加速度计的测量精度所以内参标定的结果会直接影响初始姿态对齐的精度。可以说内参标定是重力对齐的前提。还有一个执行顺序问题值得提醒。如果你要做LiDAR-IMU或者Camera-IMU联合标定一定先做IMU内参标定再做外参标定。外参标定过程中IMU的观测数据会被反复用于构建约束方程如果内参含系统性误差外参优化就相当于在输入端掺了噪声结果往往是外参收敛了但精度很差。更麻烦的是这种误差很难从外参结果里直接看出来因为优化残留也被吸收进了外参里。我自己就吃过这个亏联合标定结果反复验证都对不上最后回头重标IMU内参问题立刻解决。4.3 温漂、振动和采样率三个容易翻车的细节温漂是所有MEMS传感器都绕不开的话题。IMU零偏随时间、温度漂移这个特性决定了“一次标定、终身使用”在严苛环境下不成立。如果你的设备经常在温差很大的环境中使用比如从室内冷空调环境拿到室外暴晒环境建议做一次“快速温度标定”在不同温度节点下各静止采集一段数据看陀螺零偏的变化幅度。如果变化明显可以考虑在算法里加入温度补偿项或者至少在系统热稳定后再执行初始对准。振动是另一个容易翻车的点。多位置法要求静止但“静止”的判断标准是什么我的经验是看陀螺仪输出方差。电磁屏蔽不好的IMU放置在电机旁边静止时陀螺仪输出可能依然有较大抖动这种环境下采集的数据质量很差。判断方法很简单在数据采集脚本里实时打印陀螺仪三轴的方差如果某个姿态下方差明显偏大就换一个位置重新采集。采样率这件事看着不起眼实际影响也不小。IMU数据采集尽量使用高频模式比如400 Hz到1000 Hz然后在静止段内取平均这比低频采集能更好地抑制随机噪声。但要注意采集过程中IMU的姿态必须严格不变如果稍微有微小的移动高频数据反而会把细微的角运动也采集进来。所以严谨的流程是确认静止——采集高频原始数据——对静止段做时域平均得到一个样本。这个小流程很多人嫌麻烦直接省了结果标定效果大打折扣。最后再分享一个小技巧。如果你标定完发现残差始终偏大先别急着怀疑算法检查一下数据里是不是混入了“切换姿态过程中”的过渡数据。我的做法是每个姿态的数据采集之前加一个自动检测逻辑用滑动窗口计算加速度计输出的方差连续若干ms方差稳定小于阈值才启动采集这样能彻底避开手持切换姿态时的晃动段。这个细节在自动化采集脚本里尤其重要能帮你省掉大量人工筛选数据的力气。IMU内参标定这件事做得好的人可能觉得不值一提但真的能踏踏实实把误差模型讲清楚、把数据采集流程走完整、把结果验证做到位的人其实不多。希望这一篇能让你在标定这条路上少走弯路。
阅读完成 · 觉得有帮助?
咨询建站