点云格式转换:将 ros PointCloud2格式数据转为livox CustomMsg格式

2023-12-16 08:28

本文主要是介绍点云格式转换:将 ros PointCloud2格式数据转为livox CustomMsg格式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

将 ros PointCloud2格式数据转为livox CustomMsg格式

  • 前言
  • 点云格式
    • PointCloud2 点云格式
    • livox CustomMsg 点云格式
  • 将 ros PointCloud2格式数据转为livox CustomMsg格式
  • 测试

前言

览沃科技有限公司(Livox)成立于2016年。为了革新激光雷达行业,Livox致力于提供高性能、低成本的激光雷达传感器。通过降低使用门槛和生产成本,Livox将激光雷达技术集成到更多产品和应用之中,从而为自动驾驶、智慧城市、测绘、移动机器人等行业带来创新性改变。Livox产品已销往包括美国、加拿大、中国、日本和欧盟在内的 26 个国家和地区。

面向智能移动机器人市场,Livox 推出最新一代 3D 激光雷达 Mid-360,开启混合固态激光雷达 360° 立体感知新篇章。凭借小巧体积,Mid-360 的安装布置更加灵活。同时,Mid-360 充分考虑了移动机器人对导航、避障等升维感知的需求,兼容室内外场景,赋能移动机器人进入空间智能感知新时代。 但是这款产品官网一直购买不到, 本篇博客 在 gazebo 中 可实现对该激光雷达的仿真 。

传统激光雷达普遍采用机械扫描方式,扫描路径随时间重复。而Livox 激光雷达采用了独特的扫描⽅式,扫描路径不会重复。在非重复扫描方式中,视场中被激光照射到的区域面积会随时间增大,这意味着视场覆盖率随时间推移而显著提高,可减小视场内物体被漏检的概率,有助于探测视场中的更多细节。
在这里插入图片描述
下图中给出了一个直观的例子。(a)图由于采用了非重复扫描方式,随着时间的积累,视场覆盖率逐渐升高。而(b)图,由于扫描每次都是重复的,视场覆盖率几乎没有提升。

gazebo中自带的laser插件是上图中b的方式,并不能代表livox的这种雷达。

livox 的仿真功能包(livox_laser_simulation)中 提供了 多种半固体的雷达仿真模型,可以在gazebo中进行该雷达的仿真与其扫描方式(非重复式扫描)点云发布。

但是经过测试发现 livox_laser_simulation 雷达仿真功能包发布的是 ros PointCloud2 点云格式数据。

而现在针对livox雷达的激光slam算法用的是 livox CustomMsg 点云格式数据,例如 Fast-Lio2 、Faster-Lio 、Lio-livox等。所以想在gazebo中仿真这些算法,需要将 ros PointCloud2格式数据转为livox CustomMsg格式 。

点云格式

PointCloud2 点云格式

PointCloud2 是ros的一种点云格式

具体官方数据 http://docs.ros.org/en/jade/api/sensor_msgs/html/msg/PointCloud2.html

std_msgs/Header headeruint32 seqtime stampstring frame_id
uint32 height
uint32 width
sensor_msgs/PointField[] fieldsuint8 INT8=1uint8 UINT8=2uint8 INT16=3uint8 UINT16=4uint8 INT32=5uint8 UINT32=6uint8 FLOAT32=7uint8 FLOAT64=8string nameuint32 offsetuint8 datatypeuint32 count
bool is_bigendian
uint32 point_step
uint32 row_step
uint8[] data
bool is_dense

一个仿真的点云消息长这样

header:  // 点云的头信息seq: 963 //stamp:  // 时间戳secs: 1541143772nsecs: 912011000frame_id: "/camera_init"
height: 1   // If the cloud is unordered, height is 1  如果cloud 是无序的 height 是 1
width: 852578  //点云的长度
fields:  //  sensor_msgs/PointField[] fields - name: "x"offset: 0datatype: 7 	// 	uint8 INT8    = 1//	uint8 UINT8   = 2//	uint8 INT16   = 3//	uint8 UINT16  = 4//	uint8 INT32   = 5//	uint8 UINT32  = 6//	uint8 FLOAT32 = 7//	uint8 FLOAT64 = 8count: 1- name: "y"offset: 4datatype: 7count: 1- name: "z"offset: 8datatype: 7count: 1- name: "intensity"offset: 16datatype: 7count: 1
is_bigendian: False
point_step: 32 // Length of a point in bytes 一个点占的比特数 
row_step: 27282496 // Length of a row in bytes 一行的长度占用的比特数
data: [ .......................................................... ] //  Actual point data, size is (row_step*height)
is_dense: True // 没有非法数据点

