当前位置: 首页 > 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;就…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

API网关Kong的鉴权与限流:高并发场景下的核心实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中&#xff0c;API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关&#xff0c;Kong凭借其插件化架构…...

DiscuzX3.5发帖json api

参考文章&#xff1a;PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下&#xff0c;适配我自己的需求 有一个站点存在多个采集站&#xff0c;我想通过主站拿标题&#xff0c;采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...

云安全与网络安全:核心区别与协同作用解析

在数字化转型的浪潮中&#xff0c;云安全与网络安全作为信息安全的两大支柱&#xff0c;常被混淆但本质不同。本文将从概念、责任分工、技术手段、威胁类型等维度深入解析两者的差异&#xff0c;并探讨它们的协同作用。 一、核心区别 定义与范围 网络安全&#xff1a;聚焦于保…...