前言
vio重中之重就是傳感器標(biāo)定,需要標(biāo)定的參數(shù)一般有:相機(jī)內(nèi)參、相機(jī)畸變、相機(jī)到imu坐標(biāo)系的外參、imu噪聲
主要工具為:
- imu_utils: https://github.com/gaowenliang/imu_utils
- kalibr: https://github.com/ethz-asl/kalibr
建議系統(tǒng)為ubuntu+ros,我這里使用最常用的 ubuntu18.04+ros-melodic組合,我也制作了一個(gè) docker 鏡像方便使用:https://hub.docker.com/repository/docker/vell001/ubt18.04_ros_xrdp
docker 相關(guān)可以參考:http://www.itdecent.cn/p/52d5b35e7b77?v=1739101080481
安裝工具
可以參照:https://blog.csdn.net/qq_38429958/article/details/139276206
- 安裝 imu_utils
創(chuàng)建 imu_ws 文件夾,將https://github.com/gaowenliang/code_utils 和 https://github.com/gaowenliang/imu_utils兩個(gè)項(xiàng)目 clone 到 src 目錄下,目錄結(jié)構(gòu)如下
├── imu_ws
│ └── src
│ ├── code_utils
│ └── imu_utils
在 imu_ws 文件夾內(nèi)執(zhí)行 catkin_make,編譯好即可,記得先進(jìn)入 imu_ws,執(zhí)行 source devel/setup.bash,才能正常執(zhí)行該項(xiàng)目下的 ros 命令
- 安裝kalibr
創(chuàng)建 kalibr_ws 文件夾,將https://github.com/ethz-asl/kalibr clone 到 src 目錄下,目錄結(jié)構(gòu)如下
├── kalibr_ws
│ └── src
│ └── kalibr
在 kalibr_ws 文件夾內(nèi)執(zhí)行 catkin_make,編譯好即可
標(biāo)定 IMU
- 先錄制靜止?fàn)顟B(tài)下的 imu 數(shù)據(jù) 120 分鐘,官方工具默認(rèn)時(shí)間 120 分鐘,也可以短一點(diǎn),需要改下 launch 參數(shù)
- 修改 launch 參數(shù),在 imu_utils下隨便找到一個(gè) launch 文件,復(fù)制一份進(jìn)行修改,如:launch/A3.launch
<launch>
<node pkg="imu_utils" type="imu_an" name="imu_an" output="screen">
<param name="imu_topic" type="string" value= "/imu"/>
<param name="imu_name" type="string" value= "redmi"/>
<param name="data_save_path" type="string" value= "$(find imu_utils)/data/"/>
<param name="max_time_min" type="int" value= "120"/>
<param name="max_cluster" type="int" value= "100"/>
</node>
</launch>
注意max_time_min就是會用來標(biāo)定的最大時(shí)長,程序必須收集到大于這個(gè)時(shí)長的數(shù)據(jù)才會進(jìn)行標(biāo)定,所以值要設(shè)得比你錄制的 imu 數(shù)據(jù)時(shí)長小
- 執(zhí)行 launch
roslaunch imu_utils A3.launch
- 播放 bag 包,注意可以加速一下
rosbag play -r 200 imu.bag
- 查看標(biāo)定結(jié)果
結(jié)果在data_save_path設(shè)置的目錄下,默認(rèn)是imu_utils/data 下,如:imu_utils/data/A3_imu_param.yaml
%YAML:1.0
---
type: IMU
name: A3
Gyr:
unit: " rad/s"
avg-axis:
gyr_n: 1.0922514245261136e-04
gyr_w: 3.0407639130588035e-05
x-axis:
gyr_n: 1.1712350336249066e-04
gyr_w: 3.6395480767077183e-05
y-axis:
gyr_n: 1.0957986890514727e-04
gyr_w: 3.1881226725483150e-05
z-axis:
gyr_n: 1.0097205509019619e-04
gyr_w: 2.2946209899203768e-05
Acc:
unit: " m/s^2"
avg-axis:
acc_n: 1.4268671413807624e-03
acc_w: 6.3698303145662391e-04
x-axis:
acc_n: 1.2219441138445304e-03
acc_w: 5.3750668357445538e-04
y-axis:
acc_n: 1.2229466839249080e-03
acc_w: 6.0460048331990467e-04
z-axis:
acc_n: 1.8357106263728492e-03
acc_w: 7.6884192747551168e-04
注意:
關(guān)于vins的imu噪聲參數(shù)設(shè)置問題,imu標(biāo)定的結(jié)果只是用來參考,在vins中最好不要直接套用標(biāo)定的原始參數(shù),使用時(shí)最好將標(biāo)定參數(shù)擴(kuò)大到原始的10倍或者100倍(擴(kuò)大1~2個(gè)數(shù)量級),vins運(yùn)行只需要設(shè)置imu噪聲參數(shù)的大概值,一般情況下參數(shù)的數(shù)量級差不多能對上就行。關(guān)于這個(gè)問題的解釋可以參考 gaowenliang/imu_utils#36 (comment) 里的討論和 https://github.com/ethz-asl/kalibr/wiki/IMU-Noise-Model#kalibr-imu-noise-parameters-in-practice 里關(guān)于imu噪聲模型的解釋。imu的內(nèi)參是在靜止、恒溫情況下標(biāo)定的,而imu在實(shí)際運(yùn)行過程中是運(yùn)動的,而且溫度會改變,所以imu內(nèi)參標(biāo)定的結(jié)果只是用來參考的,而不是直接用在vins中。
參考:https://github.com/TAIL-Robot/TAIL-dataset/issues/4
個(gè)人實(shí)測,標(biāo)定參數(shù)放大 10 倍對 vins 效果較好,放大 100 倍快速運(yùn)動容易跑飛
標(biāo)定camera
https://github.com/ethz-asl/kalibr/wiki/multiple-camera-calibration
前提是已經(jīng)編譯好了kalibr,并進(jìn)入了kalibr的 catkins_workspace
- 生成并打印標(biāo)定紙
rosrun kalibr kalibr_create_target_pdf --type apriltag --nx 6 --ny 4 --tsize 0.045 --tspace 0.3 --eps
--tsize 0.045是適合 A3打印的,可以調(diào)整這個(gè)大小來生成對應(yīng)紙張大小的標(biāo)定紙
打印的 pdf 文件在執(zhí)行命令的當(dāng)前文件夾生成
? kalibr_ws rosrun kalibr kalibr_create_target_pdf --type apriltag --nx 6 --ny 4 --tsize 0.045 --tspace 0.3 --eps
? kalibr_ws ls
build devel src target.eps target.pdf
? kalibr_ws
注意打印時(shí)一定要選 100% 縮放
- 錄制標(biāo)定 bag,可以和 imu 聯(lián)合標(biāo)定一起錄制,對著標(biāo)定紙,分別在三軸上平移和旋轉(zhuǎn)三次,然后在做幾次隨機(jī)的三軸平移加旋轉(zhuǎn)的組合運(yùn)動,總共約兩分鐘即可
- 按標(biāo)定紙配置 target 標(biāo)定參數(shù), target.yaml,內(nèi)容如下:
target_type: 'aprilgrid' #gridtype
tagCols: 6 #number of apriltags
tagRows: 4 #number of apriltags
tagSize: 0.045 #size of apriltag, edge to edge [m]
tagSpacing: 0.3 #ratio of space between tags to tagSize
- 執(zhí)行標(biāo)定命令
rosrun kalibr kalibr_calibrate_cameras --target src/kalibr/config/target.yaml --models "pinhole-radtan" --bag ../bags/cali_usb_imu_cam.bag --bag-from-to 0 100 --show-extraction --topics "/cam"
可以選擇多種不同相機(jī),-bag-from-to單位是秒
相機(jī)類型參考:https://github.com/ethz-asl/kalibr/wiki/supported-models
標(biāo)定結(jié)果在 bag 包同級目錄下
camera+imu 聯(lián)合標(biāo)定
https://github.com/ethz-asl/kalibr/wiki/camera-imu-calibration
前提是已經(jīng)編譯好了kalibr,并進(jìn)入了kalibr的 catkins_workspace,且已經(jīng)單獨(dú)標(biāo)定好了 camera 和 imu
- 準(zhǔn)備好標(biāo)定配置
共需三個(gè) yaml,imu.yaml、camera.yaml、target.yaml,其中target.yaml 和 camera 標(biāo)定時(shí)保持一致
imu.yaml:
#Accelerometers
accelerometer_noise_density: 4.5912914601953958e-02 #Noise density (continuous-time)
accelerometer_random_walk: 9.8473966757113411e-04 #Bias random walk
#Gyroscopes
gyroscope_noise_density: 6.0751586827011324e-04 #Noise density (continuous-time)
gyroscope_random_walk: 4.1785854365612070e-06 #Bias random walk
rostopic: /imu #the IMU ROS topic
update_rate: 200.0 #Hz (for discretization of the values above)
和imu 標(biāo)定結(jié)果字段對應(yīng)
avg-axis:gyr_n 對應(yīng) gyroscope_noise_density
avg-axis:gyr_w 對應(yīng) gyroscope_random_walk
avg-axis:acc_n 對應(yīng) accelerometer_noise_density
avg-axis:acc_w 對應(yīng) accelerometer_random_walk
cam.yaml:
cam0:
cam_overlaps: []
camera_model: pinhole
distortion_coeffs: [-0.036380710744086116, -0.007882677343413932, 0.0003479752209189496, -0.0015383631203022155]
distortion_model: radtan
intrinsics: [237.3156818081089, 238.2197038077451, 316.0410162049171, 252.38010788205997]
resolution: [640, 512]
rostopic: /cam
將 camera 標(biāo)定結(jié)果中的cali_xxx-camchain.yaml 文件 copy 過來即可
- 執(zhí)行標(biāo)定命令
rosrun kalibr kalibr_calibrate_imu_camera --target src/kalibr/config/target.yaml --cam src/kalibr/config/cam.yaml --imu src/kalibr/config/imu.yaml --bag ../bags/cali_usb_imu_cam.bag --show-extraction --bag-from-to 0 100
標(biāo)定時(shí)間可能比較長,而且可能存在失敗的情況,特別是在時(shí)間同步做的不好的設(shè)備上
標(biāo)定結(jié)果也是在 bag 包同級目錄下,如:
cam0:
T_cam_imu:
- [-0.03697027093857613, 0.9985445095030082, -0.039269092275266995, -0.007567328099210491]
- [0.9985327866190276, 0.03846859891770388, 0.038110903218720134, 0.0023090905083560957]
- [0.0395660601218531, -0.03780250571991218, -0.9985016261617846, -0.028580542483764203]
- [0.0, 0.0, 0.0, 1.0]
cam_overlaps: []
camera_model: pinhole
distortion_coeffs: [-0.010970399611674727, -0.024434225797313736, -0.0003202003909780894, 0.0005251524383918446]
distortion_model: radtan
intrinsics: [467.56912932614364, 468.9251463870643, 638.2787884016901, 502.0816266969794]
resolution: [1280, 1024]
rostopic: /cam
timeshift_cam_imu: 0.020715376889773315
在 pdf 結(jié)果里可以看到投影誤差情況,如:

我這個(gè)是一個(gè)較差的 imu設(shè)備,沒有做時(shí)間同步,有較多幀數(shù)據(jù)誤差大于 5 個(gè)像素,不過還好,效果好的幀都集中在 3 個(gè)像素以內(nèi)