Skip to content

Commit 39c710f

Browse files
committed
PointXYZ working
1 parent 1f63a4f commit 39c710f

File tree

1 file changed

+125
-0
lines changed

1 file changed

+125
-0
lines changed
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*
2+
Author: Heethesh Vhavle
3+
Version: 1.0.1
4+
Date: Apr 01, 2019
5+
6+
References:
7+
http://wiki.ros.org/pcl/Tutorials
8+
http://pointclouds.org/documentation/tutorials/extract_indices.php
9+
10+
CMake:
11+
add_executable(ground_plane_segmentation src/ground_plane_segmentation.cpp)
12+
target_link_libraries(ground_plane_segmentation ${catkin_LIBRARIES})
13+
*/
14+
15+
#include <ros/ros.h>
16+
// PCL specific includes
17+
#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>
23+
#include <pcl/ModelCoefficients.h>
24+
#include <pcl/sample_consensus/method_types.h>
25+
#include <pcl/sample_consensus/model_types.h>
26+
#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>
30+
31+
// Publishers
32+
ros::Publisher coef_pub;
33+
ros::Publisher pcl_pub;
34+
35+
// Topics
36+
double distance_threshold;
37+
std::string input_topic;
38+
std::string output_topic;
39+
std::string coefficients_topic;
40+
41+
// Debug flag
42+
bool debug = false;
43+
44+
void callback(const sensor_msgs::PointCloud2ConstPtr& input)
45+
{
46+
// 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);
50+
if (debug) std::cerr << "PointCloud before filtering: " << cloud_ptr->width << " " << cloud_ptr->height << " data points." << std::endl;
51+
52+
// Filter the points in z-axis
53+
pcl::PassThrough<pcl::PointXYZ> pass;
54+
pass.setInputCloud(cloud_ptr);
55+
pass.setFilterFieldName("z");
56+
pass.setFilterLimits(0.0, 1.4);
57+
pass.filter(*cloud_filtered_ptr);
58+
if (debug) std::cerr << "PointCloud after filtering: " << cloud_filtered_ptr->width << " " << cloud_filtered_ptr->height << " data points." << std::endl;
59+
60+
// 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);
66+
67+
// Setup ground plane segmentation
68+
pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);
69+
pcl::PointIndices::Ptr inliers(new pcl::PointIndices);
70+
pcl::SACSegmentation<pcl::PointXYZ> seg;
71+
72+
// Segmentation paramters
73+
seg.setOptimizeCoefficients(true);
74+
seg.setModelType(pcl::SACMODEL_PLANE);
75+
seg.setMethodType(pcl::SAC_RANSAC);
76+
seg.setMaxIterations(1000);
77+
seg.setDistanceThreshold(0.01);
78+
79+
// Segment the largest planar component from the cloud
80+
seg.setInputCloud(voxel_ptr);
81+
seg.segment(*inliers, *coefficients);
82+
83+
// Extract the inliers
84+
pcl::PointCloud<pcl::PointXYZ>::Ptr plane_cloud_ptr(new pcl::PointCloud<pcl::PointXYZ>);
85+
pcl::ExtractIndices<pcl::PointXYZ> extract;
86+
extract.setInputCloud(voxel_ptr);
87+
extract.setIndices(inliers);
88+
extract.setNegative(true);
89+
extract.filter(*plane_cloud_ptr);
90+
if (debug) std::cerr << "PointCloud representing the planar component: " << plane_cloud_ptr->width << " " << plane_cloud_ptr->height << " data points." << std::endl;
91+
92+
// Publish the model coefficients
93+
pcl_msgs::ModelCoefficients ros_coefficients;
94+
pcl_conversions::fromPCL(*coefficients, ros_coefficients);
95+
coef_pub.publish(ros_coefficients);
96+
97+
// Convert to ROS data type
98+
sensor_msgs::PointCloud2 output;
99+
pcl::toROSMsg(*plane_cloud_ptr, output);
100+
pcl_pub.publish(output);
101+
}
102+
103+
int main(int argc, char** argv)
104+
{
105+
// Initialize ROS
106+
ros::init(argc, argv, "ground_plane_segmentation");
107+
ros::NodeHandle nh("~");
108+
109+
// Get params from launch file
110+
nh.getParam("distance_threshold", distance_threshold);
111+
nh.getParam("input", input_topic);
112+
nh.getParam("output", output_topic);
113+
nh.getParam("coefficients", coefficients_topic);
114+
nh.param<double>("distance_threshold", distance_threshold, 0.01);
115+
116+
// Create a ROS subscriber for the input point cloud
117+
ros::Subscriber sub = nh.subscribe(input_topic, 1, callback);
118+
119+
// Create a ROS publisher for the output segmented point cloud and coefficients
120+
pcl_pub = nh.advertise<sensor_msgs::PointCloud2>(output_topic, 1);
121+
coef_pub = nh.advertise<pcl_msgs::ModelCoefficients>(coefficients_topic, 1);
122+
123+
// Spin
124+
ros::spin();
125+
}

0 commit comments

Comments
 (0)