livox CustomMsg 点云格式

CustomMsg 是 livox雷达的 专有的点云格式,其格式如下:

Header header             # ROS standard message header
uint64 timebase          # The time of first point
uint32 point_num      # Total number of pointclouds
uint8 lidar_id               # Lidar device id number
uint8[3] rsvd                 # Reserved use
CustomPoint[] points    # Pointcloud data

上述自定义数据包中的自定义点云(CustomPoint)格式 :

uint32 offset_time      # offset time relative to the base time
float32 x               # X axis, unit:m
float32 y               # Y axis, unit:m
float32 z               # Z axis, unit:m
uint8 reflectivity      # reflectivity, 0~255
uint8 tag               # livox tag
uint8 line              # laser number in lidar
  • line
    最后一行line是激光雷达扫描的线数(livox avia为6线),从原始扫描点云可以看出,后期可以按线来对原始点处理、筛选
  • tag
    tag: 主要指示多回波信息及噪点信息。是一个二进制表达,标记信息的格式如下:bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0

bit7 bit6 保留位

bit5 bit4 回波序号 : 00: 第 0 个回波 01: 第 1 个回波 10: 第 2 个回波 11: 第 3 个回波 由于Livox Avia 采用同轴光路,即使外部无被测物体,其内部的光学系统也会产生一个回波,该回波记为第 0个回波。随后,若激光出射方向存在可被探测的物体,则最先返回系统的激光回波记为第 1 个回波,随后为第 2个回波,以此类推。如果被探测物体距离过近(例如 1.5 m),第 1 个回波将会融合到第 0 个回波里,该回波记为第 0 个回波。

bit3 bit2 基于强度的点属性: 00:正常点 01:回波能量噪点置信度高 10:回波能量噪点置信度中 11:保留位
基于回波能量强度判断采样点是否为噪点。通常情况下,激光光束受到类似灰尘、雨雾、雪等干扰产生的噪点的回波能量很小。目前按照回波能量强度大小将噪点置信度分为二档:01表示回波能量很弱,这类采样点有较高概率为噪点,例如灰尘点;10表示回波能量中等,该类采样点有中等概率为噪点,例如雨雾噪点。噪点置信度越低,说明该点是噪点的可能性越低。

bit1 bit0 基于空间位置的点属性 : 00:正常点 01:空间噪点置信度高 10:空间噪点置信度中 11:空间噪点置信度低
基于采样点的空间位置判断是否为噪点。例如,激光探测测距仪在测量前后两个距离十分相近的物体时,两个物体之间可能会产生拉丝状的噪点。目前按照不同的噪点置信度分为三档,噪点置信度越低,说明该点是噪点的可能性越低。

  • offset_time
    时间戳
    点云数据及 IMU 数据中都包含时间戳信息。

  • reflectivity
    目标反射率
    目标反射率:以 0 至 255 表示。其中 0 至 150 对应反射率介于 0 至 100% 的漫散射物体;而 151 至255 对应全反射物体。

  • x y z
    坐标信息:Livox Avia 的坐标信息可表示为直角坐标(x, y, z)或球坐标(r, θ, φ)。如果前方无被探测物体或者被探测物体超出量程范围(例如 600 m),在直角坐标系下,点云输出为(0,0,0);在球坐标系下,点云输出为(0,θ, φ)。

将 ros PointCloud2格式数据转为livox CustomMsg格式

为了使 livox_laser_simulation 功能包可以输出 CustomMsg 格式数据用于 fast-lio仿真,需要对其代码进行修改。主要是livox_laser_simulation/src/livox_points_plugin.cpp 这个文件。

重新编写这个函数

void LivoxPointsPlugin::OnNewLaserScans()

前面的这些可以不变

    if (rayShape) {std::vector<std::pair<int, AviaRotateInfo>> points_pair;InitializeRays(points_pair, rayShape);rayShape->Update();msgs::Set(laserMsg.mutable_time(), world->SimTime());msgs::LaserScan *scan = laserMsg.mutable_scan();InitializeScan(scan);SendRosTf(parentEntity->WorldPose(), world->Name(), raySensor->ParentName());auto rayCount = RayCount();auto verticalRayCount = VerticalRayCount();auto angle_min = AngleMin().Radian();auto angle_incre = AngleResolution();auto verticle_min = VerticalAngleMin().Radian();auto verticle_incre = VerticalAngleResolution();

声明要发布的 custom格式的livox 点云

        livox_ros_driver::CustomMsg pp_livox;//声明要发布的 custom格式的livox 点云

赋值点云帧头

        // 赋值点云帧头pp_livox.header.stamp = ros::Time::now();//时间pp_livox.header.frame_id = "livox";//坐标系int count = 0;

用 high_resolution_clock 记录 起始时间

        boost::chrono::high_resolution_clock::time_point start_time = boost::chrono::high_resolution_clock::now();

遍历每个点

        for (auto &pair : points_pair){

获得点的距离

            auto range = rayShape->GetRange(pair.first);

获得点的强度

            auto intensity = rayShape->GetRetro(pair.first);

最大最小距离限制

            if (range >= RangeMax()) {range = 0;} else if (range <= RangeMin()) {range = 0;}

将极坐标转为x y z

            auto rotate_info = pair.second;// 将极坐标转为x y  z ignition::math::Quaterniond ray;ray.Euler(ignition::math::Vector3d(0.0, rotate_info.zenith, rotate_info.azimuth));auto axis = ray * ignition::math::Vector3d(1.0, 0.0, 0.0);auto point = range * axis;

声明一个 Custom 点

livox_ros_driver::CustomPoint p;//声明一个 Custom 点

赋值坐标

            p.x = point.X();p.y = point.Y();p.z = point.Z();

赋值强度

 p.reflectivity = intensity;

计算当前点时间到起始时间差

            boost::chrono::high_resolution_clock::time_point end_time = boost::chrono::high_resolution_clock::now();// 当前点时间boost::chrono::nanoseconds elapsed_time = boost::chrono::duration_cast<boost::chrono::nanoseconds>(end_time - start_time);

赋值偏移时间

p.offset_time = elapsed_time.count();

将当前点存入点云中

pp_livox.points.push_back(p);
// 计点个数的计数器加1
count ++;
}//结束遍历每个点

赋值点云中点的个数

        pp_livox.point_num = count;

发布点云

        livox_pub.publish(pp_livox);ros::spinOnce();}

测试

将功能包进行编译,需要引入 livox_ros_driver 功能包

find_package(catkin REQUIRED COMPONENTSroscpptflivox_ros_driver  # 新增
)

包含头文件

#include <livox_ros_driver/CustomMsg.h>

完成编译后启动仿真环境
在这里插入图片描述
产看当前话题名
可以看到这个 /livox/lidar 话题名

查看这个话题信息

rostopic info /livox/lidar

在这里插入图片描述

jk-jone@JKKC:~$ rostopic info /livox/lidar
Type: livox_ros_driver/CustomMsg
Publishers:
/gazebo (http://JKKC:38793/)
Subscribers: None

消息类型改成了 livox_ros_driver/CustomMsg

这篇关于点云格式转换:将 ros PointCloud2格式数据转为livox CustomMsg格式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/499829

相关文章

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

Hadoop集群数据均衡之磁盘间数据均衡

生产环境,由于硬盘空间不足,往往需要增加一块硬盘。刚加载的硬盘没有数据时,可以执行磁盘数据均衡命令。(Hadoop3.x新特性) plan后面带的节点的名字必须是已经存在的,并且是需要均衡的节点。 如果节点不存在,会报如下错误: 如果节点只有一个硬盘的话,不会创建均衡计划: (1)生成均衡计划 hdfs diskbalancer -plan hadoop102 (2)执行均衡计划 hd

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

烟火目标检测数据集 7800张 烟火检测 带标注 voc yolo

一个包含7800张带标注图像的数据集,专门用于烟火目标检测,是一个非常有价值的资源,尤其对于那些致力于公共安全、事件管理和烟花表演监控等领域的人士而言。下面是对此数据集的一个详细介绍: 数据集名称:烟火目标检测数据集 数据集规模: 图片数量:7800张类别:主要包含烟火类目标,可能还包括其他相关类别,如烟火发射装置、背景等。格式:图像文件通常为JPEG或PNG格式;标注文件可能为X

pandas数据过滤

Pandas 数据过滤方法 Pandas 提供了多种方法来过滤数据,可以根据不同的条件进行筛选。以下是一些常见的 Pandas 数据过滤方法,结合实例进行讲解,希望能帮你快速理解。 1. 基于条件筛选行 可以使用布尔索引来根据条件过滤行。 import pandas as pd# 创建示例数据data = {'Name': ['Alice', 'Bob', 'Charlie', 'Dav

2、PF-Net点云补全

2、PF-Net 点云补全 PF-Net论文链接:PF-Net PF-Net (Point Fractal Network for 3D Point Cloud Completion)是一种专门为三维点云补全设计的深度学习模型。点云补全实际上和图片补全是一个逻辑,都是采用GAN模型的思想来进行补全,在图片补全中,将部分像素点删除并且标记,然后卷积特征提取预测、判别器判别,来训练模型,生成的像