ROS:一节点读取发布点云,另一节点订阅点云后进行滤波处理、切割处理然后发布至ros

在ROS中,一节点读取发布点云,另一节点订阅点云后进行滤波处理、切割处理然后发布至ros


前言

通过简单的for循环和if语句实现点云的切割


一、功能实现步骤详情

(1)创建两个节点,voxel 和 pubpcd;

第一个节点pubpcd在代码pubpcb.cpp中读取点云进行话题发布;
第二个节点voxel在代码example_voxelgrid_pcl_types.cpp 中读取图像点云message然后进行滤波切割处理;

二、节点工作环境

在工作空间~home/catkin_ws/src下新建文件夹my_pcl_tutorial,在此文件夹下新建src(文件夹)、CMakeList.cpp(构建配置文件),package.xml(依赖),
如图所示:
在这里插入图片描述

1.src文件夹下的文件

两个节点文件pubpcb.cpp 和 example_voxelgrid_pcl_types.cpp,table_scene_lms400.pcd点云文件。
在这里插入图片描述

2.CMakeLists.txt

添加并修改代码如下:

add_executable(voxel src/example_voxelgrid_pcl_types.cpp) 
add_executable(pubpcd src/pubpcb.cpp) 

3.package.xml
添加并修改代码如下:

  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>libpcl-all-dev</build_depend>
  <build_depend>pcl_conversions</build_depend>
  <build_depend>pcl_ros</build_depend>
  <build_depend>roscpp</build_depend>
  <build_depend>sensor_msgs</build_depend>
  <run_depend>libpcl-all</run_depend>
  <run_depend>pcl_conversions</run_depend>
  <run_depend>pcl_ros</run_depend>
  <run_depend>roscpp</run_depend>
  <run_depend>sensor_msgs</run_depend>

  <build_depend>cv_bridge</build_depend>
  <build_depend>image_transport</build_depend>
  <run_depend>cv_bridge</run_depend>
  <run_depend>image_transport</run_depend>

三、两节点代码详情

1.pubpcb.cpp

#include <ros/ros.h>
#include <sensor_msgs/PointCloud2.h>
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
//#include <pcl/conversions.h>
#include <pcl_conversions/pcl_conversions.h>
sensor_msgs::PointCloud2 cloud;

int main (int argc, char** argv)
{

    ros::init (argc,argv,"pub_pcb");
    ros::NodeHandle nh;
    ros::Publisher pub; 
    
    pub = nh.advertise<sensor_msgs::PointCloud2>("pcbpub",1); 

    
  // Replace the path below with the path where you saved your file
  //  pcl::io::loadPCDFile ("/home/ros/catkin_ws/src/my_pcl_tutorial/src/table_scene_lms400.pcd", cloud); // Remember to download the file first!
    pcl::io::loadPCDFile ("/home/ros/catkin_ws/src/my_pcl_tutorial/src/table_scene_lms400.pcd", cloud); // Remember to download the file first!
    cloud.header.stamp=ros::Time::now();
    cloud.header.frame_id="/base_link";  //坐标

    ros::Rate loop_rate(10);

    while(ros::ok())
    {
        pub.publish(cloud);

        loop_rate.sleep();
    }
  return (0);
}

2.example_voxelgrid_pcl_types.cpp


