做视觉惯性里程计VIO或者激光惯性里程计LIO的朋友大多有过这种体验算法照着论文复现好了数据集跑起来效果也不错可一换到自己采集的数据上轨迹就开始放飞自我。最初我以为是参数调得不对反复折腾了快一周直到把IMU标定这件事从头到尾做了一遍才明白问题根源大都在传感器本身。所谓IMU标定听起来好像是一个步骤实际上它分两个维度一是标IMU自身的内功即惯性测量单元的零偏、尺度因子、轴间误差这些内参二是标IMU与相机、激光雷达等其他传感器之间的配合即外参联合标定。这两件事解决的是完全不同的问题但很多人一开始根本分不清上来就做联合标定结果内参本身是歪的后面怎么努力都白搭。这篇文章我打算把这两种标定方式的原理、实操链路和避坑点完整展开按照一个从底层到上层的顺序来讲先把IMU的误差模型说清楚然后讲内参标定怎么用Allan方差法做透再讲外参联合标定怎么用Kalibr这类工具做通最后聊聊在实际产品项目里什么时候做哪种、先做哪个后做哪个以及频率上怎么安排最合理。1. 先分清标什么IMU误差模型与两类标定的边界1.1 加速度计和陀螺仪到底在测什么IMU全称是惯性测量单元核心器件就两个加速度计和陀螺仪。加速度计测的是比力也就是物体在惯性空间中的加速度减去重力加速度之后的那部分陀螺仪测的是载体相对惯性空间的角速度。这句看似废话实际上很多问题都出在这上面。比如加速度计静止放在桌面上时读数不是0而是大概9.8m/s²向上的值因为此时比力等于负的重力矢量。如果你把这个原始值直接积分算位置不扣除重力那速度会疯狂往上偏。这就是为什么IMU相关算法里必须有个重力对齐步骤本质上就是对初始姿态或重力方向做估计。陀螺仪的输出也有讲究。MEMS陀螺仪测的是角速度单位通常是rad/s或deg/s但你要明白它测的是哪个坐标系下的角速度。理想情况下陀螺仪的三个轴是严格正交的和加速度计的三个轴也完全对齐但实际上受MEMS加工工艺和封装应力的影响轴与轴之间总会有小角度偏差。这些偏差在高精度应用里是致命的。1.2 内参与外参两个完全不同维度的标定很多刚接触这个领域的人会被标定这个词搞晕因为同一个词在不同语境下意思差得很远。内参标定对象是IMU自身。它回答的问题是这个IMU测出来的数据准不准、偏多少、各轴之间歪了多少。需要估计的量包括加速度计和陀螺仪的零偏bias静态或运动时传感器输出中不随物理量变化的那部分偏移。尺度因子scale factor实际物理量与传感器输出之间的比例关系偏差通常接近1但不会恰好是1。轴间非正交误差axis misalignment三个测量轴不是严格90°正交的微小偏差。噪声密度和随机游走参数描述高频白噪声和低频漂移特性的统计参数。外参联合标定对象是IMU和另一个传感器之间的关系。它回答的问题是这两个传感器的坐标系之间差了多少旋转和平移以及它们的时间戳之间差了多少偏移time offset。在视觉惯性系统里就是相机坐标系到IMU坐标系的变换矩阵T_cam_imu在激光惯性系统里就是雷达坐标系到IMU坐标系的变换T_lidar_imu。用一个生活化的类比内参标定是看一个人自己走路准不准、步伐多大外参标定是确定这个人手里拿的枪和眼睛之间的相对位置关系。前者决定了测量本身的可信度后者决定了多传感器数据能不能对齐融合。两类标定解决的是不同层次的问题但它们之间有一个隐含依赖外参标定的质量会被内参误差直接影响。如果陀螺仪零偏没标准运动过程中的姿态积分就会持续累积误差那么用来估计相机和IMU相对旋转的数据本身就是有毒的就算优化算法再强也不一定能收敛到正确的外参上。2. 方式一内参标定——把IMU的出厂脾气摸清楚2.1 为什么出厂数据不能直接信如果你买的IMU模块厂商给了一份手册上面写了零偏、噪声密度等参数你是不是就以为可以直接用了我最早也是这样想的结果被现实狠狠教育了一课。手册上的参数通常是这颗芯片型号的典型值是从同型号芯片抽样测试得到的统计平均不是你手里这颗芯片的真实个体值。更关键的是IMU测量芯片贴到PCB板上之后焊接应力和结构应力会让零偏和轴间误差偏离出厂状态而且偏离方向和大小是不可预测的——同一批板子每颗的脾气都不一样。温度变化更是影响巨大许多MEMS器件的零偏会随温度成非线性漂移冬天和夏天的差异可能达到十几倍。所以如果你的系统对精度有要求内参标定必须做而且要针对每一颗实际使用的IMU来做拿一组标定参数套全部设备是行不通的。2.2 静态采集与Allan方差法的完整链路内参标定里最实用、也是目前业界用得最多的方法是Allan方差法。它最早是David Allan在1966年研究原子钟频率稳定度的时候提出的一种时域分析方法后来被引入到惯性传感器领域用来分离和辨识IMU测量数据里的各类随机误差成分。Allan方差法的思路很有意思采集一段长时间的静态数据也就是IMU静止不动时的输出然后把这段数据按不同时间长度切成若干块对每块求平均再计算相邻块平均值之差的方差。把这段方差和积分时间的关系画成双对数曲线会让不同噪声成分在不同时间尺度上显现出来斜率为-1的段对应量化噪声斜率为-0.5的段对应角度随机游走陀螺或速度随机游走加计斜率为0水平段对应零偏不稳定性斜率为0.5的段对应速率随机游走斜率为1的段对应速率斜坡这套方法不需要转台不需要外部参考只需要让IMU静止足够长时间在数据分析上把不同随机过程的特征剥离出来特别适合工程项目快速摸底。实际操作上我比较推荐用ethz-ASL开源的imu_utils这个工具。它的工作流非常成熟搭建好ROS环境比如Ubuntu 18.04 Melodic或Ubuntu 20.04 Noetic把IMU驱动跑起来发布包含线加速度和角速度的imu话题。把IMU固定在一个不受振动干扰的水平平台上保持静止用rosbag录制imu话题数据。录制时长建议陀螺仪不少于2小时、加速度计不少于1小时。说实话2小时看着久但这是为了让低频率段的随机游走特征充分暴露出来时间短了曲线低频段根本没数据可用。录完bag后用imu_utils里的launch文件和脚本对bag进行离线处理它会通过Allan方差计算并拟合成参数文件。检查输出结果重点看零偏不稳定性bias instability和角度/速度随机游走这几项。如果曲线拟合得比较干净和理论斜率符合得好说明数据质量没问题如果曲线乱成一片大概率是采集过程中有振动、温度波动或者IMU固定不稳。写代码用的时候把标定得到的零偏和随机游走参数填进系统初始值里。尤其是零偏在估计器初始化阶段如果能给出一个可靠初值收敛速度会快非常多而且不容易陷进局部极小。2.3 除了Allan方差内参还能怎么标Allan方差法虽然好用但它主要是从统计特性上辨识随机误差对于尺度因子和轴间非正交误差的分辨力比较弱。要标这两个量工程上更常用的是多位置静态法和转台法。多位置静态法的本质是利用重力矢量作为参考基准。把IMU按不同的姿态摆放理论上不管怎么摆加速度计感受到的重力矢量模长应该恒为9.8m/s²左右。通过设计一组覆盖不同朝向的姿态序列让每个轴都能经历正负重力分量就能反解出加速度计的零偏、尺度因子和轴间安装误差。实际操作中可以使用一个简单的三轴手动转台按特定的姿态表比如六个面朝上、十二姿态法依次摆放每个位置静止采集30到60秒数据取平均。转台法就更直接了高精度转台可以提供精确的角速度和角位置让陀螺仪在已知角速度下旋转拿输出和已知值做对比直接解算零偏和尺度因子。这个方法精度最高但它依赖转台设备本身成本不是一般项目能承受的。大多数创业公司和中小项目采用Allan方差加多位置法已经足够把IMU内参校准到可用的水平。我在实际项目中遇到过一个典型案例一台轮式机器人用的低端MEMS IMU刚上电时零偏估计大概在0.5 deg/s做Allan方差标定后校准到0.01 deg/s级别。别小看这个差距静止时陀螺零偏0.5 deg/s意味着姿态误差每分钟就积累30度这直接决定了航迹推算能用3分钟还是能用30分钟。3. 方式二外参联合标定——Kalibr把相机和IMU对齐3.1 为什么VIO必须做外参标定视觉惯性里程计的基本思路是把相机的视觉观测和IMU的惯性测量都丢进一个状态估计器里做融合。如果相机坐标系和IMU坐标系之间的旋转和平移是错的那么视觉特征点的投影残差和IMU预积分残差之间会存在系统性矛盾。具体表现就是静态下一切正常一运动轨迹就扭曲或者尺度漂移严重。时间偏移问题也一样。相机曝光时刻和IMU采样时刻之间如果有一个固定的延迟视觉信息和惯性信息在时间上就会错位等效于给外参引入了一个随运动速度变化的误差。这也是为什么Kalibr这类工具会把时间偏移也当作待估计参数。外参标定的价值我还想强调一点有了准确的外参系统初始化阶段的IMU陀螺零偏和重力方向估计会可靠得多。很多时候VIO系统初始化失败不是算法不能用而是外参给的太离谱导致优化问题一开始就发散了。3.2 Kalibr联合标定的完整流程Kalibr是苏黎世联邦理工ETH Zurich的自动驾驶实验室开源的相机-IMU联合标定工具也是目前社区里最主流的方案。它的基本思路是让IMU和相机固定连接在一起在一个标定板前做一组丰富而充分的运动同时采集标定板图像和IMU数据之后构建一个同时优化相机内参、IMU内参、相机-IMU外参和重力方向以及时间偏移的非线性优化问题。对应到操作上有这么几个关键步骤第一步是准备标定板。Kalibr官方推荐使用Aprilgrid就是那种黑白棋盘格加上每个格子内嵌二进制编码的靶标。和普通棋盘格相比Aprilgrid有一个巨大优势即使图像中只看到一部分格子也能通过编码信息推算出相机相对靶标的位置这对运动过程中标定板部分出画的情况非常友好。标定板的尺寸信息要精确量好填进target yaml文件里一个像素的尺寸误差最终都会变成外参的误差。第二步是标定相机内参。这一步可以用Kalibr自带的相机标定模块也可以用OpenCV或Matlab。需要强调的是联合标定结果对相机内参的准确度极其敏感所以这一步不能糊弄多采几组不同距离、不同角度的图像确保标定板覆盖整个视野。我通常的做法是先用Kalibr标一遍再做一次重投影误差检查如果误差大于0.5像素就得重新采。第三步是录制联合标定的bag包。这是整个流程里最考验手感的一步。理想的数据集要求标定板固定不动人手持IMU相机组合在板前做各种位姿的运动。运动不能只有一个方向。要包含绕X/Y/Z三个轴的旋转以及各个方向的平移让IMU的六个自由度都被充分激励起来。速度要有变化。快慢结合既有缓慢接近标定板的精细运动也有快速旋转和甩动。时长一般1到3分钟就够了太长反而容易让优化变量过多、收敛变慢。整个过程要保证标定板始终在相机视野内有足够多的有效帧光线要均匀不能过曝或反光严重。第四步是写配置文件。需要准备一个imu yaml文件把IMU的更新频率写进去如果之前做过内参标定可以把Allan方差得到的噪声密度和随机游走参数填进去这能给优化提供一个更好的初值。相机模型参数从相机标定结果里拷贝过来。第五步是运行联合标定命令。Kalibr会输出外参变换矩阵同时生成一个可视化的残差报告。拿到结果后不要急着用先看两个关键指标一是重投影残差和IMU残差是否收敛到比较小的水平二是外参结果是否和物理安装的直觉相符。比如你明明是把相机装在IMU的正上方约5厘米处结果标定出来平移量的Z分量是十几厘米那一定哪里出了问题多半是数据激励不足或者时间戳对不齐。一个非常常见的坑是IMU话题的时间戳存在跳变或时基不同步。ROS环境下多传感器时间同步一般靠同样的系统时钟但如果你用的是多台机器或者嵌入式处理器就需要先用chrony或ptp做时间同步再录数据。否则标出来的时间偏移参数会是一个不停漂移的无效值。3.3 外参标定的另一个路线手眼标定Kalibr是优化的思路还有另一个经典思路是手眼标定也就是解AXXB问题。早期做相机-IMU外参标定的时候很多研究用的是这个方式通过相机观测标定板估计相机自身的运动A通过IMU积分估计IMU自身的运动B既然两者固定连接那么A和B之间存在一个共轭变换关系X求解X就是标定外参。手眼标定的好处是实现简单不需要复杂的联合优化理解和调试比较直观。但它有个明显缺陷它分两步走先把各自的运动估出来再求X前一步的误差会全部传进后一步而且它通常不估计时间偏移。我的建议是如果你的相机和IMU已经各自做过良好标定且时间同步有保障那用手眼标定快速求一个外参初值是可以的但想要更稳定、更准确的结果还是走Kalibr这类联合优化路线更省心。实际上很多VIO框架只是需要一个外参初值做初始化后续会把外参放进状态向量里持续在线优化这种情况下手眼标定的结果也够用了。4. 两种标定的分工与实战选型4.1 内参和外参的依赖关系与使用场景说到选型核心是先搞清楚你手里这个系统的瓶颈在哪。我见过太多团队用了很贵的工业相机和高性能IMU结果系统表现还不如别人家几千块的方案原因往往就是标定链路没做全。如果你的场景只需要IMU自己出数据比如轮式机器人的航迹推算、云台的姿态稳定、或者汽车上的倾斜报警那你只需要做内参标定。尤其是航迹推算这类纯积分应用零偏直接决定发散速度内参标定几乎没有商量的余地。反过来如果你采购的是高精度光纤陀螺或激光陀螺级别的IMU出厂内参本来就足够可靠也不打算在温度剧烈变化的环境下工作那内参标定可以省略直接做外参联合标定就好。做VIO/LIO系统的话我的建议是先内后外。先把内参标定做了把零偏初值和噪声参数填进系统再去做相机-IMU或雷达-IMU联合标定。这样会少踩很多坑比如联合标定结果反复不稳定、外参收敛到明显不合理的值、时间偏移估计乱飘之类的问题很多都是内参初值太差导致的。4.2 标定频率与复现策略很多人以为标定是一次性的工作标完就一劳永逸了。实际上IMU内参会随着时间、温度、机械振动甚至PCB板老化而缓慢变化属于需要周期维护的参数。针对量产设备和长期稳定运行的设备我有几条很实际的建议第一量产产品建议逐台标定。因为每个IMU个体差异就摆在那里同批次芯片之间的零偏离散度不可忽略。逐台标定的成本看起来高但这可以在产线上用一个简单的静态标定治具让设备在固定模式下静止十几分钟自动采集数据、自动跑Allan方差流程、自动把参数写进设备存储区。第二温度变化大的应用场景最好做温补标定。可以把IMU放进温箱里从-20℃到60℃扫一遍记录各个温度点的零偏值拟合出一条补偿曲线。不做这一步的代价就是系统环境温度一变零偏也就变了之前标定的效果直接打折。第三外参标定的频次取决于机械结构是否稳定。相机和IMU如果是用螺丝刚性锁死在一个金属结构件上的只要没有磕碰导致形变标定一次可以用很久。但如果结构里有可调节的部件比如云台上会转动的部分那每次调整后都要重新标。工业相机上拧镜头这种事都可能会导致外参变化因为镜头的光轴和像面关系变了等效于相机坐标系整体偏移了。我在维护一个自主巡检机器人项目时就吃过一次亏现场的工程师拆装过相机模块之后忘记重新标定外参结果视觉定位在转弯时开始大幅抖动。排查了很久最后用Kalibr重新跑了一次标定问题随即消失。现在我把外参标定写进了设备维护SOP里凡是涉及传感器拆卸、替换的维护操作都必须重新执行一次联合标定。还有一个小技巧标定完的配置文件一定要纳入版本管理并且要记录标定时的环境信息、硬件SN、日期和标定人员。尤其是多台设备并行工作的时候没有这个记录出了问题你根本不知道哪台设备用的是哪份外参排查成本会成倍上升。踩过几次坑之后给新手的实操清单最后再分享一点个人体会吧踩过几次坑之后我总结了一套每次梳理传感器系统必做的清单拿到新IMU芯片先做一次On-board校准确保供电稳定周围没有强磁场干扰因为有些IMU内部磁力计虽然没有参与姿态解算但PCB走线异常还是会影响ADC精度。做内参标定时IMU一定要放在减振平台上别直接放在桌上录数据桌面马达或空调风机的微振动都会污染Allan方差曲线低频段。录制联合标定数据之前检查所有话题的时间戳来源是否同一时钟。时间同步一旦失真后面所有标定全是做无用功。Kalibr标定出来的外参务必用真实物理安装尺寸做一次合理性检查。别急着接管线先看旋转矩阵和平移向量和你的安装方式是否一致。不管是内参还是外参标定结果都要在系统的在线估计器里保留持续优化的能力。传感器在工作过程中会受温度、振动影响标定参数是初值不是最终答案。IMU标定这件事本质上是让系统里的每个传感器都说实话然后让它们彼此知道谁在谁旁边。内参就是传感器自己说实话的能力外参就是相互之间的位置关系。这两件事做到位了后续的融合算法才能真正发挥价值。如果时间有限只做一件事我建议先把内参标定做了因为它是地基中的地基。