将镭神C32激光雷达的PointXYZ数据转化为PointXYZIR格式 - 附代码
之前遇到过“镭神32线激光雷达ROS下运行fromRosMsg()报错 Failed to find match for field “intensity“ 问题”,
当时确定了是镭神C32雷达缺少相应字段,并记录博客【学习记录】镭神32线激光雷达ROS下运行fromRosMsg()报错 Failed to find match for field “intensity“ 问题。
这次写了一个ros的节点代码,接受原始雷达数据,并转化为相应格式。
完整代码:https://github.com/LarryDong/lslidar_PointXYZ2PointXYZIR
说明:是另写了一个节点,接受雷达发出的原始数据,再赋予ring字段的信息,然后再发布带有这个字段的点云。
但原始并没有包括intensity字段,这个信息是丢失的,所以intensity我就瞎补了一个0,至少保证了格式正确。
基本原理
计算每个点对应的角度,看距离激光雷达定义的哪条ring最接近。
如何判断最接近?计算定义的两条ring平均值,如果在左右两个平均值之间,则认为是这个ring。

由于镭神32线雷达有两种角度模式,左边这种均匀分布,直接将角度近似取整就可以,比较简单。但右侧这种不均匀分布的,就需要按照手册给出的角度信息去解算到底属于哪根。
代码说明
首先列出雷达定义的角度,并计算与上一个/下一个线束的平均值。
const vector<float> g_ring_angle = {-18, -15, -12, -10, -8, -7, -6, -5,-4, -3.33, -3, -2.66, -2.33, -2, -1.66, -1.33,-1, -0.66, -0.33, 0, 0.33, 0.66, 1, 1.33, 1.66, 2, 3, 4, 6, 8, 11, 14}; // ring angles defined by leishen
vector<float> g_angle_range; // define a range between each ring angle.void initRingAngleRange(void){// calculate angle rangeassert(RING_NUMBER==g_ring_angle.size());g_angle_range.push_back(-100); // assign a very large valuefor(int i=0; i<RING_NUMBER-1; ++i){float middle_value = (g_ring_angle[i] + g_ring_angle[i + 1]) / 2; // calculate the average value between two ring.g_angle_range.push_back(middle_value);}g_angle_range.push_back(100);
}
然后计算实际角度,并赋予线束id即可:
void lidarCallback(const sensor_msgs::PointCloud2ConstPtr &msg_pc){pcl::PointCloud<pcl::PointXYZ> pc;pcl::PointCloud<myPointXYZIR> pc_new;pcl::fromROSMsg(*msg_pc, pc);// convert to PointXYZIR.pc_new.points.reserve(pc.points.size());myPointXYZIR pt_new;for(const pcl::PointXYZ& p : pc.points){float angle = atan(p.z / sqrt(p.x * p.x + p.y * p.y)) * 180 / M_PI;if(std::isnan(angle)) // remove nan point.continue;// int scanID = int(angle + 17); // 对于1°分辨率的雷达,直接用这行指令就可以了,不需要计算下面的不均匀分布角度。// for 0.33 degree mode.int scanID = -1;for(int i=0; i<RING_NUMBER; ++i){if(angle > g_angle_range[i] && angle <= g_angle_range[i+1]){scanID = i;break;}}pt_new.x = p.x;pt_new.y = p.y;pt_new.z = p.z;pt_new.intensity = 0; // intensity is not used.pt_new.ring = scanID;pc_new.points.push_back(pt_new);}sensor_msgs::PointCloud2 msg_pc_new;pcl::toROSMsg(pc_new, msg_pc_new);msg_pc_new.header.frame_id = "laser_link";msg_pc_new.header.stamp = msg_pc->header.stamp;g_pub_pc.publish(msg_pc_new);ROS_INFO("Published new pointcloud.");}
踩坑记录
- 一开始以为直接将雷达设置为1°模式扫描就可以了,结果发现精度不正常。问了客服才知道1°模式和0.33°模式不能调整。所以无奈,只能再重写这个转换代码。但还行,算的挺对。
- rviz中PointCloud2的
intensity选项,点击后会出现一个channel,还包括XYZ以及intensity等,一开始没搞明白啥意思,说明如下: -
About RViz: If you open a PointCloud2 display and select the “Intensity” color transformer, you can select a channel to display. This doesn’t have to be intensity, it can actually be any channel of your point cloud. If you leave “autocompute intensity bounds” checked, it will compute the min + max for each point cloud separately and scale the color spectrum to that range. If you disable the check box, you can enter min + max intensity manually (good if the min/max varies a lot between point clouds and you want the colors to be consistent between point clouds).
相关文章:
将镭神C32激光雷达的PointXYZ数据转化为PointXYZIR格式 - 附代码
之前遇到过“镭神32线激光雷达ROS下运行fromRosMsg()报错 Failed to find match for field “intensity“ 问题”, 当时确定了是镭神C32雷达缺少相应字段,并记录博客【学习记录】镭神32线激光雷达ROS下运行fromRosMsg()报错 Failed to find match for fi…...
高级前端一面面试题集锦
详细说明 Event loop 众所周知 JS 是门非阻塞单线程语言,因为在最初 JS 就是为了和浏览器交互而诞生的。如果 JS 是门多线程的语言话,我们在多个线程中处理 DOM 就可能会发生问题(一个线程中新加节点,另一个线程中删除节点&#…...
Java基础 -- List集合
Java基础 -- List集合1. Introduction1.1 好处1.2 常用泛型2. 交集,差集等2.1 自身的方法2.2 1.8jdk stream 新特性2.3 Apache的CollectionUtils工具类(推荐)3. 限定泛型范围4. Awakening1. Introduction 1.1 好处 代码复用,多种…...
【Linux】网络编程 - Socket套接字/基于UDP的网络通信
目录 一.套接字 1.什么是套接字/Socket套接字 2.套接字的分类 3.Socket套接字的常见API 二.网络字节序 1.什么是网络字节序 2.网络字节序和主机字节序的转换接口 三.IP地址形式上的转换 四.客户端的套接字不由程序员bind 1.为什么客户端套接字不能由程序员bind 2.OS…...
流程引擎之Camunda简介
背景Camunda 是支持 BPMN(工作流和流程自动化)、CMMN(案例管理) 和 DMN(业务决策管理) java 框架。Camunda 基于Activiti5 保留了 PVM,其开发团队也是从 activiti 中分裂出来的。Camunda 来自拉…...
Mybatis笔记整理
1. 相关文档地址 中文文档 https://mybatis.org/mybatis-3/zh/index.htmlMybatis可以配置成适应多种环境,不过每个SqlSessionFactory实例只能选择一种环境。Mybatis默认事务管理器是JDBC,连接池:POOLEDMaven仓库:下载地址<dependency>…...
【react全家桶】面向组件编程
文章目录02 【面向组件编程】1.组件的使用1.1 函数式组件1.2 类式组件1.3 组合组件1.4 提取组件组件实例的三大属性 state props refs2.state2.1 基本使用2.2 setState()2.3 简化版本2.4 State 的更新可能是异步的2.5 异步更新解决方案2.6 数据是向下流动的3.props3.1 基本使用…...
Django框架之模型视图-使用 PostMan 对请求进行测试
使用 PostMan 对请求进行测试 PostMan 是一款功能强大的网页调试与发送网页 HTTP 请求的 Chrome 插件,可以直接去对我们写出来的路由和视图函数进行调试,作为后端程序员是必须要知道的一个工具。 安装方式1:去 Chrome 商店直接搜索 PostMan…...
(考研湖科大教书匠计算机网络)第五章传输层-第四节:TCP流量控制
获取pdf:密码7281专栏目录首页:【专栏必读】考研湖科大教书匠计算机网络笔记导航 文章目录一:流量控制概述二:流量控制举例三:拓展阅读(可不看)(1)TCP流量控制完整例子&a…...
使用Docker-Compose搭建Redis集群
1. 集群配置3主3从由于仅用于测试,故我这里只用1台服务器进行模拟redis列表2.编写redis.conf在server上创建一个目录用于存放redis集群部署文件。这里我放的路径为/root/redis-cluster 在/opt/docker/redis-cluster目录下创建redis-1,redis-2,redis-3,redis-4,redis…...
华为OD机试 -计算网络信号(Js)
计算网络信号 题目 网络信号经过传递会逐层衰减,且遇到阻隔物无法直接穿透,在此情况下需要计算某个位置的网络信号值。 注意:网络信号可以绕过阻隔物 array[m][n] 的二维数组代表网格地图,array[i][j] = 0代表 i 行 j 列是空旷位置;array[i][j] = x(x 为正整数)代表 i 行 …...
【数据结构】————栈
文章目录前言栈是什么,栈的特点实现栈的基本操作栈的相关操作声明1.创建栈2.对栈进行初始化3.销毁栈4.判断栈是否为空5.压栈操作6.删除栈顶元素7.取出栈顶元素8.计算栈内存放多少个数据总结前言 本文主要讲述特殊的线性表——栈: 栈是什么,栈…...
从零编写linux0.11 - 第十一章 可执行文件
从零编写linux0.11 - 第十一章 可执行文件 编程环境:Ubuntu 20.04、gcc-9.4.0 代码仓库:https://gitee.com/AprilSloan/linux0.11-project linux0.11源码下载(不能直接编译,需进行修改) 本章目标 本章会加载并运行…...
Win10上通过nginx代理配置远程非445端口SMB
引言 家里架了一个SMB文件服务器,想要远程访问,开了445端口,但仅限某些特殊网络可以远程访问,其他网络全部拒绝445端口,因此网上找了很多将Win10的SMB指向别的端口的教程,但所有教程均使用环回网卡解决&am…...
Allegro如何快速清除多余的规则设置操作指导
Allegro如何快速清除多余的规则设置操作指导 在用Allegro做PCB设计的时候,会给PCB设置一些规则,在PCB设计完成之后,可能会有一些没有使用到的规则,如下图 Physical规则中的45OHM的规则是多余的 单独某个规则可以直接在规则管理器中删除,如果比较多可以用下面方法批量删除…...
ROS2 入门应用 引用自定义消息(Python)
ROS2 入门应用 引用自定义消息(Python)1. 查看自定义消息2. 修改话题发布3. 修改话题订阅4. 修改依赖关系5. 编译和运行1. 查看自定义消息 引用在《ROS2 入门应用 创建自定义接口》中自定义的消息Sphere.msg ros2 interface show tutorial_interfaces/…...
SmS-Activate一款好用的短信验证码接收工具
前言 有些国外应用在使用应用上的功能时需要注册账号,由于某种不可抗因素,我们的手机号一般不支持注册,接收不到信息验证码,于是我们可以使用SmS-Activate提供的服务,使用$实现我们的需求(大概一次验证1-5…...
SpringBoot+Elasticsearch按日期实现动态创建索引(分表)
😊 作者: 一恍过去💖 主页: https://blog.csdn.net/zhuocailing3390🎊 社区: Java技术栈交流🎉 主题: SpringBootElasticsearch按日期实现动态创建索引(分表)⏱️ 创作时间&…...
Terraform基础入门 (Infrastructure as Code)
文章目录前言介绍Terraform 术语Terraform 如何工作关于provider安装开启本地缓存demo1(dockernginx)demo2(dockerzookeeperkafka)参考资料前言 像写代码一样管理基础设施。 Terraform 使用较为高级的配置文件语法来描述基础设施,这个特性让你对配置文件进行版本化…...
Redis内存回收
Redis 内存回收 Redis之所以性能很强,最主要的原因是基于内存存储,然而单节点的Redis其内存大小不宜过大,会影响持久化或主从同步性能 可以通过修改配置文件来设置Redis的最大内存 maxmemory <bytes>当内存达到上限时,就…...
BGE-Reranker-v2-m3企业部署:高并发请求压力测试案例
BGE-Reranker-v2-m3企业部署:高并发请求压力测试案例 1. 项目背景与价值 在企业级RAG(检索增强生成)系统中,检索精度直接影响最终的回答质量。传统向量检索虽然快速,但容易受到关键词相似性的干扰,返回大…...
别再让反归一化坑了你!用TensorFlow+Keras做LSTM时序预测的完整避坑指南
LSTM时序预测中的归一化陷阱:从原理到实战的完整解决方案 当你兴奋地看着训练好的LSTM模型在测试集上展现出漂亮的损失曲线,却在最后一步——将预测值还原为业务可理解的单位时栽了跟头,这种挫败感我深有体会。归一化是时序预测的标准预处理步…...
别再手动发卡了!2025新版ZFAKA搭配宝塔面板,30分钟搞定你的专属自动售卡站
2025年ZFAKA自动售卡系统:零基础30分钟搭建全攻略 在数字商品交易日益火爆的今天,手动处理订单不仅效率低下,还容易出错。想象一下凌晨三点被订单提醒吵醒,手忙脚乱地复制卡密发给买家——这种场景对于个体创业者来说再熟悉不过了…...
零基础玩转OpenClaw:Qwen3-32B镜像快速入门5个示例
零基础玩转OpenClaw:Qwen3-32B镜像快速入门5个示例 1. 为什么选择OpenClawQwen3-32B组合? 去年冬天,当我第一次看到同事用自然语言命令电脑自动整理桌面文件时,仿佛打开了新世界的大门。经过两周的折腾,我终于在本地…...
Hi-C数据分析进阶:如何用dcHiC精准识别癌症样本中的区室转换事件?
Hi-C技术解密:从染色质区室动态到癌症表观遗传调控 染色质三维结构研究已成为癌症表观遗传学的前沿领域。随着Hi-C技术的普及,科学家们能够以前所未有的分辨率观察基因组在细胞核内的空间组织形式。本文将深入探讨染色质区室(A/B compartment…...
从标定板到生产线:OpenCV实战工业相机畸变校正全流程
1. 工业相机畸变:产线精度杀手的前世今生 第一次在产线上看到相机拍出来的零件尺寸和实物差了0.5毫米时,我盯着屏幕愣了三分钟——这个误差足以让整个自动化装配线变成废品生产线。工业相机的畸变就像近视眼没戴眼镜,看到的物体位置和形状都…...
MozJPEG色彩空间扩展终极指南:支持RGBX、BGRX等32位格式的完整教程
MozJPEG色彩空间扩展终极指南:支持RGBX、BGRX等32位格式的完整教程 【免费下载链接】mozjpeg Improved JPEG encoder. 项目地址: https://gitcode.com/gh_mirrors/mo/mozjpeg MozJPEG作为libjpeg-turbo的增强版本,不仅提供了卓越的JPEG压缩性能&a…...
终极指南:VSCode Rainbow Fart如何通过Vue.js打造沉浸式编程体验
终极指南:VSCode Rainbow Fart如何通过Vue.js打造沉浸式编程体验 【免费下载链接】vscode-rainbow-fart 一个在你编程时疯狂称赞你的 VSCode 扩展插件 | An VSCode extension that keeps giving you compliment while you are coding, it will checks the keywords …...
Python实战:5分钟搞定睿尔曼机械臂与AGV底盘的Socket通信(附完整代码)
Python实战:5分钟搞定睿尔曼机械臂与AGV底盘的Socket通信(附完整代码) 在工业自动化领域,复合机器人正逐渐成为提升生产效率的关键设备。这类机器人通常由AGV(自动导引运输车)底盘和机械臂组成,…...
Qwen3字幕生成工具实战:快速处理会议录音,输出带时间戳字幕
Qwen3字幕生成工具实战:快速处理会议录音,输出带时间戳字幕 1. 会议录音转字幕的痛点与解决方案 处理会议录音是许多职场人士的日常任务。传统方法需要先听录音,再手动记录内容,最后还要逐句对齐时间轴,整个过程耗时…...
