无人机避障——4D毫米波雷达从PCD点云到二维栅格地图

ops/2024/10/31 7:19:56/

        本文旨在以 4D 毫米波雷达的 PCD 点云格式文件为基础,直接生成可用于后续无人机路径规划、能提供雷达感知环境的 2D 导航地图文件PGM,从而为无人机在相关环境中的飞行路径规划等操作提供有力的基于雷达感知的环境信息支撑。

安装PCD转PGM代码

代码来自参考博客的github:

3D激光SLAM点云地图pcd转导航可用的2D栅格地图_pcd2pgm-CSDN博客

 GitHub - hujiax380/pcd2pgm: A tool that can convert PCD pointcloud file to PGM map file

nvidia@Xavier-NX:~$ mkdir -p ~/pcd2pgm_test/src
nvidia@Xavier-NX:~$ cd pcd2pgm_test/
nvidia@Xavier-NX:~/pcd2pgm_test$ cd src/
nvidia@Xavier-NX:~/pcd2pgm_test/src$ catkin_init_workspace 
Creating symlink "/home/nvidia/pcd2pgm_test/src/CMakeLists.txt" pointing to "/opt/ros/melodic/share/catkin/cmake/toplevel.cmake"
nvidia@Xavier-NX:~/pcd2pgm_test/src$ git clone https://github.com/hujiax380/pcd2pgm.git

修改点云的路径为自己的点云数据:

这是我的4D毫米波雷达对外界场景点云进行滤波后的一份PCD数据:

代码部分:修改自己的PCD文件路径和PCD文件名

