@@ -15,24 +15,23 @@ target_link_libraries(ground_plane_segmentation ${catkin_LIBRARIES})
1515#include < ros/ros.h>
1616// PCL specific includes
1717#include < sensor_msgs/PointCloud2.h>
18- #include < pcl/conversions.h>
19- #include < pcl_conversions/pcl_conversions.h>
20- #include < pcl_ros/transforms.h>
21- #include < pcl/point_cloud.h>
22- #include < pcl/point_types.h>
2318#include < pcl/ModelCoefficients.h>
2419#include < pcl/sample_consensus/method_types.h>
2520#include < pcl/sample_consensus/model_types.h>
2621#include < pcl/segmentation/sac_segmentation.h>
27- #include < pcl/filters/passthrough.h>
28- #include < pcl/filters/voxel_grid.h>
29- #include < pcl/filters/extract_indices.h>
22+ #include < pcl_ros/point_cloud.h>
23+ #include < pcl_ros/filters/passthrough.h>
24+ #include < pcl_ros/filters/voxel_grid.h>
25+ #include < pcl_ros/filters/extract_indices.h>
26+ #include < pcl_conversions/pcl_conversions.h>
3027
3128// Publishers
32- ros::Publisher coef_pub;
3329ros::Publisher pcl_pub;
30+ ros::Publisher coef_pub;
3431
3532// Topics
33+ bool invert;
34+ double voxel_size;
3635double distance_threshold;
3736std::string input_topic;
3837std::string output_topic;
@@ -44,48 +43,52 @@ bool debug = false;
4443void callback (const sensor_msgs::PointCloud2ConstPtr& input)
4544{
4645 // Convert the sensor_msgs/PointCloud2 data to pcl/PointCloud
47- pcl::PointCloud<pcl::PointXYZ>:: Ptr cloud_ptr (new pcl::PointCloud<pcl::PointXYZ> );
48- pcl::PointCloud<pcl::PointXYZ>:: Ptr cloud_filtered_ptr (new pcl::PointCloud<pcl::PointXYZ> );
49- pcl::fromROSMsg (*input, *cloud_ptr);
46+ pcl::PCLPointCloud2:: Ptr cloud_ptr (new pcl::PCLPointCloud2 );
47+ pcl::PCLPointCloud2:: Ptr cloud_filtered_ptr (new pcl::PCLPointCloud2 );
48+ pcl_conversions::toPCL (*input, *cloud_ptr);
5049 if (debug) std::cerr << " PointCloud before filtering: " << cloud_ptr->width << " " << cloud_ptr->height << " data points." << std::endl;
5150
5251 // Filter the points in z-axis
53- pcl::PassThrough<pcl::PointXYZ > pass;
52+ pcl::PassThrough<pcl::PCLPointCloud2 > pass;
5453 pass.setInputCloud (cloud_ptr);
5554 pass.setFilterFieldName (" z" );
5655 pass.setFilterLimits (0.0 , 1.4 );
5756 pass.filter (*cloud_filtered_ptr);
5857 if (debug) std::cerr << " PointCloud after filtering: " << cloud_filtered_ptr->width << " " << cloud_filtered_ptr->height << " data points." << std::endl;
5958
6059 // Downsample the points
61- pcl::PointCloud<pcl::PointXYZ>:: Ptr voxel_ptr (new pcl::PointCloud<pcl::PointXYZ> );
62- pcl::VoxelGrid<pcl::PointXYZ> voxel ;
63- voxel .setInputCloud (cloud_filtered_ptr);
64- voxel .setLeafSize (0.01 , 0.01 , 0.01 );
65- voxel .filter (*voxel_ptr);
60+ pcl::PCLPointCloud2:: Ptr voxel_ptr (new pcl::PCLPointCloud2 );
61+ pcl::VoxelGrid<pcl::PCLPointCloud2> downsample ;
62+ downsample .setInputCloud (cloud_filtered_ptr);
63+ downsample .setLeafSize (voxel_size, voxel_size, voxel_size );
64+ downsample .filter (*voxel_ptr);
6665
6766 // Setup ground plane segmentation
6867 pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);
6968 pcl::PointIndices::Ptr inliers (new pcl::PointIndices);
7069 pcl::SACSegmentation<pcl::PointXYZ> seg;
7170
71+ // Convert to the templated PointCloud
72+ pcl::PointCloud<pcl::PointXYZ>::Ptr pcl_voxel_ptr (new pcl::PointCloud<pcl::PointXYZ>);
73+ pcl::fromPCLPointCloud2 (*voxel_ptr, *pcl_voxel_ptr);
74+
7275 // Segmentation paramters
7376 seg.setOptimizeCoefficients (true );
7477 seg.setModelType (pcl::SACMODEL_PLANE);
7578 seg.setMethodType (pcl::SAC_RANSAC);
7679 seg.setMaxIterations (1000 );
77- seg.setDistanceThreshold (0.01 );
80+ seg.setDistanceThreshold (distance_threshold );
7881
7982 // Segment the largest planar component from the cloud
80- seg.setInputCloud (voxel_ptr );
83+ seg.setInputCloud (pcl_voxel_ptr );
8184 seg.segment (*inliers, *coefficients);
8285
8386 // Extract the inliers
84- pcl::PointCloud<pcl::PointXYZ>:: Ptr plane_cloud_ptr (new pcl::PointCloud<pcl::PointXYZ> );
85- pcl::ExtractIndices<pcl::PointXYZ > extract;
87+ pcl::PCLPointCloud2:: Ptr plane_cloud_ptr (new pcl::PCLPointCloud2 );
88+ pcl::ExtractIndices<pcl::PCLPointCloud2 > extract;
8689 extract.setInputCloud (voxel_ptr);
8790 extract.setIndices (inliers);
88- extract.setNegative (true );
91+ extract.setNegative (invert );
8992 extract.filter (*plane_cloud_ptr);
9093 if (debug) std::cerr << " PointCloud representing the planar component: " << plane_cloud_ptr->width << " " << plane_cloud_ptr->height << " data points." << std::endl;
9194
@@ -96,7 +99,7 @@ void callback(const sensor_msgs::PointCloud2ConstPtr& input)
9699
97100 // Convert to ROS data type
98101 sensor_msgs::PointCloud2 output;
99- pcl::toROSMsg (*plane_cloud_ptr, output);
102+ pcl_conversions::fromPCL (*plane_cloud_ptr, output);
100103 pcl_pub.publish (output);
101104}
102105
@@ -107,11 +110,28 @@ int main(int argc, char** argv)
107110 ros::NodeHandle nh (" ~" );
108111
109112 // Get params from launch file
113+ nh.getParam (" invert" , invert);
114+ nh.getParam (" voxel_size" , voxel_size);
110115 nh.getParam (" distance_threshold" , distance_threshold);
111116 nh.getParam (" input" , input_topic);
112117 nh.getParam (" output" , output_topic);
113- nh.getParam (" coefficients" , coefficients_topic);
118+ nh.getParam (" plane_coefficients" , coefficients_topic);
119+
120+ // Params defaults
121+ nh.param <bool >(" invert" , invert, true );
122+ nh.param <double >(" voxel_size" , voxel_size, 0.01 );
114123 nh.param <double >(" distance_threshold" , distance_threshold, 0.01 );
124+ nh.param <std::string>(" input" , input_topic, " /camera/depth/color/points" );
125+ nh.param <std::string>(" output" , output_topic, " /ground_plane_segmentation/points" );
126+ nh.param <std::string>(" plane_coefficients" , coefficients_topic, " /ground_plane_segmentation/coefficients" );
127+
128+ // Display params
129+ std::cout << " \n Invert Segmentation: " << invert << std::endl;
130+ std::cout << " Voxel Size: " << voxel_size << std::endl;
131+ std::cout << " Distance Threshold: " << distance_threshold << std::endl;
132+ std::cout << " Input Topic: " << input_topic << std::endl;
133+ std::cout << " Output Topic: " << output_topic << std::endl;
134+ std::cout << " Co-efficients Topic: " << coefficients_topic << std::endl;
115135
116136 // Create a ROS subscriber for the input point cloud
117137 ros::Subscriber sub = nh.subscribe (input_topic, 1 , callback);
0 commit comments