从零用自己数据跑R3LIVE

news2024/11/17 19:45:07

1、相机内参标定

相机选用4mm的广角相机,相机内参标定选择用最常见的棋盘格方法,首先安装ROS自带的包

sudo apt install ros-melodic-camera-calibration

用usb_cam启动相机后进行标定 。

rosrun camera_calibration cameracalibrator.py --size 8x6 --square 0.06 image:=/uab_cam/image_raw camera:=/camera --no-service-check

--size:标定板的长X宽

--square:棋盘中小格的边长(m)
image:=/... : 订阅图像的话题
camera:=/camera: 相机name

标定完之后,会生成一个内参文件,Intrinsic是相机矩阵,Distortion是畸变矩阵。

Intrinsic:
[430.229,0,306.853],[0,437.83,248.373],[0,0,1]

Distortion:
[0.156215,-0.156542,-0.004833,-0.001379]

2、cam2lidar外参标定

外参标定我采用的是自动+手动的方式,先用算法进行自动配准,再用手动标定修正。

自动标定算法采用的是livox_camera_calib算法

GitHub - hku-mars/livox_camera_calib: This repository is used for automatic calibration between high resolution LiDAR and camera in targetless scenes.

此方法效果较好,但需要特定的场合,经过我的测试,选择深度差距大且平整的场景进行数据采集,例如楼道。

        自动标定算法特别依赖数据的场景,一个好的场景是能够达到不错的标定效果。之后再手动标定进行进一步修正,采用的是 SensorsCalibration,此标定库包含了大多数传感器之间的标定。

https://github.com/PJLab-ADG/SensorsCalibration

最终的标定结果如下图所示。 

标定完之后,会生成一个外参数矩阵

Extrinsic:
[-0.00650189,-0.999724,-0.0225309,0.0946092],[0.0035881,0.0225079,-0.999741,0.162664],[0.999972,-0.00658104,0.00344083,-0.00686066],[0,0,0,1]

3、记录rosbag

之后就可以采集数据了,需要注意的一点是,不同传感器之间的时间同步问题,因为LIVOX默认是从开始启动激光雷达开始算时间的并不是ROS系统时间,如果直接记录数据,是跑不起来的。下面给出两种解决方案。

  • 将激光雷达连接对应的网卡和系统时间同步:

ifconfig  查看网口 比如网口是 eno1

如果出现下列提示,则可以使用硬件同步
 `hardware-raw-clock (SOF_TIMESTAMPING_RAW_HARDWARE)`
 `hardware-transmit (SOF_TIMESTAMPING_TX_HARDWARE)`
 `hardware-recive (SOF_TIMESTAMPING_RX_HARDWARE)`

sudo apt install ptpd
sudo ptpd -M -i eno1 -C 

当出现best master的时候,用wireshark确认一下,

wireshark --  eno1-- 搜索框搜索 ptp -- 出现Sync Message信号

之后再启动激光雷达,时间戳就是和本机同步的。

  • 直接用R3LIVE作者提供的LIVOX驱动

GitHub - ziv-lin/livox_ros_driver_for_R2LIVE

作者之间将时间戳再源码中更改了,所以用这个驱动启动直接记录数据是可行的。再记录之前需要打开livox_lidar_config.json文件中的时间同步功能。并选择一个接口名称,我这里选择的是相机的接口。

再记录数据时,可以记录压缩格式的图像topic,例如usb_cam/image_raw/compressed,这样rosbag会小一点。

4、安装编译R3LIVE

https://github.com/hku-mars/r3live

跟着官网reademe走就可以了,作者写的很详细 。

5、跑结果

主要需要改yaml文件,将得到的相机内参,外参,畸变矩阵填入。注意3*3的旋转矩阵,是4*4的变换矩阵左上3*3部分的转置。再把launch文件的topic改为自己的就可以了。

r3live_vio:
   image_width: 640
   image_height: 480
   camera_intrinsic:
      [460.799008, 0.000000, 280.624145,
    0.000000, 459.386391, 167.344099,
    0.0, 0.0, 1.0] 
   camera_dist_coeffs: [-0.107372, 0.087416, 0.001676, -0.001356, 0.000000]  #k1, k2, p1, p2, k3
   # Fine extrinsic value. form camera-LiDAR calibration.
   #转置矩阵
   camera_ext_R:       
          [-0.00650189,0.0035881,0.999972,
            -0.999724,0.0225079,-0.00658104,
            -0.0225309,  -0.999741,   0.00344083]
   # camera_ext_t: [0.050166, 0.0474116, -0.0312415] 
   camera_ext_t: [0.0946092,0.162664,-0.00686066] 