#include <ros/ros.h>#include <nav_msgs/OccupancyGrid.h>
#include <nav_msgs/GetMap.h>#include <sensor_msgs/PointCloud2.h>
#include <pcl/io/pcd_io.h>
#include <pcl_conversions/pcl_conversions.h>#include <pcl/point_types.h>std::string file_directory;
std::string file_name;
std::string pcd_file;std::string map_topic_name;const std::string pcd_format = ".pcd";nav_msgs::OccupancyGrid map_topic_msg;double map_resolution = 0.05;pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_after_PassThrough(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_after_Radius(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr pcd_cloud(new pcl::PointCloud<pcl::PointXYZ>);void SetMapTopicMsg(const pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, nav_msgs::OccupancyGrid& msg);int main(int argc, char** argv)
{ros::init(argc, argv, "pcl_filters");ros::NodeHandle nh;ros::NodeHandle private_nh("~");ros::Rate loop_rate(1.0);private_nh.param("file_directory", file_directory, std::string("/home/nvidia/PCD_test_data/"));//此处需要修改为自己pcd文件的路径ROS_INFO("*** file_directory = %s ***\n", file_directory.c_str());private_nh.param("file_name", file_name, std::string("test"));//此处"pcd_name"需要修改为自己的pcd文件名,无需.pcdROS_INFO("*** file_name = %s ***\n", file_name.c_str());pcd_file = file_directory + file_name + pcd_format;ROS_INFO("*** pcd_file = %s ***\n", pcd_file.c_str());private_nh.param("map_resolution", map_resolution, 0.05);private_nh.param("map_topic_name", map_topic_name, std::string("map"));ros::Publisher map_topic_pub = nh.advertise<nav_msgs::OccupancyGrid>(map_topic_name, 1);if (pcl::io::loadPCDFile<pcl::PointXYZ> (pcd_file, *pcd_cloud) == -1){PCL_ERROR ("Couldn't read file: %s \n", pcd_file.c_str());return (-1);}std::cout << "输入点云点数:" << pcd_cloud->points.size() << std::endl;SetMapTopicMsg(pcd_cloud, map_topic_msg);while(ros::ok()){map_topic_pub.publish(map_topic_msg);loop_rate.sleep();ros::spinOnce();}return 0;
}void SetMapTopicMsg(const pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, nav_msgs::OccupancyGrid& msg)
{msg.header.seq = 0;msg.header.stamp = ros::Time::now();msg.header.frame_id = "map";msg.info.map_load_time = ros::Time::now();msg.info.resolution = map_resolution;double x_min, x_max, y_min, y_max; //这里是投影到xy平面,如果要投到xz/yz,这里以及后面的xy对应的数据改为你想投影的平面if(cloud->points.empty()){ROS_WARN("pcd is empty!\n");return;}for(int i = 0; i < cloud->points.size() - 1; i++){if(i == 0){x_min = x_max = cloud->points[i].x;y_min = y_max = cloud->points[i].y;}double x = cloud->points[i].x;double y = cloud->points[i].y;if(x < x_min) x_min = x;if(x > x_max) x_max = x;if(y < y_min) y_min = y;if(y > y_max) y_max = y;}msg.info.origin.position.x = x_min;msg.info.origin.position.y = y_min;msg.info.origin.position.z = 0.0;msg.info.origin.orientation.x = 0.0;msg.info.origin.orientation.y = 0.0;msg.info.origin.orientation.z = 0.0;msg.info.origin.orientation.w = 1.0;msg.info.width = int((x_max - x_min) / map_resolution);msg.info.height = int((y_max - y_min) / map_resolution);msg.data.resize(msg.info.width * msg.info.height);msg.data.assign(msg.info.width * msg.info.height, 0);ROS_INFO("data size = %d\n", msg.data.size());for(int iter = 0; iter < cloud->points.size(); iter++){int i = int((cloud->points[iter].x - x_min) / map_resolution);if(i < 0 || i >= msg.info.width) continue;int j = int((cloud->points[iter].y - y_min) / map_resolution);if(j < 0 || j >= msg.info.height - 1) continue;msg.data[i + j * msg.info.width] = 100;}
}

修改完成进行编译:

nvidia@Xavier-NX:~/pcd2pgm_test$ catkin_make

编译完成source一下 :

nvidia@Xavier-NX:~/pcd2pgm_test$ source devel/setup.bash

然后打开roscore,打开新终端,进行rosrun:

roscorerosrun pcd2pgm pcd2topic

报错没有包就再source一下 

 然后另起终端:

nvidia@Xavier-NX:~/pcd2pgm_test$ rosrun map_server map_saver

 结果:

原点云数据:

分辨率为0.05

分辨率为0.5

 

 


http://www.ppmy.cn/ops/129804.html

相关文章

重生之我在Java世界------学工厂设计模式

文章目录 为什么需要工厂模式&#xff1f;简单工厂模式&#xff1a;第一步改进实际应用场景(常见场景)1. 数据库连接的创建2. 支付方式的处理 工厂模式的优势注意事项总结 在日常开发工作中&#xff0c;我们经常需要创建对象。随着项目的发展&#xff0c;对象创建的逻辑可能变得…

redis详细教程(5.AOP和RDB持久化)

AOF&#xff08;Append Only File&#xff09;日志和RDB&#xff08;Redis Database Backup&#xff09;持久化是Redis中两种重要的数据持久化机制。 RDB持久化机制原理RDB是Redis提供的一种数据快照保存机制&#xff0c;它将某个时间点的数据库状态保存到一个RDB文件中。这个…

算法定制LiteAIServer视频智能分析软件的过亮、过暗及抖动检测应用场景

在现代社会中&#xff0c;视频监控系统扮演着举足轻重的角色&#xff0c;其视频质量直接关乎监控系统的可靠性与有效性。算法定制LiteAIServer通过引入抖动检测和过亮过暗检测功能&#xff0c;为视频监控系统的稳定性和用户体验带来了显著提升。 以下是对这两种功能的技术实现、…

macOS Sonoma 14.7.1 (23H222) Boot ISO 原版可引导镜像下载

macOS Sonoma 14.7.1 (23H222) Boot ISO 原版可引导镜像下载 2024 年 10 月 28 日&#xff0c;Apple 智能今日登陆 iPhone、iPad 和 Mac。用户现可借助 Apple 智能优化写作&#xff0c;为通知、邮件和消息生成摘要&#xff0c;体验交互更自然、功能更丰富的 Siri&#xff0c;使…

Diving into the STM32 HAL-----Interrupts

硬件管理就是处理异步事件。其中大部分来自硬件外围设备。例如&#xff0c;计时器达到配置的 period 值&#xff0c;或者 UART 在数据到达时发出警告。 中断是一个异步事件&#xff0c;它会导致按优先级停止执行当前代码&#xff08;中断越重要&#xff0c;其优先级越高;这将导…

目录遍历漏洞

目录遍历 目录 概念漏洞分析 加密型传递参数编码绕过目录限定绕过绕过文件后缀过滤(截断上传原理) 漏洞挖掘 访问图片文件测试时去掉文件名只访问目录路径搜索引擎谷歌关键字 pikachu目录遍历 目录遍历与任意文件下载其实差不多,但是如果目录遍历比如etc/passwd只能看不能下…

MySQL安装配置教程

以下是 MySQL 在 Windows 系统下的安装配置教程: 1. 下载 MySQL 访问 MySQL 官方网站(https://dev.mysql.com/downloads/mysql/),根据您的操作系统版本(32 位或 64 位)选择合适的 MySQL 安装包。一般建议下载社区版(Community Server),它是免费且功能丰富的版本。2. …

51c深度学习~合集6

我自己的原文哦~ https://blog.51cto.com/whaosoft/12369516 #卷积神经网络压缩方法总结 本文介绍了卷积网络压缩的常见方法&#xff1a;低秩近似、剪枝与稀疏约束、参数量化、二值化网络、知识蒸馏和浅层/轻量网络。 我们知道&#xff0c;在一定程度上&#xff0c;网络越深…