```cpp
#include <ros/ros.h>
// PCL specific includes
//#include <pcl_conversions/pcl_conversions.h>
//#include <pcl/point_cloud.h>

#include <pcl/ros/conversions.h>
#include <pcl_ros/point_cloud.h>
#include <pcl/point_types.h>

#include <pcl/filters/voxel_grid.h>

typedef pcl::PointCloud<pcl::PointXYZ> PointCloud;

ros::Publisher pub;

void cloud_cb (const pcl::PCLPointCloud2ConstPtr& cloud)
//void cloud_cb (const  PointCloud::ConstPtr& cloud)
{

  // PointCloud cloud_filtered;
  pcl::PCLPointCloud2 cloud_filtered;
  pcl::PointCloud<pcl::PointXYZ>*cloudPXYZ1(new pcl::PointCloud<pcl::PointXYZ>);
  pcl::PointCloud<pcl::PointXYZ>*cloudPXYZ2(new pcl::PointCloud<pcl::PointXYZ>);

  // Perform the actual filtering// 创建滤波器对象
  pcl::VoxelGrid<pcl::PCLPointCloud2> sor;


  //pcl::VoxelGrid<PointCloud> sor;
  sor.setInputCloud (cloud);
  sor.setLeafSize (0.01, 0.01, 0.01);//设置滤波时创建的体素体积为 10cm*10cm*10cm的立方体
  sor.filter (cloud_filtered);

  //转换为模板,点云实现从ROS到PCL中的数据的转化,同时也可以直接使用PCL库实现可视化
  pcl::fromPCLPointCloud2(cloud_filtered,*cloudPXYZ1);  //PCL转换点云
  ROS_INFO_STREAM("pointxyz size: "<<(*cloudPXYZ1).size());

  
  (*cloudPXYZ2).resize((*cloudPXYZ1).size());

  //for循环 进行切割
  for(unsigned long int i=0;i<(*cloudPXYZ1).size();++i)
  { 
    //矩形切割
    if((*cloudPXYZ1).at(i).x>-0.3&&(*cloudPXYZ1).at(i).y>0.2&&(*cloudPXYZ1).at(i).z>-2)
        //满足if条件的点云存放到×cloudPXYZ2
        (*cloudPXYZ2).push_back((*cloudPXYZ1).at(i)); 
  
  }
  //pcl到ros的转换
  pcl::toPCLPointCloud2(*cloudPXYZ2,cloud_filtered);

  //
  pcl_conversions::toPCL(ros::Time::now(),cloud_filtered.header.stamp);
  cloud_filtered.header.frame_id = "/base_link";
  
  // Publish the data
  pub.publish (cloud_filtered);
}

int main (int argc, char** argv)
{
  // Initialize ROS
  ros::init (argc, argv, "my_pcl_tutorial");
  ros::NodeHandle nh;

  // Create a ROS subscriber for the input point cloud
  ros::Subscriber sub = nh.subscribe ("input", 1, cloud_cb);

  // Create a ROS publisher for the output point cloud
  //pub = nh.advertise<pcl::PCLPointCloud2> ("output", 1);
  pub = nh.advertise<PointCloud> ("output", 1);
  // Spin
  ros::spin ();
}

四、编译,并运行节点

1.在工作空间打开一个终端,输入指令:catkin_make

ros@ubuntu:~/catkin_ws$ catkin_make

在这里插入图片描述

2.打开新终端,运行roscore

输入指令:roscore

ros@ubuntu:~$ roscore

在这里插入图片描述

3. 打开新终端,运行第一个节点pubpcd

输入指令:rosrun my_pcl_tutorial pubpcd

ros@ubuntu:~/catkin_ws/$ rosrun my_pcl_tutorial pubpcd

在这里插入图片描述

4.打开新终端,运行第二个节点voxel

输入指令:rosrun my_pcl_tutorial voxel input:=/pcbpub

ros@ubuntu:~/catkin_ws/$ rosrun my_pcl_tutorial voxel input:=/pcbpub

5.将处理后的点云以坐标形式显示

输入指令:rosrun tf static_transform_publisher 0 0 0 0 0 0 1 map base_link 30

ros@ubuntu:~/catkin_ws/$ rosrun rosrun tf static_transform_publisher 0 0 0 0 0 0 1  map base_link 30

在这里插入图片描述

6.在rviz查看运行结果

在新终端输入指令:rviz

ros@ubuntu:~$ rviz

7.添加话题:

在这里插入图片描述

8.最终切割后效果图:

在这里插入图片描述

9.原图:

在这里插入图片描述

五、总结

重点为ROS到PCL的互相转化,以及代码切割

ROS到PCL

  //转换为模板,点云实现从ROS到PCL中的数据的转化,同时也可以直接使用PCL库实现可视化
  pcl::fromPCLPointCloud2(cloud_filtered,*cloudPXYZ1);  //PCL转换点云
  ROS_INFO_STREAM("pointxyz size: "<<(*cloudPXYZ1).size());
  
  (*cloudPXYZ2).resize((*cloudPXYZ1).size());

“切割”代码部分

//for循环 进行切割
  for(unsigned long int i=0;i<(*cloudPXYZ1).size();++i)
  { 
    //矩形切割
    if((*cloudPXYZ1).at(i).x>-0.3&&(*cloudPXYZ1).at(i).y>0.2&&(*cloudPXYZ1).at(i).z>-2)
        //满足if条件的点云存放到×cloudPXYZ2
        (*cloudPXYZ2).push_back((*cloudPXYZ1).at(i)); 
  
  }

PCL到ROS

  //pcl到ros的转换
  pcl::toPCLPointCloud2(*cloudPXYZ2,cloud_filtered);

  //
  pcl_conversions::toPCL(ros::Time::now(),cloud_filtered.header.stamp);
  cloud_filtered.header.frame_id = "/base_link";
  
  // Publish the data
  pub.publish (cloud_filtered);
  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
ROS(Robot Operating System)是一个用于构建机器人系统的开源框架。它提供了一系列的工具、库和约定,用于简化机器人软件开发过程。其中,点云处理ROS中一个重要的功能模块之一。 在ROS中,点云是由三维空间中的一组点构成的数据结构,常用于表示激光雷达或深度相机等传感器获取到的环境信息。Python是ROS中常用的编程语言之一,可以通过使用相应的ROS包和库来进行点云处理。 在Python中,可以使用ROS提供的PointCloud2消息类型来表示点云数据。可以通过订阅相应的点云话题来获取点云数据,并使用相关的库(如PCL、Open3D等)进行点云处理操作,例如滤波、配准、分割等。 以下是一些常用的ROS点云处理库和工具: 1. PCL(Point Cloud Library):是一个功能强大的点云处理库,提供了丰富的算法和工具,可以用于点云滤波、配准、分割、特征提取等操作。 2. Open3D:是一个用于三维数据处理的现代化开源库,支持点云和网格数据的处理和可视化。 3. ROS中的点云相关包:ROS提供了一些点云相关的包,如pcl_ros、pointcloud_to_laserscan等,可以方便地进行点云数据的转换和处理。 如果你想在ROS中使用Python进行点云处理,可以按照以下步骤进行: 1. 安装ROS和相应的点云处理库(如PCL、Open3D等)。 2. 创建一个ROS工作空间,并在该工作空间下创建一个Python包。 3. 在Python包中编写相应的代码,订阅点云话题,获取点云数据,并进行相应的处理操作。 4. 编译和运行代码,观察点云处理结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Skyblueee_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值