<launch>
    <!-- Subscribed topics -->
    <param name="LiDAR_pointcloud_topic" type="string" value= "/laser_cloud_flat" />
    <param name="IMU_topic" type="string" value= "/livox/imu" />
    <param name="Image_topic" type="string" value= "/usb_cam/image_raw" />
    <param name="r3live_common/map_output_dir" type="string" value="$(env HOME)/r3live_output" />
    <rosparam command="load" file="$(find r3live)/../config/my_data_r3live_config.yaml" />

    <node pkg="r3live" type="r3live_LiDAR_front_end" name="r3live_LiDAR_front_end"  output="screen" required="true"/>
    <node pkg="r3live" type="r3live_mapping" name="r3live_mapping" output="screen" required="true" />
    
    <arg name="rviz" default="1" />
    <group if="$(arg rviz)">
        <node name="rvizvisualisation" pkg="rviz" type="rviz" output="log" args="-d $(find r3live)/../config/rviz/r3live_rviz_config.rviz" />
    </group>
</launch>

之后 运行就可以建图了。

roslaunch r3live my_data_r3live_bag.launch 

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux】网络编程相关概念介绍、UDP套接字简单演示、最简单的UDP公共聊天室实现~

文章目录 [toc] 网络编程 - 套接字一些概念1. 源ip地址与目的ip地址2. 端口号 和 socket套接字 **问题 3. 源端口号和目的端口号4. 认识TCP协议基本特点5. 认识UDP协议基本特点6. 网络字节序 socket编程接口**struct sockaddr**接口演示: 简单的UDP网络通信int socket()UDP网络…

读书笔记-《ON JAVA 中文版》-摘要18[第十八章 字符串-1]

文章目录 第十八章 字符串1. 字符串的不可变2. 的重载与 StringBuilder3. 意外递归4. 字符串操作5. 格式化输出5.1 printf()5.2 System.out.format()5.3 Formatter 类5.3.1 格式化修饰符5.3.2 Formatter 转换 5.4 String.format() 6. 自我学习总结 第十八章 字符串 字符串操作…

【专题速递】更多的解决方案:传统行业不再「传统」

// 音视频技术作为企业数字化转型的关键技术与能力之一&#xff0c;为众多传统行业在生产、服务、管理与维护等方面提供了强有力的支持。那么&#xff0c;音视频技术是如何助力企业数字化转型的&#xff1f;7月28日LiveVideoStackCon上海站数字化与行业案例专场&#xff0c;为…

【AI】PyTorch安装记录及Anaconda环境配置

【AI】PyTorch安装记录及Anaconda环境配置 说下本地环境&#xff0c;RTX4070 12GB GPU&#xff1b;618刚买&#xff0c;不能让他闲着&#xff0c;配置一下炼丹环境&#xff0c;开始为打工人工作。为了方便后续部署模型之间依赖不冲突&#xff0c;所以使用Anaconda管理Python环…

【数据结构】第 1~10 章:思维导图与重点汇总

目录 一、概论 &#xff08;1&#xff09;思维导图 &#xff08;2&#xff09;常见名词 &#xff08;3&#xff09;数据结构的定义 &#xff08;4&#xff09;抽象数据类型 ADT &#xff08;5&#xff09;算法 &#xff08;6&#xff09;评价算法的好坏的因素 &am…

Python基础 —— 循环语句

如约来更新循环语句了.说到循环&#xff0c;有一定编程基础的小伙伴们都知道&#xff0c;我们最常用的循环莫过于 while循环&#xff0c;for循环和goto循环&#xff08;不过goto也不怎么常用&#xff09;&#xff0c;所以今天就来说一说 while循环和 for循环 来看一下本文大致…

IMX6ULL系统移植篇-uboot基础命令

一. uboot 启动 当设备上电启动时&#xff0c;需要马上按下回车键&#xff0c;开发板启动会停止在 uboot的启动Log信息时刻。 这就是 uboot的命令模式&#xff0c;即可以输入 uboot命令进行一些操作。 二. uboot 基础命令 1. help 命令 当开发板上电启动后&#xff0c;马…

电脑如何设置外网内网一起使用

如果你的电脑支持连接无线网&#xff0c;就可以设置内网外网一起使用。一般情况下&#xff0c;连接无线网还是网线都是系统自动链接的,但有时候开发中需要内网外网一块使用&#xff0c;不用手动切换网络。 首先确保我们的电脑有双网卡&#xff0c;可以两个都是有线网卡&#xf…

【机械臂视觉抓取从理论到实战】

