kalibr安装采坑过程

2023-05-16

前言

有两种方式进行kalibr标定。一种是编译好的kelibr-cde,另一种是源码编译,使用rosrun运行。我推荐源码安装方式。

一. 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]

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

安装报错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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

kalibr安装采坑过程 的相关文章

随机推荐

  • 【Python源码阅读】PYC 文件剖析

    pyc 文件相信大家见怪不怪 xff0c 大家经常在 pycache 里面见到这些文件 这些文件存储了 python 编译出来的字节码文件 xff0c 还有一些元信息 xff08 例如版本号 xff0c 对应文件的修改时间 xff09 接下
  • 【小米手环7】使用 Zeus + 表盘自定义工具 为小米手环7开发和安装小程序

    有关 Zepp OS Zepp OS 是华米开发的一个 RTOS xff0c 运行在手表 手环等设备上 最新发布的小米手环7 7NFC 搭载的就是由华米研发的 Zepp OS 相比与之前小米手环搭载的 RTOS xff0c Zepp OS
  • 使用memoize解决PEG解析器无法左递归的问题

    本篇文章是个人对 Guido 有关 Packrat PEG 解析器文章的处理左递归部分的理解和总结 左递归 众所周知 xff0c PEG 解析器的一个缺陷就在于无法解析具有左递归的文法 xff0c 而大多数情况下 xff0c CFG 使用左
  • 观测器计算频率与效果对比

    文章目录 速度环内计算 8KHz 速度环内计算 xff0c 加400Hz低通滤波相位延迟 电流环内计算 16KHz 观测器带宽160Hz xff0c 800HzLPF观测器带宽236Hz xff0c 无LPF观测器带宽236Hz xff0c
  • Docker 10张图带你深入理解Docker容器和镜像

    这篇文章希望能够帮助读者深入理解Docker的命令 xff0c 还有容器 xff08 container xff09 和镜像 xff08 image xff09 之间的区别 xff0c 并深入探讨容器和运行中的容器之间的区别 题外话 xff
  • Nginx 多进程模型

    Nginx 整体结构 Nginx运行在企业内网的边缘节点 xff0c 也就是最外层 xff0c 也就是边缘节点 它处理的流量是其他应用服务器处理流量的数倍 xff0c 甚至是几个数量级 在应用场景下所有的问题都会被放大 所以有必要去了解ma
  • 海康威视SDK 整合到springboot(二)

    上篇连接 xff1a 海康威视SDK告警上传功能整合到springboot xff08 一 xff09 上篇的只是兼容Windows系统 xff0c 此篇写兼容windos和Linux的一个整合 还是下载好sdk xff0c 将所需的so文
  • JS手写防抖与节流

    1 概念 xff1a 防抖 xff1a 指定内只执行一次 xff0c 如果指定时间内再次被触发 xff0c 则重新开始计时 实现主要需要利用闭包 xff0c 定时器 xff0c arguments和this指向 xff0c 立即执行 节流
  • QT 读取txt文件的几种方法

    废话不说直接上代码 xff11 xff0e 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 QString displayString QFile file 34 home alvin text txt 34 if
  • socket本地多进程通信基本使用方法和示例

    目录 前言 xff1a socket是什么 socket基本原理框图 socket基本函数 1 socket 函数 2 bind 函数 3 connect 函数 4 listen 函数 5 accept 函数 6 read write se
  • STM32串口读取一帧数据USART_IT_IDLE

    stm32 串口读取数据中断 USART IT RXNE xff1a 读取到一个数据产生中断USART IT IDLE xff1a 读取到一帧数据产生中断 以前串口读取一帧数据的方法 xff1a 收到数据后重置定时器的值 xff0c 等到定
  • Vivado连不上目标板(Target)

    可能是Vivado没把JTAG驱动装上 xff0c JTAG驱动在Vivado安装目录X Xilinx Vivado 2015 4 data xicom cable drivers nt64 digilent xff0c 双击install
  • 图解跨域请求、反向代理原理,对前端更友好的反向代理服务器 - Caddy

    写在开头 本文采用图文解析 结合实战的方式进行网络原理解析 xff0c 帮助大家去掌握一些网络知识 xff0c 并了解 Caddy 的基本使用 xff08 见下图 xff09 本人计划在近几年将持续输出深度好文 xff0c 如果对这类文章感
  • java toString()方法的使用和详解

    java toString方法是使用和详解 1 toString 方法2 通过java lang Object类的toString 定义来看实际使用中会出现什么情况 xff1f 1 toString 方法 toString 方法在Objec
  • vscode使用git

    1 找到项目路径 打开gitbash输入 git config global user name 34 your name 34 git config global user email 34 your email address 34 2
  • Logback

    logback logback 与 log4f出自同一作者 logback是作者对log4j的升级 它实现了slf4j slf4j是 simple log face for java 的缩写 我们要入门logback 搞懂几个核心类就可了
  • 取消与关闭

    取消与关闭 两方面 1 线程池的关闭 线程池的关闭 线程池给了两个方法 一个是shutdown 一个是shutdownnow 前者会把队里的任务给执行完 xff0c 且拒绝再进来的任务 而后者会将队里没有执行的任务返回 xff0c 且让正在
  • Linux 的文件的基本属性

    Linux 的文件的基本属性 1 两个指令 chown 修该所属用户与组合 chmod 修改用户的权限 首先这两个指令很重要 xff0c 我们以后会经常用到 xff0c 其次 xff0c 这两个指令也引出的两个概念 一个文件一定属于某个用户
  • Linux的用户和用户组

    Linux的用户和用户组 两个文件 我们学习Linux的用户和用户组可以从两个文件开始 1 passwd 如上图 这个配置文件 在 etc passwd路径下 每一行表示一个用户 1 1 每一行的结构 user name x uId gId
  • kalibr安装采坑过程

    前言 有两种方式进行kalibr标定 一种是编译好的kelibr cde xff0c 另一种是源码编译 xff0c 使用rosrun运行 我推荐源码安装方式 一 kalibr cde方式 想使用kalibr cde见如下过程 软件 我使用了