当前位置: 首页 > news >正文

将镭神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“ 问题”&#xff0c; 当时确定了是镭神C32雷达缺少相应字段&#xff0c;并记录博客【学习记录】镭神32线激光雷达ROS下运行fromRosMsg()报错 Failed to find match for fi…...

高级前端一面面试题集锦

详细说明 Event loop 众所周知 JS 是门非阻塞单线程语言&#xff0c;因为在最初 JS 就是为了和浏览器交互而诞生的。如果 JS 是门多线程的语言话&#xff0c;我们在多个线程中处理 DOM 就可能会发生问题&#xff08;一个线程中新加节点&#xff0c;另一个线程中删除节点&#…...

Java基础 -- List集合

Java基础 -- List集合1. Introduction1.1 好处1.2 常用泛型2. 交集&#xff0c;差集等2.1 自身的方法2.2 1.8jdk stream 新特性2.3 Apache的CollectionUtils工具类&#xff08;推荐&#xff09;3. 限定泛型范围4. Awakening1. Introduction 1.1 好处 代码复用&#xff0c;多种…...

【Linux】网络编程 - Socket套接字/基于UDP的网络通信

目录 一.套接字 1.什么是套接字/Socket套接字 2.套接字的分类 3.Socket套接字的常见API 二.网络字节序 1.什么是网络字节序 2.网络字节序和主机字节序的转换接口 三.IP地址形式上的转换 四.客户端的套接字不由程序员bind 1.为什么客户端套接字不能由程序员bind 2.OS…...

流程引擎之Camunda简介

背景Camunda 是支持 BPMN&#xff08;工作流和流程自动化&#xff09;、CMMN&#xff08;案例管理&#xff09; 和 DMN&#xff08;业务决策管理&#xff09; java 框架。Camunda 基于Activiti5 保留了 PVM&#xff0c;其开发团队也是从 activiti 中分裂出来的。Camunda 来自拉…...

Mybatis笔记整理

1. 相关文档地址 中文文档 https://mybatis.org/mybatis-3/zh/index.htmlMybatis可以配置成适应多种环境&#xff0c;不过每个SqlSessionFactory实例只能选择一种环境。Mybatis默认事务管理器是JDBC&#xff0c;连接池&#xff1a;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 插件&#xff0c;可以直接去对我们写出来的路由和视图函数进行调试&#xff0c;作为后端程序员是必须要知道的一个工具。 安装方式1&#xff1a;去 Chrome 商店直接搜索 PostMan…...

(考研湖科大教书匠计算机网络)第五章传输层-第四节:TCP流量控制

获取pdf&#xff1a;密码7281专栏目录首页&#xff1a;【专栏必读】考研湖科大教书匠计算机网络笔记导航 文章目录一&#xff1a;流量控制概述二&#xff1a;流量控制举例三&#xff1a;拓展阅读&#xff08;可不看&#xff09;&#xff08;1&#xff09;TCP流量控制完整例子&a…...

使用Docker-Compose搭建Redis集群

1. 集群配置3主3从由于仅用于测试&#xff0c;故我这里只用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 行 …...

【数据结构】————栈

文章目录前言栈是什么&#xff0c;栈的特点实现栈的基本操作栈的相关操作声明1.创建栈2.对栈进行初始化3.销毁栈4.判断栈是否为空5.压栈操作6.删除栈顶元素7.取出栈顶元素8.计算栈内存放多少个数据总结前言 本文主要讲述特殊的线性表——栈&#xff1a; 栈是什么&#xff0c;栈…...

从零编写linux0.11 - 第十一章 可执行文件

从零编写linux0.11 - 第十一章 可执行文件 编程环境&#xff1a;Ubuntu 20.04、gcc-9.4.0 代码仓库&#xff1a;https://gitee.com/AprilSloan/linux0.11-project linux0.11源码下载&#xff08;不能直接编译&#xff0c;需进行修改&#xff09; 本章目标 本章会加载并运行…...

Win10上通过nginx代理配置远程非445端口SMB

引言 家里架了一个SMB文件服务器&#xff0c;想要远程访问&#xff0c;开了445端口&#xff0c;但仅限某些特殊网络可以远程访问&#xff0c;其他网络全部拒绝445端口&#xff0c;因此网上找了很多将Win10的SMB指向别的端口的教程&#xff0c;但所有教程均使用环回网卡解决&am…...

Allegro如何快速清除多余的规则设置操作指导

Allegro如何快速清除多余的规则设置操作指导 在用Allegro做PCB设计的时候,会给PCB设置一些规则,在PCB设计完成之后,可能会有一些没有使用到的规则,如下图 Physical规则中的45OHM的规则是多余的 单独某个规则可以直接在规则管理器中删除,如果比较多可以用下面方法批量删除…...

ROS2 入门应用 引用自定义消息(Python)

ROS2 入门应用 引用自定义消息&#xff08;Python&#xff09;1. 查看自定义消息2. 修改话题发布3. 修改话题订阅4. 修改依赖关系5. 编译和运行1. 查看自定义消息 引用在《ROS2 入门应用 创建自定义接口》中自定义的消息Sphere.msg ros2 interface show tutorial_interfaces/…...

SmS-Activate一款好用的短信验证码接收工具