1. 概述 GR-CNN&#xff1a;https://paperswithcode.com/paper/antipodal-robotic-grasping-using-generative 2. 环境搭建及模型训练 GR-CNN&#xff1a;https://github.com/skumra/robotic-grasping 下载源码创建环境 #下载robotic-grasping源码 git clone https://github.…

CVE-2021-3493:Overlay 文件系统 Ubuntu 本地提权漏洞分析

分析此漏洞的文章非常多&#xff0c;在此只是记录一下复现漏洞的过程以及对漏洞的个人理解。Linux 内核漏洞有一定的准入门槛&#xff0c;不适合小白阅读。 基本信息 [影响范围] Ubuntu 14.04 ~20.10 [漏洞描述] Ubuntu 内核代码允许低权限用户在使用 unshare() 函数创建的…

李彦宏:AI原生应用比大模型数量更重要

6月26日&#xff0c;百度创始人、董事长兼首席执行官李彦宏出席“世界互联网大会数字文明尼山对话”&#xff0c;发表了题为 《大模型重塑数字世界》 的演讲。 大模型是当下全球科技创新的焦点&#xff0c;也是全球人工智能竞赛的主战场。李彦宏认为&#xff0c;“新的国际竞争…

箱线图概念和使用介绍

箱线图时一种针对连续型变量的统计图。通常用作比较。 箱子中间的一条线&#xff0c;是数据的中位数&#xff0c;代表了数据的平均水平。 箱子的上限和下限&#xff0c;分别是数据的上四分位数和下四分位数&#xff0c;意味着箱子包含50%的数据。因此&#xff0c;箱子的高度在…

23.RocketMQ之NameServer处理Broker心跳包,更新本地路由信息

NameServer处理Broker心跳包,更新本地路由信息 DefaultRequestProcessor继承自NettyRequestProcessor:处理各种客户端的请求&#xff0c;如果请求类型是为REGISTER_BROKER&#xff0c;则将请求转发到RouteInfoManager#regiesterBroker,主要是服务器端 或者客户端或者broker发送…

go语言环境安装

文章目录 环境介绍安装软件包步骤环境变量设置来一个经典的hello worldNice 最近的项目需要用到go来开发了&#xff0c;前几天就已经在看书了&#xff0c;今天是个周末&#xff0c;先在家里的机器上把环境搭好&#xff0c;特此记录一下。 环境介绍 下载地址&#xff1a;https:…

RRT 算法研究(附 Python / C++ 实现)

RRT 算法研究 参考 机器人路径规划、轨迹优化课程-第五讲-RRT算法原理和代码讲解 机器人路径规划之RRT算法(附C源码) RRT算法(快速拓展随机树)的Python实现 《基于改进RRT算法的路径规划研究》 《面向室内复杂场景的移动机器人快速路径规划算法研究》 理论基础 RRT&#xff0…

meb stm32开发

matlab1028b以上 stm32cubemx5.6.0以上 stm32-mat/target 教程与代码分享 - 知乎 安装好这些后&#xff0c;打开matlab&#xff0c;打开路径STM32-MAT\STM32 打开simulink&#xff0c;view-lib 可以看到 在STM32CUBEMX完成底层配置&#xff0c;生成ioc文件

UI的绘制流程

1.App的启动流程 每个App都是一个独立的进程&#xff0c;当一个app启动的时候&#xff0c;当前进程也被启动&#xff0c;在Android中有一个类ActivityThread&#xff0c;就是进程的初始类&#xff0c;其中main方法就是整个app的入口。ActivityThread并不是一个线程&#xff0c;…

Java并发编程中的JMM、3个基本属性、synchronized和volatile

1、Java内存模型JMM (Java Meemory Model) JMM规定&#xff0c;所有变量均存储在主内存中每个线程都有自己的工作内存&#xff0c;保存了该线程中用到的变量的主内存副本拷贝线程对变量的所有操作&#xff0c;必须在自己的工作内存中&#xff0c;不可直接读写主内存不同线程无法…

2023-6-29-第十一式代理模式

&#x1f37f;*★,*:.☆(&#xffe3;▽&#xffe3;)/$:*.★* &#x1f37f; &#x1f4a5;&#x1f4a5;&#x1f4a5;欢迎来到&#x1f91e;汤姆&#x1f91e;的csdn博文&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f49f;&#x1f49f;喜欢的朋友可以关注一下&#xf…

C++primer(第五版)第八章(IO库)

8.1 IO库 上表中以w开头的类型和函数是C标准库为了支持使用宽字符的语言而定义的一组类型和对象来操纵wchar_t类型的数据.(然而我没有遇到过) 8.1.1 IO对象无拷贝或赋值 IO对象不能拷贝或赋值,通常用引用方式传递和返回流,由于读写一个IO对象回改变其状态,因此传递和返回的引…