-
Notifications
You must be signed in to change notification settings - Fork 0
/
plane_detection.cpp
134 lines (127 loc) · 5.93 KB
/
plane_detection.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include <ros/ros.h>
#include <iostream>
#include <cmath>
#include <cstring>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/filters/extract_indices.h>
#include "pcl_tutorial_ros/basic_point_cloud_handle.h"
typedef pcl::PointXYZ PointT;
typedef pcl::PointCloud<PointT> PointCloud;
namespace pd {
class PlaneDetection {
private :
pcl::SACSegmentation<pcl::PointXYZ> seg;
pcl::ExtractIndices<PointT> extract;
public :
PlaneDetection(void){
seg.setOptimizeCoefficients (true);
seg.setModelType (pcl::SACMODEL_PLANE);
seg.setMethodType (pcl::SAC_RANSAC);
setPlaneDetectionParameter( 0.01, 0.95 );
}
bool setPlaneDetectionParameter( const double threshold, const double probability ){
try{
seg.setDistanceThreshold (threshold);
seg.setProbability(probability);
return true;
} catch ( std::exception& ex ) {
ROS_ERROR("%s", ex.what());
return false;
}
}
bool detectPlane( const PointCloud::Ptr input_cloud, PointCloud::Ptr plane_cloud ){
try{
PointCloud::Ptr tmp (new PointCloud());
pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);
pcl::PointIndices::Ptr inliers (new pcl::PointIndices);
seg.setInputCloud (input_cloud);
seg.segment (*inliers, *coefficients);
extract.setInputCloud(input_cloud);
extract.setIndices(inliers);
extract.setNegative(false);
extract.filter(*tmp);
tmp->header.frame_id = input_cloud->header.frame_id;
*plane_cloud = *tmp;
return true;
} catch ( std::exception& ex ) {
ROS_ERROR("%s", ex.what());
return false;
}
}
bool removePlane( const PointCloud::Ptr input_cloud, PointCloud::Ptr remove_cloud ){
try{
PointCloud::Ptr tmp (new PointCloud());
pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);
pcl::PointIndices::Ptr inliers (new pcl::PointIndices);
seg.setInputCloud (input_cloud);
seg.segment (*inliers, *coefficients);
extract.setInputCloud(input_cloud);
extract.setIndices(inliers);
extract.setNegative(true);
extract.filter(*tmp);
tmp->header.frame_id = input_cloud->header.frame_id;
*remove_cloud = *tmp;
return true;
} catch ( std::exception& ex ) {
ROS_ERROR("%s", ex.what());
return false;
}
}
};
}
class PointcloudSsubscriber {
private:
ros::NodeHandle nh_;
ros::NodeHandle pnh_;
ros::Subscriber sub_points_;
ros::Publisher pub_cloud_;
ros::Publisher pub_cloud_plane_;
ros::Publisher pub_cloud_remove_;
std::string target_frame_;
pch::BasicPointCloudHandle pch_;
pd::PlaneDetection pd_;
void cbPoints(const sensor_msgs::PointCloud2ConstPtr &cloud_msg) {
PointCloud::Ptr cloud (new PointCloud());
PointCloud::Ptr cloud_plane (new PointCloud());
PointCloud::Ptr cloud_remove (new PointCloud());
pch_.transformFramePointCloud( target_frame_, cloud_msg, cloud );
pch_.voxelGrid( cloud, cloud );
pd_.detectPlane( cloud, cloud_plane );
pd_.removePlane( cloud, cloud_remove );
pub_cloud_.publish(cloud);
pub_cloud_plane_.publish(cloud_plane);
pub_cloud_remove_.publish( cloud_remove );
ROS_INFO("\ncloud points size = %zu\nplane points size = %zu\nremove points size = %zu\n",
cloud->points.size(), cloud_plane->points.size(), cloud_remove->points.size());
}
public:
PointcloudSsubscriber(): nh_(), pnh_("~") {
std::string topic_name = pnh_.param<std::string>( "topic_name", "/sensor_data" );
target_frame_ = pnh_.param<std::string>( "target_frame", "base_footprint" );
float leaf_size = pnh_.param<float>( "voxel_leaf_size", 0.03 );
pch_.setVoxelGridParameter( leaf_size );
float threshold = pnh_.param<float>( "segment_distance_threshold", 0.03 );
float probability = pnh_.param<float>( "segment_probability", 0.90 );
pd_.setPlaneDetectionParameter( threshold, probability );
std::cout << "========================================"
<< "\n[ Parameters ]"
<< "\n * topic_name : " << topic_name
<< "\n * target_frame : " << target_frame_
<< "\n * voxel_leaf_size : " << leaf_size
<< "\n * segment_distance_threshold : " << threshold
<< "\n * segment_probability : " << probability
<< "\n========================================"
<< std::endl;
pub_cloud_ = nh_.advertise<PointCloud>("/cloud", 1);
pub_cloud_plane_ = nh_.advertise<PointCloud>("/cloud_plane", 1);
pub_cloud_remove_ = nh_.advertise<PointCloud>("/cloud_remove", 1);
sub_points_ = nh_.subscribe(topic_name, 5, &PointcloudSsubscriber::cbPoints, this);
}
};
int main(int argc, char *argv[]) {
ros::init(argc, argv, "plane_detection");
PointcloudSsubscriber pointcloud_subscriber;
ros::spin();
}