[Documentation] [TitleIndex] [WordIndex

PCL Overview

Data types

Point cloud data types in ROS

These are the current data structures in ROS that represent point clouds:

Determining the point type for a given point cloud message

Each point cloud object type gives you information about the field names in a different way.

If you have a sensor_msgs::PointCloud object, they're all floats. To find out their names, look at the elements of the channels() vector; each one has a name field.

If you have a sensor_msgs::PointCloud2 object, look at the elements of the fields() vector; each one has a name field and a datatype field. PCL has methods for extracting this information, see io.h.

If you have a pcl::PointCloud<T> object, you probably already know what type the fields are because you know what T is. If it's a topic published by another node that you didn't write, you'll have to look at the source for that node. PCL has methods for extracting this information, see io.h.

It has been suggested that it would be helpful if rostopic info could tell you what T is for a given PointCloud2 topic, but this hasn't been implemented yet.

Common PointCloud2 field names

Because field names are generic in the new PointCloud2 message, here's the list of commonly used names within PCL:

The complete list of field names and point types used in PCL can be found in pcl/point_types.hpp.

Point Cloud conversion

Converting between sensor_msgs::PointCloud2 and pcl::PointCloud<T> objects

Use pcl::fromROSMsg and pcl::toROSMsg from pcl_conversions. The versions of these methods provided by PCL (pcl::fromROSMsg and pcl::toROSMsg) are deprecated. The point_cloud::fromMsg() and point_cloud::toMsg() methods are deprecated and will be removed in an imminent release.

Converting between the `sensor_msgs::PointCloud` and `sensor_msgs::PointCloud2` format

The easiest way to convert between sensor_msgs/PointCloud and sensor_msgs/PointCloud2 messages is to run an instance of the point_cloud_converter node, which subscribes to topics of both types and publishes topics of both types.

If you want to do the conversion in your node, look at sensor_msgs::convertPointCloud2ToPointCloud and sensor_msgs::convertPointCloudToPointCloud2.

Publishing and subscribing to point cloud messages

Note: Use of the old PointCloud message type should be discontinued. Just for completeness, we'll summarize the subscription and publication operations for all three point cloud types below anyway.

Subscribing to different point cloud message types

For all of these, assume you've done the following:

   1 ros::NodeHandle nh;
   2 std::string topic = nh.resolveName("point_cloud");
   3 uint32_t queue_size = 1;

For sensor_msgs::PointCloud topics:

   1 // callback signature:
   2 void callback(const sensor_msgs::PointCloudConstPtr&);
   3 
   4 // create subscriber:
   5 ros::Subscriber sub = nh.subscribe(topic, queue_size, callback);

For sensor_msgs::PointCloud2 topics:

   1 // callback signature
   2 void callback(const sensor_msgs::PointCloud2ConstPtr&);
   3 
   4 // to create a subscriber, you can do this (as above):
   5 ros::Subscriber sub = nh.subscribe<sensor_msgs::PointCloud2> (topic, queue_size, callback);

For a subscriber that receives pcl::PointCloud<T> objects directly:

   1 // Need to include the pcl ros utilities
   2 #include <pcl_ros/point_cloud.h>
   3 
   4 // callback signature, assuming your points are pcl::PointXYZRGB type:
   5 void callback(const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr&);
   6 
   7 // create a templated subscriber
   8 ros::Subscriber sub = nh.subscribe<pcl::PointCloud<pcl::PointXYZRGB> > (topic, queue_size, callback);

When subscribing to a pcl::PointCloud<T> topic with a sensor_msgs::PointCloud2 subscriber or viceversa, the conversion (deserialization) between the two types sensor_msgs::PointCloud2 and pcl::PointCloud<T> is done on the fly by the subscriber.

Publishing different point cloud types

As before, assume you've already done this:

   1 ros::NodeHandle nh;
   2 std::string topic = nh.resolveName("point_cloud");
   3 uint32_t queue_size = 1;

For sensor_msgs::PointCloud messages:

   1 // assume you get a point cloud message somewhere
   2 sensor_msgs::PointCloud cloud_msg;
   3 
   4 // advertise
   5 ros::Publisher pub = nh.advertise<sensor_msgs::PointCloud>(topic, queue_size);
   6 // and publish
   7 pub.publish(cloud_msg);

For sensor_msgs::PointCloud2 messages:

   1 // get your point cloud message from somewhere
   2 sensor_msgs::PointCloud2 cloud_msg;
   3 
   4 // to advertise you can do it like this (as above):
   5 ros::Publisher pub = nh.advertise<sensor_msgs::PointCloud2>(topic, queue_size);
   6 
   7 /// and publish the message
   8 pub.publish(cloud_msg);

If you have a pcl::PointCloud<T> object, you don't have to convert it to a message:

   1 // Need to include the pcl ros utilities
   2 #include "pcl_ros/point_cloud.h"
   3 
   4 // you have an object already, eg with pcl::PointXYZRGB points
   5 pcl::PointCloud<pcl::PointXYZRGB> cloud;
   6 
   7 // create a templated publisher
   8 ros::Publisher pub = nh.advertise<pcl::PointCloud<pcl::PointXYZRGB> > (topic, queue_size);
   9 
  10 // and just publish the object directly
  11 pub.publish(cloud);

The publisher takes care of the conversion (serialization) between sensor_msgs::PointCloud2 and pcl::PointCloud<T> where needed.


2024-10-05 14:24