1. IMU标定基础

1.1 为什么需要标定

IMU原始输出包含多种误差,可分为两类:

  • 确定性误差:如零偏(bias)、尺度因子(scale factor)、轴间交轴耦合(misalignment)。通常通过六面法或转台标定。
  • 随机误差:随时间变化的不确定性,包括高斯白噪声(white noise)和零偏不稳定性(bias instability)。这类误差需要通过统计方法(如Allan方差)在长时间静止数据中分析得出。

随机误差参数是VIO(视觉惯性里程计)算法(如VINS-Mono、OKVIS)输入的必要项,直接影响状态估计的精度和鲁棒性。

1.2 Allan方差法简介

Allan方差是一种时域分析技术,最初用于描述振荡器的频率稳定性,现广泛应用于IMU随机误差建模。通过对长时间静止数据按不同积分时间(簇时间)计算方差,绘制双对数曲线,可以辨识出不同随机过程的系数:

  • 斜率为 -1/2 的段对应量化噪声(通常可忽略)
  • 斜率为 0 的段对应角度/速度随机游走(即白噪声积分)
  • 斜率为 +1/2 的段对应零偏不稳定性
  • 斜率为 +1 的段对应速率随机游走
  • 斜率为 +2 的段对应速率斜坡

在实际工程中,最关注的是白噪声(角度/速度随机游走系数)和零偏不稳定性

1.3 标定输出参数含义

