kalibr安装采坑过程

前言

有三种方式进行kalibr标定。一种是编译好的kelibr-cde,另一种是源码编译,使用rosrun运行。我推荐源码安装方式。第三种方式适用于自己电脑环境有问题,于是采用kalibr提供的docker镜像运行标定程序。

一. kalibr-cde方式

想使用kalibr-cde见如下过程

软件

我使用了Kalibr-cde软件,先进入kalibr-cde的目录,再执行如下命令。

多相机标定

参考网页:Multi camera calibration
参考命令

./kalibr_calibrate_cameras --bag /media/wzy/EB5E-C002/SLAM/bag/cam3_imu_calib_2022-08-19-18-12-46.bag --topics /camera3/camera/infra1/image_rect_raw /camera3/camera/infra2/image_rect_raw --models pinhole-equi pinhole-equi --target dynamic/april_6x6_80x80cm.yaml

相机与IMU标定

参考网页:Camera IMU calibration
参考命令

./kalibr_calibrate_imu_camera --bag dynamic/camera4-infra12-imu-2022-07-18-09-37-41.bag --cam dynamic/camchain-camera4-infra12-2022-07-18-09-37-41.yaml --imu dynamic/camera4_imu.yaml --target dynamic/april_6x6_80x80cm.yaml --bag-from-to 8 70

二. 源码编译方式

网上一般的方式都是源码编译,首先git clone到ros工作空间下,然后catkin_make。以下链接可以参考。
链接:使用kalibr标定流程非常详细
我直接给出我的编译指令,供参考

2.1 先采集数据

运动方式是相机正对二维码, 沿x y z轴向平移3次,再绕x y z轴来回转动3次,最后随机运动一下。(我看YouTube是这样,但每次标定出来,像素投影误差都有1~2个像素,没有官方给出的那么好。)

rosbag record /imu/data /camera5/camera/infra1/image_rect_raw /camera5/camera/infra2/image_rect_raw /camera5/camera/infra1/camera_info /infra1/image_rect_raw /camera5/camera/infra1/image_rect_raw /camera5/camera/infra2/camera_info -o cam5_cams_imu_calib

2.2 运行两个相机镜头标定

这里需要预先准备../april_6x6_80x80cm.yaml文件,需要用A0大小打印出来,文件内容如下:

target_type: 'aprilgrid' #gridtype
tagCols: 6               #number of apriltags
tagRows: 6               #number of apriltags
tagSize: 0.088           #size of apriltag, edge to edge [m]
tagSpacing: 0.264          #ratio of space between tags to tagSize
codeOffset: 0            #code offset for the first tag in the aprilboard

然后运行下面命令

$ rosrun kalibr kalibr_calibrate_cameras --bag ~/rosbag/kalibr_bag/cam5_cams_imu_calib_2022-12-04-11-23-38.bag --topics /camera5/camera/infra1/image_rect_raw /camera5/camera/infra2/image_rect_raw --models pinhole-radtan pinhole-radtan --target ../april_6x6_80x80cm.yaml --bag-from-to 5 115 --approx-sync 0.06

我用的D455相机的两个红外镜头。一般得到的标定结果和D455原厂标定结果有些许差别,我一般信任原厂,所以如果标定结果差别不大,就手动改一改标定的内参,取当次标定和原厂数值的平均值更为可靠。得到如下结果。
cam5_cams_imu_calib_camchain_mean.yaml文件:

cam0:
  cam_overlaps: [1]
  camera_model: pinhole
  distortion_coeffs: [-0.0006436511438276515, -0.01165348200528119, 0.0019951321118770325, -0.0007110618480805931]
  distortion_model: radtan
  intrinsics: [387.1605481551291, 387.84054907181496, 313.4358013166151, 243.71198013921006]
  resolution: [640, 480]
  rostopic: /camera5/camera/infra1/image_rect_raw
