segmentation_ros_node.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016, Australian Centre for Robotic Vision, ACRV
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of Osnabrück University nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *
29  * Created on: 11.07.2016
30  *
31  * Authors:
32  * Trung T. Pham <trung.pham@adelaide.edu.au>
33  * Markus Eich <markus.eich@qut.edu.au>
34  *
35  *
36  */
37 
38 #include <pcl/filters/filter.h>
40 #include <ros/ros.h>
41 #include <sensor_msgs/PointCloud2.h>
42 #include <string>
43 
44 #include <segmentation/segmentation.hpp>
45 #include <cpf_segmentation_ros/DoSegmentation.h>
46 #include <cpf_segmentation_ros/DoSegmentationAction.h>
47 #include <cpf_segmentation_ros/EnablePublisher.h>
48 
50 
51 #include <boost/thread.hpp>
52 
57 using namespace std;
58 using namespace pcl;
59 using namespace ros;
60 using namespace APC;
61 
63  public:
65  : nh_(nh),
66  publisherEnabled_(true),
67  actionServer_(nh_, "segmentation", false) {
68  std::string pc_topic;
69  nh_.getParam("pointcloud_topic", pc_topic);
70 
71  if (pc_topic.empty()) {
72  pc_topic = "/realsense/points_aligned";
73  }
74  // pub sub
75  pcl_sub_ =
76  nh_.subscribe(pc_topic, 1, &SegmentationNode::scan_callback, this);
77  segmented_pub_ =
78  nh_.advertise<sensor_msgs::PointCloud2>("segmented_pointcloud", 1);
79 
80  // register services
81  doSegmentationSrv_ = nh_.advertiseService(
82  "do_segmentation", &SegmentationNode::doSegmentation, this);
83  enablePublisherSrv_ = nh_.advertiseService(
84  "enable_publisher", &SegmentationNode::enablePublisher, this);
85 
86  // register action server
87  actionServer_.registerGoalCallback(
88  boost::bind(&SegmentationNode::goalCB, this));
89 
90  actionServer_.start();
91 
92  Config config = segmentation.getConfig();
93 
94  // Initialize params from the param server
95  nh_.param<float>("voxel_resolution", config.voxel_resolution, 0.003f);
96  nh_.param<float>("seed_resolution", config.seed_resolution, 0.05f);
97 
98  nh_.param<float>("color_importance", config.color_importance, 1.0f);
99  nh_.param<float>("spatial_importance", config.spatial_importance, 0.4f);
100  nh_.param<float>("normal_importance", config.normal_importance, 1.0f);
101 
102  nh_.param<bool>("use_single_cam_transform",
103  config.use_single_cam_transform, false);
104  nh_.param<bool>("use_supervoxel_refinement",
105  config.use_supervoxel_refinement, false);
106 
107  nh_.param<bool>("use_random_sampling", config.use_random_sampling,
108  false);
109  nh_.param<float>("outlier_cost", config.outlier_cost, 0.02f);
110  nh_.param<float>("smooth_cost", config.smooth_cost,
111  config.outlier_cost * 0.01);
112 
113  nh_.param<int>("min_inliers_per_plane", config.min_inliers_per_plane,
114  10);
115  nh_.param<float>(
116  "label_cost", config.label_cost,
117  config.min_inliers_per_plane * 0.5 * config.outlier_cost);
118 
119  nh_.param<int>("max_num_iterations", config.max_num_iterations, 25);
120  nh_.param<float>("max_curvature", config.max_curvature, 0.001f);
121  nh_.param<int>("gc_scale", config.gc_scale, 1e4);
122 
123  segmentation.setConfig(config);
124  }
125 
129  void goalCB() {
130  actionServer_.acceptNewGoal();
131  publisherEnabled_ = false;
132  segmentation_thread = new boost::thread(
133  boost::bind(&SegmentationNode::doSegmentation, this));
134  }
135 
141  void doSegmentation() {
142  cpf_segmentation_ros::DoSegmentationResult result;
143  pcl::PointCloud<pcl::PointXYZL>::Ptr segmented_pc_ptr;
144 
145  std::vector<int> removedIndices;
146  pcl::removeNaNFromPointCloud(cloud_, cloud_, removedIndices);
147 
148  if (cloud_.size() > 0) {
149  segmentation.setPointCloud(cloud_.makeShared());
150  segmentation.doSegmentation();
151  segmented_pc_ptr = segmentation.getSegmentedPointCloud();
152 
153  pcl::PointCloud<PointXYZL> cloud2_;
154 
155  pcl::copyPointCloud(*segmented_pc_ptr, cloud2_);
156  cloud2_.clear();
157 
158  BOOST_FOREACH (pcl::PointXYZL point, *segmented_pc_ptr) {
159  if (point.label == 0) continue;
160  cloud2_.push_back(point);
161  }
162 
163  pcl::toROSMsg(cloud2_, result.segmented_cloud);
164 
165  actionServer_.setSucceeded(result);
166  } else {
167  ROS_ERROR("No points in cloud. Aborting..\n");
168  actionServer_.setAborted(result);
169  }
170  }
171 
178  bool enablePublisher(cpf_segmentation_ros::EnablePublisher::Request &req,
179  cpf_segmentation_ros::EnablePublisher::Response &resp) {
180  ROS_INFO("Publisher set to %d\n", req.enable);
181  publisherEnabled_ = req.enable;
182  return true;
183  }
184 
191  bool doSegmentation(cpf_segmentation_ros::DoSegmentation::Request &req,
192  cpf_segmentation_ros::DoSegmentation::Response &res) {
193  sensor_msgs::PointCloud2 seg_msg;
194  pcl::PointCloud<pcl::PointXYZL>::Ptr segmented_pc_ptr;
195 
196  pcl::fromROSMsg(req.input_cloud, cloud_);
197 
198  std::vector<int> removedIndices;
199  pcl::removeNaNFromPointCloud(cloud_, cloud_, removedIndices);
200 
201  ROS_INFO("Got cloud %lu points\n", cloud_.size());
202 
203  segmentation.setPointCloud(cloud_.makeShared());
204 
205  segmentation.doSegmentation();
206 
207  segmented_pc_ptr = segmentation.getSegmentedPointCloud();
208 
209  pcl::PointCloud<PointXYZL> cloud2_;
210  if (cloud_.size() > 0) {
211  pcl::copyPointCloud(*segmented_pc_ptr, cloud2_);
212  cloud2_.clear();
213 
214  BOOST_FOREACH (pcl::PointXYZL point, *segmented_pc_ptr) {
215  if (point.label == 0) continue;
216  cloud2_.push_back(point);
217  }
218  pcl::toROSMsg(cloud2_, res.segmented_cloud);
219  res.segmented_cloud.header = req.input_cloud.header;
220  segmented_pub_.publish(res.segmented_cloud);
221  } else {
222  res.segmented_cloud.header = req.input_cloud.header;
223  }
224  return true;
225  }
230  void scan_callback(const sensor_msgs::PointCloud2ConstPtr &cloud_ptr) {
231  pcl::fromROSMsg(*cloud_ptr, cloud_);
232 
233  if (publisherEnabled_ && cloud_.size() > 0) {
234  sensor_msgs::PointCloud2 seg_msg;
235  pcl::PointCloud<pcl::PointXYZL>::Ptr segmented_pc_ptr;
236 
237  std::vector<int> removedIndices;
238  pcl::removeNaNFromPointCloud(cloud_, cloud_, removedIndices);
239 
240  segmentation.setPointCloud(cloud_.makeShared());
241 
242  segmentation.doSegmentation();
243 
244  segmented_pc_ptr = segmentation.getSegmentedPointCloud();
245 
246  if (cloud_.size() > 0) {
247  pcl::PointCloud<PointXYZL> cloud2_;
248 
249  pcl::copyPointCloud(*segmented_pc_ptr, cloud2_);
250  cloud2_.clear();
251 
252  BOOST_FOREACH (pcl::PointXYZL point, *segmented_pc_ptr) {
253  if (point.label == 0) continue;
254  cloud2_.push_back(point);
255  }
256 
257  pcl::toROSMsg(cloud2_, seg_msg);
258  segmented_pub_.publish(seg_msg);
259  }
260  }
261  }
262 
263  private:
265 
266  // pub sub
269 
270  // services
273 
274  // action libs
276 
277  boost::thread *segmentation_thread;
278 
279  pcl::PointCloud<PointT> cloud_;
280  Segmentation segmentation;
281 
282  // enable/desable publisher
284 };
285 
286 int main(int argc, char **argv) {
287  ros::init(argc, argv, "segmentation_node");
288  ros::NodeHandle nh("~");
289  SegmentationNode node(nh);
290 
291  ros::spin();
292 
293  ROS_INFO("Terminating node...");
294 
295  return 0;
296 }
boost::thread * segmentation_thread
ros::Publisher segmented_pub_
void scan_callback(const sensor_msgs::PointCloud2ConstPtr &cloud_ptr)
scan_callback
ros::ServiceServer enablePublisherSrv_
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
void fromROSMsg(const sensor_msgs::PointCloud2 &cloud, pcl::PointCloud< T > &pcl_cloud)
int main(int argc, char **argv)
SegmentationNode(ros::NodeHandle nh)
void goalCB()
goalCB callback funtion for the new goal
actionlib::SimpleActionServer< cpf_segmentation_ros::DoSegmentationAction > actionServer_
#define ROS_INFO(...)
ROSCPP_DECL void spin()
void doSegmentation()
doSegmentation thread for doing the segmentation
bool doSegmentation(cpf_segmentation_ros::DoSegmentation::Request &req, cpf_segmentation_ros::DoSegmentation::Response &res)
doSegmentation service callback for synchronized processing
bool enablePublisher(cpf_segmentation_ros::EnablePublisher::Request &req, cpf_segmentation_ros::EnablePublisher::Response &resp)
enablePublisher
ros::ServiceServer doSegmentationSrv_
void toROSMsg(const sensor_msgs::PointCloud2 &cloud, sensor_msgs::Image &image)
pcl::PointCloud< PointT > cloud_
#define ROS_ERROR(...)


cpf_segmentation_ros
Author(s):
autogenerated on Mon Jun 10 2019 13:04:53