0%

Kalibr标定软件使用教程

1 简介

近期在基于在基于GVINS进行开发,采集了GNSS、IMU、相机的数据,需要对相机和IMU的数据进行标定,包括相机内参标定以及相机和IMU之间的外参标定,这里使用了经典的Kalibr标定软件进行操作,在此记录一下使用过程。

2 Kalibr安装过程

Kalibr软件是一个经典的标定软件,可以解决以下标定问题:

  • 多相机标定;
  • 相机-IMU标定;
  • 多IMU标定;
  • 卷帘快门相机标定。

具体可以参考Kalibr 页面介绍。

由于Kalibr软件开发得比较早,安装环境是基于较旧的Ubuntu环境,所以本人在Ubuntu22.04上基于源码编译安装出现了很多问题,最终还是采用了基于Docker的安装方式,这里就不对源码编译安装的惨痛过程进行赘述了,直接开始介绍Docker安装过程。

Kalibr的安装过程可以参考install wiki页面,本人所用的安装命令为:

1
2
3
git clone https://github.com/ethz-asl/kalibr.git
cd kalibr
docker build -t kalibr -f Dockerfile_ros1_20_04 . # change this to whatever ubuntu version you want

尽管本人电脑的操作系统为Ubuntu22.04,但是安装的ROS版本还是ROS-noetic,所以这里还是选用的Dockerfile_ros1_20_04。执行上述命令后不出意外报错了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[+] Building 30.1s (2/2) FINISHED                                     docker:default

=> [internal] load build definition from Dockerfile_ros1_20_04 0.0s

=> => transferring dockerfile: 1.37kB 0.0s

=> ERROR [internal] load metadata for docker.io/osrf/ros:noetic-desktop-full 30.0s

------

> [internal] load metadata for docker.io/osrf/ros:noetic-desktop-full:

------

Dockerfile_ros1_20_04:1

--------------------

1 | >>> FROM osrf/ros:noetic-desktop-full

2 |

3 |

--------------------

ERROR: failed to solve: osrf/ros:noetic-desktop-full: failed to do request: Head "https://registry-1.docker.io/v2/osrf/ros/manifests/noetic-desktop-full": dial tcp 128.121.243.235:443: i/o timeout

根据以上报错原因,是Docker从官方仓库获取镜像osrf/ros:noetic-desktop-full时超时了,这我就不理解了,本机一直开着代理,curl google也没有问题,这里为什么就会超时。咨询了Gemini后是这么回答我的:

终端的环境变量代理(HTTP_PROXY)与 Docker 守护进程(Docker Daemon)的代理是完全独立的。

即使你在终端里执行 export http_proxy=... 并且 curl 成功了,这只影响当前这个 Shell 窗口发出的请求。而 docker build 命令实际上是将指令发送给后台运行的 Docker Engine (dockerd),它并不读取你终端里的环境变量。

要解决 docker build 时的超时,你需要针对性地配置 Docker 守护进程或构建参数。

嗯,看来Docker还是有很多东西要学习的。Gemini也给出了解决办法,快速点就是直接换源,在Dockerfile_ros1_20_04中修改源地址:

1
2
# FROM osrf/ros:noetic-desktop-full	# 注释掉原有的官方地址
FROM docker.m.daocloud.io/osrf/ros:noetic-desktop-full # 换为国内镜像源

然后就是漫长的等待时间,等待安装完成即可。

3 标定过程

安装完成之后,使用以下命令进入docker环境:

1
2
3
4
5
docker run -it \
--name my_kalibr \
-v "${/PATH/TO/SHARE}:/data" \ # 修改共享的文件夹路径
kalibr \
/bin/bash

要进行相机-IMU标定前需要先对相机进行内参标定,然后才可以进行外参标定,接下来分别进行介绍。

3.1 相机内参标定

进行相机内参标定时需要用到标定板,然后编写对应的配置文件,我这里用的是棋盘格(Checkerboard),将对应的配置文件写下作为参考:

1
2
3
4
5
target_type: 'checkerboard'
targetCols: 6 # 内角点数量(行)
targetRows: 9 # 内角点数量(列)
rowSpacingMeters: 0.024 # 格子高度 (米)
colSpacingMeters: 0.024 # 格子宽度 (米)

当然,更推荐使用Aprilgrid,在抗遮挡方面效果更佳,其对应的配置文件为:

1
2
3
4
5
target_type: 'aprilgrid'
tagCols: 6
tagRows: 6
tagSize: 0.088 # 二维码大小 (米)
tagSpacing: 0.3 # 间距比例 (0.3 表示间距是 tagSize 的 30%)

完成标定板的配置文件之后,就可以利用提前录制的标定rosbag来进行标定了:

1
2
3
4
5
rosrun kalibr kalibr_calibrate_cameras \
--bag /data/vins_calib.bag \ # 修改为自己的rosbag路径
--target /data/config_self/target.yaml \ # 标定板配置文件
--models omni-radtan \ # 这里根据使用的镜头类型选择合适的模型
--topics /sensor/cam1 # 同上

然后程序就可以自主运行,解算出相机的内参与标定结果文件了。

3.2 相机-IMU外参标定

3.2.1 IMU配置文件

在得到相机的内参之后,就可以进行相机-IMU的外参标定了,这里还需要准备以下IMU的相关噪声参数,这些参数都可以从datasheet中获取,这里写下IMU的噪声参数配置文件:

1
2
3
4
5
6
rostopic: /imu0
update_rate: 200.0 # 频率 (Hz)
accelerometer_noise_density: 9.81e-04 # (m/s^2/sqrt(Hz))
accelerometer_random_walk: 6.17e-04 # (m/s^3/sqrt(Hz))
gyroscope_noise_density: 1.39e-04 # (rad/s/sqrt(Hz))
gyroscope_random_walk: 9.89e-05 # (rad/s^2/sqrt(Hz))

这里需要注意单位换算,以ADIS16470手册中给的数值为例:

image-20260509163500179

文件中给定的陀螺仪、加速度计的随机游走单位分别为$^\circ/\sqrt{\text{hr}}$、$ \text{m}/\text{s}/\sqrt{\text{hr}}$,而配置文件中要求的单位分别是:$ \text{rad}/\text{s}^2/\sqrt{\text{Hz}}$、$\text{m}/\text{s}^3/\sqrt{\text{Hz}}$,这里给出对应的转换关系:

而噪声密度参数的单位转换比较简单,从$^\circ$转换为rad、从$\mu g$转换为$\text{m}/\text{s}^2$,这里就不多赘述了。

3.2.2 标定与结果

编写完IMU的配置文件之后即可进行相机-IMU外参标定了,命令如下所示:

1
2
3
4
5
rosrun kalibr kalibr_calibrate_imu_camera \
--bag /data/vins_calib_converted.bag \
--target /data/config_self/target.yaml \
--cam /data/vins_calib-camchain.yaml \
--imu /data/config_self/imu.yaml

与相机标定命令类似,需要对上述各路径根据实际情况进行修改。然后程序就可以自主运行,得到相机和IMU之间的外参了。这里以我的标定结果为例进行说明:

1
2
3
4
5
6
cam0:
T_cam_imu:
- [-0.9999077671725599, 0.006788928204283567, 0.01176297589148161, -0.010043807082338534]
- [0.011335063851105292, -0.05995628234656512, 0.998136644219954, 0.06764716589702693]
- [0.007481542319459307, 0.9981779173378946, 0.05987379947444539, -0.10102821338700176]
- [0.0, 0.0, 0.0, 1.0]

值得注意的是,这里得到的是从IMU坐标系到相机坐标系的转换矩阵,即:

若想获取从相机坐标系到IMU坐标系的转换矩阵,可以通过下式得到: