【手眼标定】使用kalibr对imu和双目摄像头进行联合标定

使用kalibr对imu和双目摄像头进行联合标定

    • 前言
    • 一、IMU标定
    • 二、双目摄像头标定
    • 三、手眼标定(imu和双目摄像头的联合标定)

前言

由于本文的imu、双目摄像头都是在ros2环境下开发,数据传输自然也是在ros2中。
但想要使用kalibr进行标定,就需要安装ros1,在ros1的环境下录制bag包提供给kalibr进行标定。所以本文在板端同时安装ros1和ros2,使用ros1_bridge允许ROS1节点和ROS2节点在同一个系统中运行,并相互通信,使得ros1环境下可以直接录制ros2发布的话题数据!

一、IMU标定

首先需要自己的系统中能够发布imu数据到某个话题,这里因人而异,我使用的是IMU40609D六轴传感器,对于大部分人应该都是买的成品,或者实验室有现成的,只需要运行某个ros指令能将imu的原始数据发布出来即可。本文使用Allan_Variance_ROS功能包来进行标定,官方建议imu的发布频率是200hz,自己调好即可。

预备:
对于使用ros2开发的小伙伴来说,就需要安装ros1和ros1_bridge。使用ros1开发的小伙伴可以参考其它博主教程,基本上联合标定他们都是在ros1中直接开发的。
①安装ros1,直接使用鱼香ros的命令:

wget http://fishros.com/install -O fishros && . fishros

②安装ros1_bridge,在ros2的环境中执行(source /opt/ros/foxy/setup.bash ):

sudo apt install ros-foxy-ros1-bridge

imu数据录制
需要开启四个终端,ros1,ros2环境都用到
①ros1环境下开启roscore:

source /opt/ros/noetic/setup.bash
roscore

②ros1、ros2环境下运行bridge:

source /opt/ros/foxy/setup.bash
source /opt/ros/noetic/setup.bash
 ros2 run ros1_bridge dynamic_bridge --bridge-all-topics

③ros2环境下运行imu数据发布节点:

source /opt/ros/foxy/setup.bash
source install/setup.bash 
ros2 run imu_test_node imu_test_node              #换成自己的发布数据指令,记住发布数据的话题名称,一会儿录制,发布频率改为200hz

④ros1环境下运行rosbag进行录制:

source /opt/ros/noetic/setup.bash
rosbag record -o imu_rawdata.bag /data       #/data是我imu数据话题,可以先使用ros2 topic hz /data查看发布的频率是否达到200hz

录制三个小时以上即可,在同级目录会生成bag包,后面标定会用到。

imu标定
在ros1环境下进行。开启新终端,安装、编译Allan_Variance_ROS功能包:

source /opt/ros/noetic/setup.bash
mkdir -p ~/imu_calibration_ws/src
cd  ~/imu_calibration_ws/src
git clone https://github.com/ori-drs/allan_variance_ros.git
cd ..
catkin_make
source devel/setup.bash

只需要开启两终端:
①ros1环境下开启roscore:

source /opt/ros/noetic/setup.bash
roscore

②ros1环境下运行Allan_Variance_ROS进行标定:
1、对前面保存的bag按时间戳重新组织 ROS 消息:

rosrun allan_variance_ros cookbag.py --input ../Documents/imu_rawdata_2024-06-22-08-47-14.bag --output imu_cookbag.bag
--input参数:原始数据包的路径--output参数:时间戳排序后的数据包名称

2、查看bag录制时间:

rosbag play --pause ./imu_cookbag.bag
Duration后的数字向下取整即可,后面需要填入yaml文件中

3、在工作空间目录新建config文件夹,文``件夹里新建config.yaml文件,填入:

imu_topic: '/data'                           #imu话题
imu_rate: 200                               #imu发布频率
measure_rate: 200                # Rate to which imu data is subsampled
sequence_time: 24952         #bag包时间

4、运行Allan_Variance_ROS方差计算工具:

rosrun allan_variance_ros allan_variance ./ config/config.yaml
/指的是bag包存放的路径,config/config.yaml是前面新建的yaml的路径。运行结束之后生成的.csv文件保存在当前目录下

5、运行Allan_Variance_ROS可视化绘图并获取参数:

rosrun allan_variance_ros analysis.py --data allan_variance.csv

会在同级目录下生成校准文件imu.yaml和加速度、角速度曲线图。至此imu标定结束!

在这里插入图片描述
在这里插入图片描述

#imu.yaml                       下面的话题和频率需要自己手动改成自己对应的,之后kalibr进行手眼标定时会用到。
#Accelerometer
accelerometer_noise_density: 0.0064937090556434415 
accelerometer_random_walk: 4.0599218203799446e-05 

#Gyroscope
gyroscope_noise_density: 0.005704862739811861 
gyroscope_random_walk: 0.00039076770788208285 

rostopic: '/data #Make sure this is correct
update_rate: 200.0 #Make sure this is correct

二、双目摄像头标定

双目摄像头标定单独写过一篇博客,直接看这篇博客即可:使用kalibr进行双目摄像头标定

三、手眼标定(imu和双目摄像头的联合标定)

板端
板端需要准备四个文件:imu标定参数、双目相机标定参数、标定板yaml、录制imu,双目_imu的bag。
前三个文件是已经有的,分别列出来:
①imu.yaml

#Accelerometer
accelerometer_noise_density: 0.0064937090556434415 
accelerometer_random_walk: 4.0599218203799446e-05 

#Gyroscope
gyroscope_noise_density: 0.005704862739811861 
gyroscope_random_walk: 0.00039076770788208285 

rostopic: '/data #Make sure this is correct
update_rate: 200.0 #Make sure this is correct

②stereo_cam.yaml(使用opencv标定得到的畸变系数和使用kalibr标定得到的畸变系数不一样,多了一个k3,不知道能不能直接用opnecv得到的参数进行标定)

cam0:
  cam_overlaps: [1]
  camera_model: pinhole
  distortion_coeffs: [-0.17969016421219008, 0.05576666461251156, 0.0016209134649260832, 0.0009481489974055125]
  distortion_model: radtan
  intrinsics: [557.1217108511009, 556.8106438635324, 642.3927048356297, 379.35829636447596]
  resolution: [1280, 800]
  rostopic: /image_raw_right
cam1:
  T_cn_cnm1:
  - [0.9998667767511064, 0.0008779927232403428, -0.016299014636997042, 0.06913922407160743]
  - [-0.0009892592697515817, 0.9999762557402679, -0.0068197743201160455, 0.00010461888423681866]
  - [0.01629263991673287, 0.006834989718941845, 0.999843904217099, 0.0018747285708525514]
  - [0.0, 0.0, 0.0, 1.0]
  cam_overlaps: [0]
  camera_model: pinhole
  distortion_coeffs: [-0.18534759506889162, 0.07196655593564935, 0.0015543265305883987, 0.003219336127464086]
  distortion_model: radtan
  intrinsics: [559.8892318701168, 560.5548115446029, 660.5508624473196, 408.46268966459587]
  resolution: [1280, 800]
  rostopic: /image_raw_left

③april_6_6.yaml

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

现在只需要录制双目摄像头和imu的bag即可:
1、ros1环境下开启roscore:

source /opt/ros/noetic/setup.bash
roscore

2、ros1、ros2环境下运行bridge:

source /opt/ros/foxy/setup.bash
source /opt/ros/noetic/setup.bash
 ros2 run ros1_bridge dynamic_bridge --bridge-all-topics

3、ros2环境下运行imu数据发布节点:

source /opt/ros/foxy/setup.bash
source install/setup.bash 
ros2 run imu_test_node imu_test_node              #换成自己的发布数据指令,记住发布数据的话题名称,一会儿录制,发布频率改为200hz

4、ros2环境下运行双目摄像头发布节点:

source /opt/ros/foxy/setup.bash
source install/setup.bash 
 ros2 launch hobot_t1_cam mipi_cam.launch.py mipi_out_format:=bgr8 mipi_io_method:=ros mipi_framerate:=4              #换成自己的发布数据指令,记住发布数据的话题名称,一会儿录制,相机发布频率改为4hz

5、ros1环境下运行rosbag进行录制:

source /opt/ros/noetic/setup.bash
 rosbag record /data /image_raw_right /image_raw_left -O imu_stereo.bag       #/data是imu数据话题, /image_raw_right /image_raw_left分别是右左相机的话题

录制的要点是绕偏航、俯仰、翻滚3个轴旋转,上下左右前后平移,再加一些随机动作,官方给出了示例视频,有人搬运到了b站:
https://www.bilibili.com/video/av795841344/?vd_source=2a10d30b8351190ea06d85c5d0bfcb2a
录制完成之后就可以标定了。

虚拟机ubuntu端
由于手眼标定是很耗时的,并且板端不知道要跑多久,所以在虚拟机中进行。虚拟机中配置也参考双目摄像头标定那篇文章,按照里面装好kalibr,现在再安装一些手眼标定会用到的依赖:

sudo apt-get install python-setuptools python-rosinstall ipython libeigen3-dev libboost-all-dev doxygen libopencv-dev

sudo apt-get install libopencv-dev ros-melodic-vision-opencv ros-melodic-image-transport-plugins ros-melodic-cmake-modules software-properties-common libpoco-dev python-matplotlib python-scipy python-git python-pip libtbb-dev libblas-dev liblapack-dev python-catkin-tools libv4l-dev

 sudo apt install libgtk-3-dev
 
 pip install numpy==1.21
 
 pip install wxPython

安装结束之后虚拟机端就配置好了。
进入kalibr工作空间,在里面创建config文件夹,随便哪都行,后面运行时会指定路径,将上面的四个文件拷贝到config文件夹中,终端首先开一个roscore,另一个在工作空间中执行:

rosrun kalibr kalibr_calibrate_imu_camera --target src/kalibr/april_6_6.yaml --cam src/kalibr/cam_chain.yaml --imu src/kalibr/imu.yaml --bag src/kalibr/stereocam_imu.bag --timeoffset-padding 0.1

将上述的yaml文件和bag文件路径换成自己的即可。由于第一次报了优化相关错误,所以在命令最后加上–timeoffset-padding 0.1,后面这个数字越大计算时间越久,0.1大概一个半小时。由于电脑和bag的情况不一样,0.1并不适用,如果继续报优化相关错误就增大,如果报内存溢出就减小。
标定结束后会生成xxx-camchain-imucam.yaml,xxx-report-imu.yaml,xxx-report-imucam.pdf,xxx-results-imucam.txt 四个文件。其中.txt文件中的部分结果,最重要的是相机与imu的变换矩阵(相机到IMU(T_ci),IMU到相机都有(T_ic))

Calibration results
===================
Normalized Residuals
----------------------------
Reprojection error (cam0):     mean 0.392266281765, median 0.369929098336, std: 0.19958606249
Reprojection error (cam1):     mean 0.375133761186, median 0.359180980381, std: 0.184717708985
Gyroscope error (imu0):        mean 3.8491659049e-10, median 7.60223123076e-13, std: 6.26981798021e-09
Accelerometer error (imu0):    mean 3.87002731774e-09, median 2.88022512412e-11, std: 1.04950189834e-07

Residuals
----------------------------
Reprojection error (cam0) [px]:     mean 0.392266281765, median 0.369929098336, std: 0.19958606249
Reprojection error (cam1) [px]:     mean 0.375133761186, median 0.359180980381, std: 0.184717708985
Gyroscope error (imu0) [rad/s]:     mean 1.98542432638e-11, median 3.9212793611e-14, std: 3.23401210741e-10
Accelerometer error (imu0) [m/s^2]: mean 4.82519529359e-11, median 3.59109834953e-13, std: 1.30853123368e-09

Transformation (cam0):
-----------------------
T_ci:  (imu0 to cam0): 
[[-0.99979884 -0.01950712  0.00466432 -0.00049002]
 [ 0.01951878 -0.99980645  0.00246575 -0.00055285]
 [ 0.00461532  0.0025563   0.99998608  0.00016617]
 [ 0.          0.          0.          1.        ]]

T_ic:  (cam0 to imu0): 
[[-0.99979884  0.01951878  0.00461532 -0.0004799 ]
 [-0.01950712 -0.99980645  0.0025563  -0.00056272]
 [ 0.00466432  0.00246575  0.99998608 -0.00016252]
 [ 0.          0.          0.          1.        ]]

timeshift cam0 to imu0: [s] (t_imu = t_cam + shift)
-0.0552938932701


Transformation (cam1):
-----------------------
T_ci:  (imu0 to cam1): 
[[-0.99972373 -0.02042401 -0.01163292  0.06864607]
 [ 0.0204759  -0.99978085 -0.0043586  -0.00044886]
 [-0.01154135 -0.00459559  0.99992284  0.00202911]
 [ 0.          0.          0.          1.        ]]

T_ic:  (cam1 to imu0): 
[[-0.99972373  0.0204759  -0.01154135  0.06865972]
 [-0.02042401 -0.99978085 -0.00459559  0.00096259]
 [-0.01163292 -0.0043586   0.99992284 -0.00123236]
 [ 0.          0.          0.          1.        ]]

timeshift cam1 to imu0: [s] (t_imu = t_cam + shift)
-0.102528581781

Baselines:
----------
Baseline (cam0 to cam1): 
[[ 0.99986678  0.00087799 -0.01629901  0.06913922]
 [-0.00098926  0.99997626 -0.00681977  0.00010462]
 [ 0.01629264  0.00683499  0.9998439   0.00187473]
 [ 0.          0.          0.          1.        ]]
baseline norm:  0.0691647154086 [m]


Gravity vector in target coords: [m/s^2]
[ 0.40446197 -9.78898103  0.42506912]


Calibration configuration
=========================

cam0
-----
  Camera model: pinhole
  Focal length: [557.1217108511009, 556.8106438635324]
  Principal point: [642.3927048356297, 379.35829636447596]
  Distortion model: radtan
  Distortion coefficients: [-0.17969016421219008, 0.05576666461251156, 0.0016209134649260832, 0.0009481489974055125]
  Type: aprilgrid
  Tags: 
    Rows: 6
    Cols: 6
    Size: 0.021 [m]
    Spacing 0.006000204 [m]

cam1
-----
  Camera model: pinhole
  Focal length: [559.8892318701168, 560.5548115446029]
  Principal point: [660.5508624473196, 408.46268966459587]
  Distortion model: radtan
  Distortion coefficients: [-0.18534759506889162, 0.07196655593564935, 0.0015543265305883987, 0.003219336127464086]
  Type: aprilgrid
  Tags: 
    Rows: 6
    Cols: 6
    Size: 0.021 [m]
    Spacing 0.006000204 [m]



IMU configuration
=================

IMU0:
 ----------------------------
  Model: calibrated
  Update rate: 10.0
  Accelerometer:
    Noise density: 0.00394276474817 
    Noise density (discrete): 0.0124681168824 
    Random walk: 3.18793819883e-05
  Gyroscope:
    Noise density: 0.016311229883
    Noise density (discrete): 0.0515806378689 
    Random walk: 0.000282102576474
  T_ib (imu0 to imu0)
    [[ 1.  0.  0.  0.]
     [ 0.  1.  0.  0.]
     [ 0.  0.  1.  0.]
     [ 0.  0.  0.  1.]]
  time offset with respect to IMU0: 0.0 [s]


在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/746381.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Power BI 插件 DAX Studio 安装配置

1,dax studio 下载地址 DAX Studio | DAX Studio 2,安装配置(几乎是默认) 3,使用方法 打开DAX studio 默认支持Power povit, PBI/SSDT ,Tabular server。先打开PBI再打开DAX studio ,不然如果只打开Dax …

ios18开发者预览,Beta 2升级新增镜像等功能

近日,苹果发布了 iOS 18 开发者预览版 Beta 2 升级,为 iPhone 用户带来了多项新功能。据了解,这些新功能包括 iPhone 镜像和 SharePlay 屏幕共享,以及其他新增功能。 据了解,iPhone镜像可以让Mac用户将iPhone屏幕镜像…

IPFoxy Tips:匿名海外代理IP的使用方法及注意事项

在互联网上,隐私和安全问题一直备受关注。为了保护个人隐私和数据安全,使用匿名代理IP是一种常用的方法。匿名代理IP可以隐藏用户的真实IP地址,使用户在访问网站时更加隐秘和安全。 本文将介绍匿名代理IP的基本原理和核心功能。 基本原则 匿…

【云原生】Docker可视化工具Portainer使用详解

目录 一、前言 二、docker可视化管理概述​​​​​​​ 2.1 什么是docker可视化管理 2.1.1 Docker可视化管理常用功能 2.2 为什么需要docker可视化管理工具 2.3 docker可视化工具带来的好处 三、常用的docker容器可视化管理工具解决方案 3.1 Portainer 3.2 Rancher 3…

作 业 二

cs与msf权限传递 1、进入cs界面,首先来到 Cobalt Strike 目录下,启动 Cobalt Strike 服务端 2、用客户端进 3、建立监听 4、生成脚本文件 5、开启服务,让win_2012 下载木马文件并运行 6、显示已经获取到了win的权限 转到Metasploit Framework 7、进去m…

6 序列数据和文本的深度学习

6.1 使用文本数据 文本是常用的序列化数据类型之一。文本数据可以看作是一个字符序列或词的序列。对大多数问题,我们都将文本看作词序列。深度学习序列模型(如RNN及其变体)能够从文本数据中学习重要的模式。这些模式可以解决类似以下领域中的问题: 自然…

vface贴图使用说明

第一部分:01_head 说明 geos:几何体正常导入DCC软件即可; maps:重点说明: ID_mask:做头部区域细节区分控制的遮罩图;官方有详细教程; XYZ_albedo_lin_srgb.1001.exr 颜色贴图正常使用即可&…

【曦灵平台】深度体验百度智能云曦灵平台之数字人3.0、声音克隆、直播等功能,AI加持就是不一样,快来一起体验

目录 资产数字人 2D数字人克隆声音克隆 AI卡片更多功能总结推荐文章 资产 可进行人像与声音的定制,让数字人形象和声音成为我们的专属资产,用于后续的内容生产工作 数字人 这里拍摄的视频分辨率和帧率必须要确保是官方要求,这里博主通过第…

再谈kettle两种循环之--调用http分页接口循环获取数据

再谈kettle两种循环之 – 调用http分页接口循环获取数据 1.场景介绍: 由于数据量比较大,接口有返回限制,需要用到循环分页获取数据 2.案例适用范围: 循环job可参考,变量运用可参考,调用http分页接口循环获取数据可参考&#…

【idea-jdk1.8】使用Spring Initializr 创建 Spring Boot项目没有JDK8

信息差真可怕! 很久没创建springboot项目,今天使用idea的Spring Initializr 创建 Spring Boot项目时,发现java版本里,无法选择jdk1.8,只有17、21、22;前段时间也听说过,springboot将放弃java8&a…

Java面试问题(一)

一.Java语言具有的哪些特点 1.Java是纯面向对象语言,能够直接反应现实生活中的对象 2.具有平台无关性,利用Java虚拟机运行字节码文件,无论是在window、Linux还是macOS等其他平台对Java程序进行编译,编译后的程序可在其他平台上运行…

深入理解计算机系统 CSAPP 家庭作业7.13

用一下496页提到的工具咯 A: whereis libm.a file lidm.a gedit libm.a libm.a是个ASCII text文件打开一看原来 libm-2.27.a 和libmvec.a才是我们要看的 所以我们cd到目标地址后 ar -t libm-2.27.a ar -t libmvec.a B: gcc -Og bar5.c foo5.c 用之前的两个文件链接后生成…

使用AI机器学习,轻松解决化合物配比优化问题

为什么需要化合物配比的优化? 在化合物制造行业中,化合物的配比是产品质量控制的关键环节。 化合物制造流程 目前,这一过程高度依赖于材料专家和工程技术人员的经验,通过反复试验来验证产品性能,确保其满足市场和客户的…

JavaWeb系列八: WEB 开发通信协议(HTTP协议)

HTTP协议 官方文档什么是HTTP协议快速入门页面请求的一个问题(分析)http请求包分析(get)http请求包分析(post)GET请求 POST请求分别有哪些http响应包分析常用的状态码说明状态码200状态码404状态码500状态码302状态码304 MIME类型MIME介绍常见的 MIME 类型 官方文档 HTTP常见请…

一家大型银行的电子课程示例

Logrus IT的专家为最大的金融公司之一开发了一门课程,作为一个交互式路线图,向用户介绍公司的业务部门。我们的设计师以企业风格创造了独特的布局,每个课程模块都被创造性地表示为一个单独的建筑。用户可以在部门之间进行非线性导航&#xff…

Java基础:常用类(四)

Java基础:常用类(四) 文章目录 Java基础:常用类(四)1. String字符串类1.1 简介1.2 创建方式1.3 构造方法1.4 连接操作符1.5 常用方法 2. StringBuffer和StringBuilder类2.1 StringBuffer类2.1.1 简介2.1.2 …

编程设计思想

健康检查脚本 nmap:扫描端口 while true do healthycurl B:httpPORT/healthy -i | grep HTTP/1.1 | tail -n 1 | awk {print $2} done 批量操作类型脚本(记录每一步日志) 将100个nginx:vn推送到harbor仓库192.168.0.100 根据镜像对比sha值…

jdk1.8升级到jdk11遇到的各种问题

一、第三方依赖使用了BASE64Decoder 如果项目中使用了这个类 sun.misc.BASE64Decoder,就会导致错误,因为再jdk11中,该类已经被删除。 Caused by: java.lang.NoClassDefFoundError: sun/misc/BASE64Encoder 当然这个类也有替换方式&#xf…

mysql查询2个日期之间的数据,表字段只有年和月,无日期字段查询的解决

1.核心mysql查询 SELECT * FROM 表名 WHERE CONCAT(year, -, LPAD(month, 2, 0)) > 2022-02-08 AND CONCAT(year, -, LPAD(month, 2, 0)) < 2024-06-06;2.表结构 CREATE TABLE ys_datezzq (id int(10) NOT NULL AUTO_INCREMENT,bid int(10) NOT NULL DEFAULT 0 COMMEN…

海外云服务器与传统服务器的对比与选择

在信息技术快速发展的今天&#xff0c;海外云服务器和传统服务器成为企业和个人用户的两大选择。它们各有优势&#xff0c;适用于不同的使用场景和需求。下面&#xff0c;我们将从多个角度对这两种服务器进行深入对比&#xff0c;帮助您做出更明智的决策。 基础设施 海外云服务…