cam1:
  T_cn_cnm1:
  - [0.9999914754079172, 0.0025116449302754144, -0.003277308535519918, -0.09558105539360899]
  - [-0.0024762063385359804, 0.999938904212508, 0.010772940381051388, 0.006515065205643839]
  - [0.0033041661068663195, -0.010764733253960138, 0.9999365994923405, -0.007410902436475767]
  - [0.0, 0.0, 0.0, 1.0]
  cam_overlaps: [0]
  camera_model: pinhole
  distortion_coeffs: [-0.007400396837104382, -0.005671860746890236, -0.0034262073549618543, -0.0009614868304447853]
  distortion_model: radtan
  intrinsics: [387.8555715413133, 387.8953278983378, 314.73981903087537, 241.981461]
  resolution: [640, 480]
  rostopic: /camera5/camera/infra2/image_rect_raw

解释一下T_cn_cnm1:含义,cam0cam1图像坐标系下的位姿。由于图像坐标系是:x右,y下,z前。那么4x4矩阵最后一列,t_x = -0.0955 , t_y = 0.0065, t_z = -0.0074表示cam0cam1的右边-0.095m,也就是左边0.095m,正好是D455的双目基线长度。y和z几乎为0。因为双目镜头位置在这两个方向几乎一样。

2.3 将imu与两个相机镜头标定

需要预先准备cam5_cams_imu_calib_camchain_mean.yaml(这个2.2步骤是两个镜头标定输出的参数文件)。另一个需要cam5_imu.yaml(这个文件一般是Allan标定的结果,通过IMU静置2小时,然后分析误差,我试过,但后面懒,直接手动给噪声参数了,而且手持IMU噪声和装在飞机上时IMU振动时噪声又不一样,所以感觉没必要静置标定。如下所示)

rostopic: /imu/data
update_rate: 200.0 #Hz

accelerometer_noise_density: 0.01 #continous
accelerometer_random_walk: 0.0002 
gyroscope_noise_density: 0.005 #continous
gyroscope_random_walk: 4.0e-06

然后运行

$ rosrun kalibr kalibr_calibrate_imu_camera --bag ~/rosbag/kalibr_bag/cam5_cams_imu_calib_2022-12-04-13-40-59.bag --cam camera5/cam5_cams_imu_calib_camchain_mean.yaml --imu camera5/cam5_imu.yaml --target ../april_6x6_80x80cm.yaml --bag-from-to 5 85

得到结果如下:

%YAML:1.0

cam0:
  T_cam_imu:
    - [0.005396026321574626, -0.9999262748511594, 0.01087785650850831, 0.02]
    - [-0.06457685627174603, -0.011203751804069656, -0.997849841198349, -0.02]
    - [0.9978981473747679, 0.004681966231790791, -0.06463255107304097, 0.01]
    - [0.0, 0.0, 0.0, 1.0]
  cam_overlaps: [1]
  camera_model: pinhole
  distortion_coeffs: [-0.0006436511438276515, -0.01165348200528119, 0.0019951321118770325, -0.0007110618480805931]
  distortion_model: radtan
  intrinsics: [387.1605481551291, 387.84054907181496, 313.4358013166151, 243.71198013921006]
  resolution: [640, 480]
  rostopic: /camera5/camera/infra1/image_rect_raw
  timeshift_cam_imu: -0.029391262854232037
cam1:
  T_cam_imu:
    - [0.0019633660730125624, -0.9999612349818692, 0.008583340095701053, -0.07]
    - [-0.05383597532440887, -0.008676604979094116, -0.9985120952131259, -0.02]
    - [0.9985478621250626, 0.001498352285640936, -0.053850923723694155, 0.01]
    - [0.0, 0.0, 0.0, 1.0]
  T_cn_cnm1:
    - [0.9999914754079181, 0.0025116449302754144, -0.003277308535519918, -0.095]
    - [-0.0024762063385359804, 0.9999389042125089, 0.010772940381051388, 0.00]
    - [0.0033041661068663195, -0.010764733253960138, 0.9999365994923414, 0.00]
    - [0.0, 0.0, 0.0, 1.0]
  cam_overlaps: [0]
  camera_model: pinhole
  distortion_coeffs: [-0.007400396837104382, -0.005671860746890236, -0.0034262073549618543, -0.0009614868304447853]
  distortion_model: radtan
  intrinsics: [387.8555715413133, 387.8953278983378, 314.73981903087537, 241.981461]
  resolution: [640, 480]
  rostopic: /camera5/camera/infra2/image_rect_raw
  timeshift_cam_imu: -0.019921372808489393