imu_utils 最终输出的 YAML 文件包含四个关键值:

  • acc_n: 加速度计白噪声(单位:m/s2/Hzm/s2/Hz 或 m/s2⋅sm/s2⋅s
  • acc_w: 加速度计零偏不稳定性(单位:m/s2m/s2)
  • gyr_n: 陀螺仪白噪声(单位:rad/s/Hzrad/s/Hz 或 rad/s⋅srad/ss
  • gyr_w: 陀螺仪零偏不稳定性(单位:rad/srad/s

这些值将直接填入VIO配置文件中。


2. 准备工作

2.1 硬件与数据要求

  • IMU数据包:用户已录制了4小时的ROS bag包,包含IMU数据。理想情况下,IMU应置于静止水平面上,无振动、无温度突变。
  • 数据时长:为了获得可靠的Allan方差曲线,静止数据建议不少于2小时,4小时已非常充足。
  • 话题名称:请确保知道bag包中IMU数据的话题名(例如 /imu/data_raw),后续配置需要用到。

2.2 系统环境与依赖

  • 操作系统:Ubuntu 16.04/18.04/20.04(建议18.04或20.04,ROS版本对应 melodic/noetic)
  • ROS:已安装并配置好环境(包括rosbag、roscore等基本工具)
  • 编译工具:cmake、git、g++等基础开发工具
  • 系统库libdw-dev, libgoogle-glog-dev, libgflags-dev, libatlas-base-dev, libeigen3-dev

安装基础依赖:

bash

sudo apt-get update
sudo apt-get install libdw-dev libgoogle-glog-dev libgflags-dev libatlas-base-dev libeigen3-dev

3. 安装imu_utils及依赖

imu_utils 依赖两个关键部分:code_utils(一个基础工具库)和 Ceres Solver(非线性优化库)。需按顺序编译。

3.1 安装Ceres Solver

如果系统尚未安装Ceres,请执行以下步骤:

bash

# 下载源码
git clone https://ceres-solver.googlesource.com/ceres-solver
cd ceres-solver
mkdir build && cd build
cmake ..
make -j4
sudo make install

也可以使用 apt 安装(版本可能较旧):sudo apt install libceres-dev,但建议源码编译以获得最新版本。

3.2 编译code_utils与imu_utils

创建一个专用的工作空间(例如 imu_calib_ws):

bash

mkdir -p ~/imu_calib_ws/src
cd ~/imu_calib_ws/src

1. 克隆 code_utils

bash

git clone https://github.com/gaowenliang/code_utils.git

2. 首次编译 code_utils

bash

cd ~/imu_calib_ws
catkin_make

这一步可能遇到编译错误(如找不到 backward.hpp),需要按下一节的解决方法处理。

3. 克隆 imu_utils

bash

cd ~/imu_calib_ws/src
git clone https://github.com/gaowenliang/imu_utils.git

4. 再次编译整个工作空间

bash

cd ~/imu_calib_ws
catkin_make

如果一切顺利,你将看到 [100%] Built target ...

5. 设置环境变量

bash

source ~/imu_calib_ws/devel/setup.bash

为了永久生效,可以将此行添加到 ~/.bashrc

3.3 常见编译错误及解决

错误1:fatal error: backward.hpp: No such file or directory

原因:code_utils 中的 sumpixel_test.cpp 包含了 backward.hpp,但路径不对。
解决方法:修改 code_utils/src/sumpixel_test.cpp,将 #include "backward.hpp" 改为 #include "code_utils/backward.hpp"。修改后重新编译 code_utils

错误2:error: ‘CV_GRAY2BGR’ was not declared in this scope
原因:OpenCV版本更新后宏定义变化(如CV_前缀改为cv::)。
解决方法:将 code_utils 中所有 CV_ 开头的宏改为对应的 cv:: 枚举,或使用兼容版本。通常安装OpenCV 3.2以上即可。

错误3:ceres::相关未定义引用
原因:Ceres未正确链接。
解决方法:确认Ceres安装成功,并在 CMakeLists.txt 中检查 find_package(Ceres REQUIRED)。也可尝试重新安装Ceres。


4. 配置标定Launch文件

4.1 创建launch文件

进入 imu_utils 的 launch 目录,新建一个自定义的 launch 文件,例如 my_imu_calib.launch

bash

roscd imu_utils/launch
gedit my_imu_calib.launch

4.2 参数详解

将以下内容复制到文件中,并修改为你的实际参数:

xml

<launch>
    <node pkg="imu_utils" type="imu_an" name="imu_an" output="screen">
        <!-- IMU话题名称,必须与bag包中的话题一致 -->
        <param name="imu_topic" type="string" value="/imu/data_raw"/>
        <!-- 自定义的IMU名称,用于生成输出文件名 -->
        <param name="imu_name" type="string" value="my_imu"/>
        <!-- 结果保存路径,默认为imu_utils/data/ -->
        <param name="data_save_path" type="string" value="$(find imu_utils)/data/"/>
        <!-- 要分析的数据时长(分钟),必须小于bag包总时长(240分钟) -->
        <param name="max_time_min" type="int" value="230"/>
        <!-- 最大簇数,保持默认100即可 -->
        <param name="max_cluster" type="int" value="100"/>
    </node>
</launch>

参数说明

  • imu_topic:字符串,必须与bag包中的IMU话题完全一致,例如 /my_imu/data
  • imu_name:任意字符串,将作为输出文件名的前缀。
  • data_save_path:保存结果的目录。如果目录不存在,程序会自动创建。
  • max_time_min:整型,指定从bag中提取多长的数据进行分析(单位分钟)。建议比总时长少留几分钟余量,如230分钟(4小时=240分钟)。
  • max_cluster:整型,Allan方差计算中最大簇的数量,默认100足够。

5. 执行标定

执行标定需要两个终端:一个运行标定节点,一个回放bag数据。

5.1 启动标定节点

在第一个终端中,刷新环境并启动刚才创建的launch文件:

bash

source ~/imu_calib_ws/devel/setup.bash
roslaunch imu_utils my_imu_calib.launch

此时终端会显示类似以下信息:

text

[ INFO] [1678901234.567890123]: wait for imu data.

表示节点已启动,正在等待订阅的IMU话题数据。

5.2 高速回放bag数据

在第二个终端中,进入存放bag包的目录,使用 rosbag play 以较高速率回放,以加快处理速度(注意不要过快导致丢帧,一般200倍速以内安全):

bash

cd /path/to/your/bagfile
rosbag play -r 200 your_4hours_imu.bag

其中 -r 200 表示200倍速播放,这样4小时的数据可在约1.2分钟内回放完毕。

5.3 等待计算完成

bag回放完毕后,切勿立即关闭第一个终端imu_utils 节点需要时间对接收到的数据进行Allan方差分析。根据数据量和计算机性能,计算可能需要几分钟到十几分钟。观察第一个终端,直到输出大量计算结果并最终显示 done 字样,才算完成。

如果一切正常,你会看到类似如下的实时输出:

text

[ INFO] [1678901345.123456]: wait for imu data.
[ INFO] [1678901350.123456]: data received, start allan analysis...
[ INFO] [1678901400.123456]: cluster 10/100
...
[ INFO] [1678901800.123456]: cluster 100/100
[ INFO] [1678901805.123456]: allan analysis done, result saved to /home/user/imu_calib_ws/src/imu_utils/data/my_imu_imu_param.yaml

6. 结果分析与参数解读

6.1 生成的文件

data_save_path 指定的目录下(默认为 imu_utils/data/),会生成多个文件:

  • my_imu_imu_param.yaml:最终的标定参数YAML文件。
  • my_imu_acc_allan.mat / my_imu_gyr_allan.mat:MATLAB数据文件,可用于进一步绘图分析。
  • 一些 .txt 中间文件。

6.2 YAML参数详解

打开 my_imu_imu_param.yaml,内容大致如下:

yaml

%YAML:1.0
---
type: IMU
name: my_imu
acc_n: 0.001234567890
acc_w: 0.000012345678
gyr_n: 0.000023456789
gyr_w: 0.000000123456

各字段含义:

  • acc_n:加速度计白噪声(单位通常为 m/s2/Hzm/s2/Hz),即加速度随机游走。
  • acc_w:加速度计零偏不稳定性(单位 m/s2m/s2)。
  • gyr_n:陀螺仪白噪声(单位 rad/s/Hzrad/s/Hz),即角度随机游走。
  • gyr_w:陀螺仪零偏不稳定性(单位 rad/srad/s)。

注意:不同VIO系统可能要求不同的单位,例如VINS-Mono中需要的是连续时间下的噪声密度,即上述值可以直接使用。但有时需要乘以 1/dt1/dt 转换为离散时间,请根据具体算法文档确认。

6.3 如何应用到VIO系统中

以VINS-Mono为例,其配置文件 config.yaml 中与IMU相关的部分如下:

yaml

# IMU parameters
acc_n: 0.001234567890
gyr_n: 0.000023456789
acc_w: 0.000012345678
gyr_w: 0.000000123456

直接将标定得到的值填入即可。对于其他算法(如OKVIS、MSCKF),通常也是类似的噪声参数。


7. 高级话题与备选方案

7.1 使用Kalibr进行Allan方差标定

ETH Zurich的Kalibr工具包也提供了Allan方差标定功能,称为 kalibr_allan。它支持直接从ROS bag包读取IMU数据,输出参数文件,并提供更丰富的可视化。如果你希望获得更专业的曲线拟合或对结果有疑问,可以尝试Kalibr。

基本用法(需先安装Kalibr):

bash

rosrun kalibr kalibr_allan IMU my_imu.bag --imu-topic /imu/data --bag-from-to 0 14400 --output-dir ./

其中 14400 秒即4小时。Kalibr会生成一个PDF报告和YAML文件。

7.2 确定性误差标定

本文主要针对随机误差。如果还需要标定确定性误差(零偏、尺度因子、交轴耦合),可以使用 imu_tkimu_calib 等工具,它们通常需要多轴旋转数据(如通过手持IMU做特定运动),而非单纯静止数据。


8. 常见问题FAQ

8.1 编译code_utils时报错“backward.hpp”找不到

现象:编译 code_utils 时,sumpixel_test.cpp 提示找不到 backward.hpp
解决:如3.3节所述,修改 code_utils/src/sumpixel_test.cpp,将 #include "backward.hpp" 改为 #include "code_utils/backward.hpp",然后重新编译。

8.2 标定过程中收不到数据

现象:启动launch文件后,一直显示 wait for imu data.,即使回放bag包也没有反应。
排查步骤

  1. 确认launch文件中的 imu_topic 是否与bag包中的话题名完全一致(包括斜杠)。
  2. 确认在回放bag前已经启动了 roscore?通常 roslaunch 会自动启动 roscore,但如果之前未运行,可能无法通信。可先单独运行 roscore
  3. 尝试用 rostopic list 查看回放时话题是否出现。
  4. 检查节点是否订阅了正确的话题:rostopic info /imu/data_raw 查看订阅者。

8.3 标定结果不合理

现象:得到的噪声值数量级异常(如陀螺白噪声达到0.1量级)或与IMU手册相差悬殊。
原因分析

  • 数据质量不佳:静止期间IMU受到振动或移动。
  • 时长不够:Allan方差需要长时间静止数据,2小时以下可能不稳定。
  • 参数设置错误:max_time_min 设置过短,或 max_cluster 设置不合理。
  • 数据频率问题:IMU频率过高(如1000Hz)但 max_cluster 不够大?通常默认100足够。

改进建议:检查原始数据是否确实静止(可用 rqt_bagrostopic echo 查看加速度模值是否接近g),尝试更长的数据段,或使用Kalibr进行交叉验证。

8.4 是否需要先标定确定性误差?

随机误差标定通常不依赖于确定性误差的精确值,因为Allan方差分析对数据中的常数偏置不敏感。但为了得到最准确的结果,建议先进行确定性误差的粗略校正(例如使用IMU内置温度补偿,或通过六面法标定零偏),然后再录制静止数据用于随机误差标定。不过,对于大多数消费级IMU,直接对原始数据做Allan方差也足够。


9. 结语

本文详细阐述了使用ROS工具 imu_utils 对4小时静止IMU数据进行随机误差标定的全过程。通过Allan方差分析,我们可以获取陀螺仪和加速度计的白噪声及零偏不稳定性,这些参数是视觉惯性里程计算法正确工作的基础。文中涵盖了环境搭建、编译、配置、执行、结果解读等环节,并列举了常见问题的解决方案。

值得注意的是,标定结果的质量高度依赖于原始数据的纯净度——一个平稳、无干扰的静止环境至关重要。如果你的应用对精度有极高要求,建议多次采集数据标定并取平均,或使用更高精度的标定设备(如温控转台)辅助。

希望本文能帮助你顺利完成IMU的随机误差标定,为后续的机器人定位与建图工作打下坚实基础。如果在实践中遇到其他问题,欢迎交流讨论。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