
简介imu-utils是面向机器人导航、自动驾驶、飞行控制及虚拟现实等场景的IMU标定工具包针对加速度计、陀螺仪等传感器实现偏差、尺度因子、非正交性误差校正旨在提升惯性数据的测量精度是搭建高精度定位与姿态解算系统中的重要一环。资源共235个文件压缩包仅4.32MB文件类型涵盖114个txt文本、20个h头文件、13个cpp源码、7个yaml/launch配置、7个m脚本等txt多为说明与数据文件h/cpp构成算法主体yaml/launch便于调整参数与启动节点。工具内置Allan方差分析等标定流程目录结构细分为code_utils和imu_utils两大模块并修复了错误引用稳定性更好开发者还可按硬件环境自定义标定流程便于二次开发。已有431人学习下载适合有一定传感器基础的机器人、SLAM方向开发者对照源码研习标定原理并快速集成到自己的项目中。 大家跑VINS-Mono或者VINS-Fusion的时候有没有遇到过这种诡异的情况代码按教程一步步搭好了数据集也跑得挺顺结果换到自己的传感器上初始化特别慢或者飞一会儿轨迹就开始飘甚至直接发散。很多人第一反应是调VINS的参数把process noise、imu_rate翻来覆去改一遍发现没啥用。我当初也卡在这个坑里好几天最后才意识到问题出在IMU本身的噪声参数上——你用的imu.yaml还是人家数据集里默认的那份跟你的传感器根本不是一回事。imu-utils就是干这个的。它是港科大秦通开源的一套IMU标定工具专门用来估计陀螺仪和加速度计的噪声密度noise density和随机游走random walk输出一份和你硬件匹配的imu.yaml。这套工具配合Allan方差法能帮你把手里的IMU底摸清楚。这篇文章我会从工具边界、编译坑、数据采集、原理、结果落地这几个角度把整套流程从头到尾捋一遍包括我在实际使用中踩过的坑和验证过的经验希望对正在折腾IMU标定的朋友有帮助。1. 为什么跑VINS总觉得飘imu-utils要解决的是哪个环节在动手装工具之前先搞清楚imu-utils的定位这点非常关键。很多人以为用imu-utils标定完IMU的所有误差都解决了其实不是。IMU的误差来源分好几层。第一层是零偏bias也就是静止时传感器读数不为零这个可以用静态平均值粗标VINS在初始化阶段也会在线估计。第二层是尺度因子和安装误差这是加速度计三个轴不正交、刻度不准造成的这类参数imu-utils不处理通常要用imu_tk或者Kalibr做六面标定。第三层才是噪声特性包括角度随机游走对应噪声密度和速率随机游走对应随机游走/bias instabilityimu-utils干的就是这个而且它只输出这两个核心参数。用VINS这类视觉惯性里程计算法时状态方程里的IMU积分模型会把噪声密度和随机游走作为过程噪声协方差的输入。如果你的IMU标称噪声是0.03 deg/sqrt(hr)但imu.yaml里给的还是别人传感器0.01的值滤波器就会过于信任IMU积分当视觉观测不稳定时位置估计会迅速发散。反过来噪声给大了IMU的权重又被压低初始化需要更长时间动态响应也变迟钝。所以这一步不是可做可不做的流程性工作它是影响系统性能的上游环节。我见过有朋友直接拿官方imu_utils仓库里自带的示例文件或者从网上下一个别人标定好的配置套在自己的传感器上跑。如果你的IMU型号恰好一样问题不大但绝大多数情况下硬件批次、焊接质量、温度特性都不一样最稳妥的做法是每块板子单独标定一次。尤其做无人车、无人机这种对定位连续性要求很高的项目IMU噪声参数错一个数量级后期排查问题会非常痛苦。2. 编译安装的隐藏门槛依赖版本、编译顺序和ROS发行版imu-utils本身是ROS功能包编译过程不复杂但有几个前置条件容易卡人。整个工具包含两个仓库code_utils和imu_utils。code_utils是基础工具库imu_utils依赖它所以必须先编译code_utils再编译imu_utils顺序不能反否则rosdep找不到依赖包。我第一次装的时候就是先clone了imu_utilscatkin_make直接报错找不到code_utils后来才注意到README上特别标注了依赖顺序。如果你用wstool一次性拉取两个包编译时最好分开build或者干脆先只build code_utils成功后再一起build。环境方面我在Ubuntu 18.04 ROS Melodic和Ubuntu 20.04 ROS Noetic上都编译过。Melodic没问题Noetic下需要确认ceres-solver版本。imu-utils的CMakeLists里用的ceres版本比较老如果你系统装的是ceres 2.x编译会报API不匹配的错误。两个解决办法装ceres 1.14.0版本或者修改CMakeLists把ceres相关依赖降到最低。ceres 1.14在Ubuntu 20.04上可以用源码编译几分钟就够不用纠结版本问题。另外还需要eigen、libdw-dev这些基础库记得提前装好sudo apt-get install libdw-dev libeigen3-dev编译命令有一套统一的流程cd your_ws/src git clone https://github.com/gaowenliang/code_utils.git git clone https://github.com/gaowenliang/imu_utils.git cd .. catkin_make这里有个细节如果你之前建过多个工作空间source顺序会影响ROS包发现。建议一个人单独为imu-utils建workspace避免和别人已有的功能包冲突。还有如果你的主工作空间用的是catkin build比如你同时编译PX4固件那这个工具用catkin_make编译就行生成的devel目录source一下功能包依然能被主空间发现不必强行统一构建工具。编译完成后用rospack find imu_utils确认一下能不能找到能找出来就说明环境没问题。接下来才进入数据采集环节这也是整个标定流程中我觉得最考验耐心的一步。3. 数据采集决定成败静止两小时背后的物理逻辑imu-utils的标定原理是Allan方差分析它要求输入一段足够长的静止IMU数据。注意关键词是足够长——官方建议至少两个小时这个时间不是拍脑袋定的后面解释原理的时候你会明白为什么短数据标出来根本没法用。数据采集姿势很简单把设备放在一个稳定、无振动、温度相对恒定的台面上保持静止录制IMU的topic录够一到两个小时。我用的是自己组的一块带BMI088的开发板放在泡沫垫上周围不要放风扇、不要有人走动。理论上越静越好但也不用做到减震台那么夸张正常的桌面环境足够。录制命令和普通rosbag一致rosbag record /imu/data -O imu_static.bag这里有个经验点在启动录制之前先把传感器通电预热几分钟等温度稳定再开始录。IMU的噪声特性和温度强相关冷启动那几分钟的数据和后面稳定状态的数据混在一起会让Allan方差曲线在长相关时间区域出现异常拐点。我对比过冷启动直接录和预热五分钟后录的两份数据前者的bias instability估计值明显偏大而且曲线在100秒以后的区域抖动得很厉害。录制的时长直接决定可用性。如果只录二十分钟Allan方差曲线在长相关时间区域没有足够的数据支撑随机游走那一项根本拟合不出来。官方建议两小时实际操作中一小时起步、两小时最稳。如果时间紧张至少要保证一小时以上而且采样频率要尽量高我习惯设置成200Hz这样时间序列的点数足够多方差计算的结果也平滑。还有一个坑容易被忽略录制时不要只录IMU数据建议把相机曝光时间、系统时间戳一起记录下来。因为后续你还需要把IMU时间戳和视觉时间戳对齐时间戳跳变、回跳会导致Allan方差里出现虚假的周期误差。我遇到过一块GPS授时模块偶尔会给系统时间做微调导致rosbag里出现两次时间跳跃标定出来的噪声密度偏大检查了半天才发现是时间戳问题。所以录制前最好用chrony或者ntp把系统时间同步好录制过程中不要手动调整时间。4. Allan方差的直观理解与标定结果解读Allan方差这个名词听起来很数学但它的思想其实很直观。假设你有一段很长的静止IMU数据按不同的积分时间T把整段数据切片每个切片算一个平均值然后比较相邻两个切片的平均值差异。当T很小时差异主要由高频噪声决定当T很大时差异主要反映传感器的低频漂移特性。把T从小到大变化画出横轴是T、纵轴是方差的对数曲线这条曲线就能把不同时间尺度上的噪声来源分离出来。为什么需要两小时的数据因为在Allan方差曲线上如果要看到长相关时间区域比如100秒到1000秒的斜率特征数据长度至少要达到积分时间的几十倍。你想看1000秒处的方差数据至少得有个几小时才够统计意义。这也是很多人拿十分钟数据标出来的结果没法用的原因——短数据给不出长相关时间的方差估计拟合出的随机游走纯属硬凑。imu-utils跑完后在输出目录里会生成几个文件核心的是imu.yaml。里面的结构大概是# 陀螺仪 gyro: noise_density: 0.00012345 # rad/s/sqrt(Hz) random_walk: 0.00000321 # rad/s^2/sqrt(Hz) # 加速度计 accel: noise_density: 0.00123456 # m/s^2/sqrt(Hz) random_walk: 0.00001567 # m/s^3/sqrt(Hz)注意单位。陀螺仪的noise_density单位是rad/s/sqrt(Hz)random_walk单位是rad/s^2/sqrt(Hz)。加速度计对应的是m/s^2/sqrt(Hz)和m/s^3/sqrt(Hz)。VINS的配置模板里通常是deg/sqrt(hr)和deg/hr/sqrt(hr)这种单位直接拷贝数值会错一个量级后面第5章细说。除了yaml工具还会画Allan方差曲线图PDF和PNG格式都有。你会看到一条拟合曲线和几个关键点的标注比如bias instability最优点。看曲线的时候有个实操技巧正常结果的对数曲线应该是平滑的对勾形状左边斜率为-0.5角度随机游走主导右边斜率为0.5速率随机游走主导中间凹底大约落在几十秒到几百秒之间。如果你的曲线在中间出现了明显的台阶或者突变说明数据里有周期性干扰比如电机振动、空调气流或者周围有人走动。重新采集往往比硬调数据更省时间。5. 从imu.yaml到VINS参数落地与三个常见误区拿到imu.yaml不代表标定完成把它正确用进SLAM系统才是最后一步。这里面最容易出问题的三个地方我一个个说。误区一单位换算。刚才提到imu-utils输出的噪声密度是rad/s/sqrt(Hz)这个国际标准单位。VINS-Mono的配置模板里imu noise参数通常写成0.010.02这种数值看起来像个经验值。实际上VINS内部对单位有注释说明但代码版本不同注释写的单位也可能有出入。我建议你把imu-utils输出的值按国际单位直接用然后去vins_estimator的nodelet或者estimator节点里核对一遍单位注释。比如IMU噪声的实际物理意义是角度随机游走典型手持模块在0.01到0.05 deg/sqrt(hr)之间换算成rad/s/sqrt(Hz)大概是0.00015到0.0007这个范围。如果你算出来是0.000001这种数量级那基本是数据采集时传感器并没有完全静止或者时间戳有问题。误区二只改噪声不改随机游走。很多人的做法是把noise_density填进VINS配置然后random_walk保留原值。实际上这两个参数在IMU积分协方差里各管一段噪声密度影响短时间积分的不确定性增长速度随机游走影响长时间积分时候的漂移。VINS初始化阶段对陀螺仪bias估计用的主要是随机游走这个值给得不准bias估计会偏慢甚至不收敛。正确做法是两个都填上而且填之前确认单位。误区三标定一次用一辈子。IMU的噪声特性会随温度、供电电压、机械结构变化而变化。如果你的设备经常在户外日晒环境下工作最好做一次高温和常温和低温的对比标定至少心里有数。之前做一款户外巡检小车冬天和夏天标定结果差了一倍多后来在程序里加了两套参数的温度切换才把定位稳定性补回来。如果你不改程序那至少每隔几个月或者传感器经历剧烈温度变化后重新标一次。还有个小建议标定结果不要做完就扔。把imu.yaml、Allan曲线图、录制时间、温度环境、传感器型号批次这些信息一起归档。以后换一批板子或者怀疑参数有问题要复标的时候有基线数据对比会舒服很多。我现在的标准流程是新板子到手先预热、录两小时静止数据、跑一次imu-utils、看一眼Allan曲线是否正常然后才写进VINS配置跑数据集验证初始化时间和轨迹精度。这个过程看上去耗时但真正值钱的是省掉了后面排查问题的大把时间。IMU标定这件事确实是磨刀不误砍柴工。本文还有配套的精品资源点击获取