注意文件开头的 %YAML:1.0是我标定结果出来以后手动添加的。还有一些缩进也是我后来手动调整的。kalibr给出的yaml文件格式原本这些都没有。
解释一下矩阵含义,在cam0坐标系下,imu的位姿。依旧按照图像坐标系(x右,y下,z前)来看。imu位于相机右边0.02m,下方-0.02m,前方0.01m。旋转矩阵R看作,imu的xyz在cam0的xyz下的表示,即[x_cam,y_cam,z_cam]’ = R * [x_imu,y_imu,z_imu]

cam0:
  T_cam_imu:
    - [0.005396026321574626, -0.9999262748511594, 0.01087785650850831, 0.02]
    - [-0.06457685627174603, -0.011203751804069656, -0.997849841198349, -0.02]
    - [0.9978981473747679, 0.004681966231790791, -0.06463255107304097, 0.01]
    - [0.0, 0.0, 0.0, 1.0]

可以看出矩阵最后一列是我手动填写的。因为kalibr在标定效果不好时,结果非常差。不如手动给,一般在跑SLAM算法时,都有实时标定外参,所以给一个基本正确的初值就可以了。
同理,下面是在cam1坐标系下,imu的位姿

cam1:
  T_cam_imu:
    - [0.0019633660730125624, -0.9999612349818692, 0.008583340095701053, -0.07]
    - [-0.05383597532440887, -0.008676604979094116, -0.9985120952131259, -0.02]
    - [0.9985478621250626, 0.001498352285640936, -0.053850923723694155, 0.01]
    - [0.0, 0.0, 0.0, 1.0]

同理,下面是在cam1坐标系下,cam0的位姿

  T_cn_cnm1:
    - [0.9999914754079181, 0.0025116449302754144, -0.003277308535519918, -0.095]
    - [-0.0024762063385359804, 0.9999389042125089, 0.010772940381051388, 0.00]
    - [0.0033041661068663195, -0.010764733253960138, 0.9999365994923414, 0.00]
    - [0.0, 0.0, 0.0, 1.0]

三. Docker方式

参考官方文档
分为3步:

  • 使用dockerfile制作镜像
    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
    
  • 挂载一个本机的文件夹用于提供rosbag和yaml文件以及存放标定结果
    FOLDER=/path/to/your/data/on/host
    xhost +local:root
    docker run -it -e "DISPLAY" -e "QT_X11_NO_MITSHM=1" \
        -v "/tmp/.X11-unix:/tmp/.X11-unix:rw" \
        -v "$FOLDER:/data" kalibr
    
  • 在docker中运行标定命令
    source devel/setup.bash
    rosrun kalibr kalibr_calibrate_cameras \
        --bag /data/cam_april.bag --target /data/april_6x6.yaml \
        --models pinhole-radtan pinhole-radtan \
        --topics /cam0/image_raw /cam1/image_raw
    

四.下面是一些我遇到的报错

安装报错1:关于SuiteSparse

链接:参考链接
具体操作我参考了链接:更改cmakelist文件
虽然可以成功下载,但是包的名字有后缀,导致后面找不到文件路径,参考链接:修改文件夹名称,见文章末尾

运行报错1:python-igraph