前言 有些国外应用在使用应用上的功能时需要注册账号&#xff0c;由于某种不可抗因素&#xff0c;我们的手机号一般不支持注册&#xff0c;接收不到信息验证码&#xff0c;于是我们可以使用SmS-Activate提供的服务&#xff0c;使用$实现我们的需求&#xff08;大概一次验证1-5…...

SpringBoot+Elasticsearch按日期实现动态创建索引(分表)

&#x1f60a; 作者&#xff1a; 一恍过去&#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390&#x1f38a; 社区&#xff1a; Java技术栈交流&#x1f389; 主题&#xff1a; SpringBootElasticsearch按日期实现动态创建索引(分表)⏱️ 创作时间&…...

Terraform基础入门 (Infrastructure as Code)

文章目录前言介绍Terraform 术语Terraform 如何工作关于provider安装开启本地缓存demo1(dockernginx)demo2(dockerzookeeperkafka)参考资料前言 像写代码一样管理基础设施。 Terraform 使用较为高级的配置文件语法来描述基础设施&#xff0c;这个特性让你对配置文件进行版本化…...

Redis内存回收

Redis 内存回收 Redis之所以性能很强&#xff0c;最主要的原因是基于内存存储&#xff0c;然而单节点的Redis其内存大小不宜过大&#xff0c;会影响持久化或主从同步性能 可以通过修改配置文件来设置Redis的最大内存 maxmemory <bytes>当内存达到上限时&#xff0c;就…...

STM32串口通信实战指南与常见问题解析

1. 串口通信基础概念解析串口通信作为嵌入式系统中最基础也最常用的通信方式之一&#xff0c;其核心原理是通过单根数据线按位顺序传输数据。与并行通信相比&#xff0c;虽然传输速率较低&#xff0c;但具有布线简单、成本低廉、传输距离远等显著优势。在实际工程应用中&#x…...

AMD Ryzen硬件调试指南:5分钟掌握SMUDebugTool核心功能

AMD Ryzen硬件调试指南&#xff1a;5分钟掌握SMUDebugTool核心功能 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https://g…...

新手友好:在快马平台通过可交互代码学习OpenClaw Onboard抓取基础

今天想和大家分享一个特别适合机器人领域新手的实践项目——通过InsCode(快马)平台学习OpenClaw Onboard框架的基础操作。作为一个刚接触机械臂控制的小白&#xff0c;我发现这个平台能直接把抽象的控制概念变成可交互的代码&#xff0c;学习效率提升了好几倍。 项目环境搭建零…...

Qwen3.5-4B助力Python爬虫:智能解析与数据清洗实战

Qwen3.5-4B助力Python爬虫&#xff1a;智能解析与数据清洗实战 1. 爬虫开发者的新困境 最近和几个做数据抓取的朋友聊天&#xff0c;发现大家普遍遇到一个头疼的问题&#xff1a;现在的网站越来越难爬了。以前写个正则表达式或者XPath就能搞定的事情&#xff0c;现在经常要面…...

3大优化方案让经典游戏重获新生:WarcraftHelper解决老游戏新设备适配难题

3大优化方案让经典游戏重获新生&#xff1a;WarcraftHelper解决老游戏新设备适配难题 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 当你在4K显示器上…...

LeetCode 热题 100(每日两题)-Day2

坚持打卡第二天&#xff01;昨天的哈希表大显神威&#xff0c;今天我们将继续探索哈希集合的妙用&#xff0c;并引入数组操作中极其重要的技巧——双指针&#xff08;快慢指针&#xff09;。一、最长连续序列LeetCode 第 128 题&#xff0c;难度中等。这道题的难点在于题目强制…...

[实战] 从点云到避障:FIESTA ESDF实时构建全解析

1. 为什么需要实时ESDF构建 当机器人需要在复杂环境中自主移动时&#xff0c;避障是最基础也最关键的能力。想象一下你在黑暗中摸索前行&#xff0c;手碰到墙壁就立即缩回——机器人也需要类似的"触觉"。欧氏距离场&#xff08;ESDF&#xff09;就是机器人的三维空间…...

DLSS Swapper革新性图形优化工具:一键提升游戏帧率最高达40%的开源解决方案

DLSS Swapper革新性图形优化工具&#xff1a;一键提升游戏帧率最高达40%的开源解决方案 【免费下载链接】dlss-swapper 项目地址: https://gitcode.com/GitHub_Trending/dl/dlss-swapper DLSS Swapper是一款开源的图形优化工具&#xff0c;专为游戏玩家打造&#xff0c…...

Neo4j关系创建失败?手把手教你处理GraphRAG生成的异常ID格式(含正则清洗技巧)

Neo4j关系创建失败&#xff1f;手把手教你处理GraphRAG生成的异常ID格式&#xff08;含正则清洗技巧&#xff09; 当你满怀期待地将GraphRAG生成的知识图谱数据导入Neo4j&#xff0c;准备欣赏可视化成果时&#xff0c;却发现关系创建失败——这可能是每个数据工程师都经历过的噩…...

如何在3天内快速掌握音频驱动面部动画技术?完整实战指南 [特殊字符]

如何在3天内快速掌握音频驱动面部动画技术&#xff1f;完整实战指南 &#x1f680; 【免费下载链接】FACEGOOD-Audio2Face http://www.facegood.cc 项目地址: https://gitcode.com/gh_mirrors/fa/FACEGOOD-Audio2Face 想要让虚拟角色拥有逼真的面部表情吗&#xff1f;FA…...