这个错误一般是标定多个相机时候,运行如下命令时
kalibr_calibrate_cameras --bag stereo_calib_20hz.bag --topic /infra1 /infra2 --models pinhole-equi pinhole-equi --target april_6x6.yaml
调用了一个python库叫igraph
如果直接使用sudo pip install python-graph会安装最新的版本0.9.1,但是我的ubuntu18.04会报错(可能是python2.7的原因)。
于是下载0.8.3版本就没问题
命令sudo pip install python-graph==0.8.3

运行报错2:相机图像不同步

Cameras are not connected through mutual observations, please check the dataset. Maybe adjust the approx. sync. tolerance.

原因是两个相机不同步,既可以提高采集频率到20hz,也可以同时增加同步忍耐度 --bag-from-to 5 35 --approx-sync 0.04
完整参数如下:
kalibr_calibrate_cameras --bag stereo_calib_20hz.bag --topic /infra1 /infra2 --models pinhole-equi pinhole-equi --target april_6x6.yaml --bag-from-to 5 35 --approx-sync 0.04

运行报错3:当生成pdf标定板时缺pyx

运行命令

python kalibr_create_target_pdf --type apriltag --nx 6 --ny 6 --tsize 0.08 --tspace 0.3

得到错误

	Traceback (most recent call last):
	  File "/usr/lib/python2.7/atexit.py", line 24, in _run_exitfuncs
	    func(*targs, **kargs)
	  File "/usr/lib/python2.7/dist-packages/pyx/text.py", line 748, in _cleantmp
	    texrunner.texinput.write("\n\\end\n")
	IOError: [Errno 32] Broken pipe

网上说法是sudo apt-get install python-pyx 或者 sudo apt-get install python3-pyx,但是我依旧报错Tex runTime error,放弃了,用楼下另一台vicon白色电脑装这个python-pyx就没问题,也顺利生成pdf标定版。

运行报错5:标定时Boost.Python出错

运行命令

rosrun kalibr kalibr_calibrate_cameras --bag ~/hard_disk/rosbag/kalibr_bag/usb-ir-color/kun1_ir_mono_apriltag_v3_2023-09-12-13-21-35.bag --topics /kun1/ir_mono --models pinhole-radtan --target ~/hard_disk/rosbag/kalibr_bag/usb-ir-color/april_6x6_352x352cm.yaml

得到错误

importing libraries
Initializing cam0:
	Camera model:	  pinhole-radtan
	Dataset:          /home/zph/hard_disk/rosbag/kalibr_bag/usb-ir-color/kun1_ir_mono_apriltag_v3_2023-09-12-13-21-35.bag
	Topic:            /kun1/ir_mono
	Number of images: 403
Traceback (most recent call last):
  File "/home/zph/ros_ws/kalibr_workspace/src/kalibr/aslam_offline_calibration/kalibr/cmake-build-debug/catkin_generated/installspace/kalibr_calibrate_cameras", line 450, in <module>
    main()
  File "/home/zph/ros_ws/kalibr_workspace/src/kalibr/aslam_offline_calibration/kalibr/cmake-build-debug/catkin_generated/installspace/kalibr_calibrate_cameras", line 174, in main
    cam = kcc.CameraGeometry(cameraModel, targetConfig, dataset, verbose=(parsed.verbose or parsed.showextraction))
  File "/home/zph/ros_ws/kalibr_workspace/src/kalibr/aslam_offline_calibration/kalibr/python/kalibr_camera_calibration/CameraCalibrator.py", line 44, in __init__
    self.setDvActiveStatus(True, True, False)
  File "/home/zph/ros_ws/kalibr_workspace/src/kalibr/aslam_offline_calibration/kalibr/python/kalibr_camera_calibration/CameraCalibrator.py", line 51, in setDvActiveStatus
    self.dv.projectionDesignVariable().setActive(projectionActive)
Boost.Python.ArgumentError: Python argument types in
    DesignVariable.setActive(DistortedPinholeProjectionDesignVariable, bool)
did not match C++ signature:
    setActive(aslam::backend::DesignVariable {lvalue}, bool)

最后没找到办法,后来采用了DockerFile方式,在Docker中运行标定命令了。

  • 1
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值