34 #define BOOST_PARAMETER_MAX_ARITY 7
37 #include <visualization_msgs/Marker.h>
38 #include <pcl/surface/concave_hull.h>
39 #include <pcl/sample_consensus/method_types.h>
40 #include <pcl/sample_consensus/model_types.h>
41 #include <pcl/segmentation/sac_segmentation.h>
42 #include <pcl/filters/project_inliers.h>
43 #include <pcl/filters/extract_indices.h>
44 #include <pcl/ModelCoefficients.h>
45 #include <pcl/kdtree/kdtree.h>
46 #include <pcl/segmentation/extract_clusters.h>
47 #include <pcl/common/centroid.h>
53 pcl::console::setVerbosityLevel(pcl::console::L_ERROR);
54 DiagnosticNodelet::onInit();
55 srv_ = boost::make_shared <dynamic_reconfigure::Server<Config> > (*pnh_);
56 typename dynamic_reconfigure::Server<Config>::CallbackType
f =
58 srv_->setCallback (
f);
61 *pnh_,
"output/hint/polygon", 1);
63 *pnh_,
"output/hint/polygon_array", 1);
65 *pnh_,
"output/hint/inliers", 1);
67 *pnh_,
"output/hint/coefficients", 1);
69 *pnh_,
"output/polygon", 1);
71 *pnh_,
"output/polygon_array", 1);
73 *pnh_,
"output/hint_filtered_indices", 1);
75 *pnh_,
"output/plane_filtered_indices", 1);
77 *pnh_,
"output/density_filtered_indices", 1);
79 *pnh_,
"output/euclidean_filtered_indices", 1);
81 *pnh_,
"output/inliers", 1);
83 *pnh_,
"output/coefficients", 1);
103 sync_ = boost::make_shared<message_filters::Synchronizer<SyncPolicy> >(100);
105 sync_->registerCallback(
129 Config &config, uint32_t level)
150 if (need_resubscribe && isSubscribed()) {
157 const sensor_msgs::PointCloud2::ConstPtr &
msg)
165 const sensor_msgs::PointCloud2::ConstPtr& cloud_msg,
166 const sensor_msgs::PointCloud2::ConstPtr& hint_cloud_msg)
168 vital_checker_->poke();
170 if (!hint_cloud_msg) {
173 "hint cloud is not received. Set hint cloud or enable 'synchronize'");
176 pcl::PointCloud<pcl::PointNormal>::Ptr
177 input_cloud (
new pcl::PointCloud<pcl::PointNormal>);
178 pcl::PointCloud<pcl::PointXYZ>::Ptr
179 hint_cloud (
new pcl::PointCloud<pcl::PointXYZ>);
198 pcl::PointCloud<pcl::PointNormal>::Ptr input_cloud,
199 const std::vector<pcl::PointIndices>& cluster_indices,
202 Eigen::Vector3f center = hint_convex->centroid();
203 double min_dist = DBL_MAX;
204 size_t min_index = 0;
205 for (
size_t i = 0;
i < cluster_indices.size();
i++) {
206 Eigen::Vector4f center_cluster4;
207 pcl::compute3DCentroid<pcl::PointNormal>(*input_cloud,
208 cluster_indices[
i].indices,
210 Eigen::Vector3f center_cluster3(center_cluster4[0], center_cluster4[1], center_cluster4[2]);
211 double dist = (center - center_cluster3).norm();
212 if (dist < min_dist) {
217 pcl::PointIndices::Ptr ret (
new pcl::PointIndices);
218 ret->indices = cluster_indices[min_index].indices;
223 const pcl::PointCloud<pcl::PointNormal>::Ptr cloud,
224 const pcl::PointIndices::Ptr indices,
225 pcl::PointIndices& output)
228 pcl::KdTreeFLANN<pcl::PointNormal> kdtree;
229 pcl::KdTreeFLANN<pcl::PointNormal>::IndicesPtr indices_ptr
230 (
new std::vector<int>);
231 *indices_ptr = indices->indices;
232 kdtree.setInputCloud(
cloud, indices_ptr);
233 for (
size_t i = 0;
i < indices->indices.size();
i++) {
234 int point_index = indices->indices[
i];
235 std::vector<int> result_indices;
236 std::vector<float> result_distances;
238 result_indices, result_distances);
240 output.indices.push_back(point_index);
247 output.header =
cloud->header;
254 const pcl::PointCloud<pcl::PointNormal>::Ptr cloud,
255 const pcl::PointIndices::Ptr indices,
257 pcl::PointIndices& output)
260 pcl::EuclideanClusterExtraction<pcl::PointNormal> ec;
262 pcl::search::KdTree<pcl::PointNormal>::Ptr
tree
263 (
new pcl::search::KdTree<pcl::PointNormal>);
265 ec.setSearchMethod(
tree);
266 ec.setIndices(indices);
267 ec.setInputCloud(
cloud);
269 std::vector<pcl::PointIndices> cluster_indices;
270 ec.extract(cluster_indices);
271 if (cluster_indices.size() == 0) {
275 pcl::PointIndices::Ptr filtered_indices
277 output = *filtered_indices;
282 output.header =
cloud->header;
289 const pcl::PointCloud<pcl::PointNormal>::Ptr cloud,
291 pcl::PointIndices& output)
293 for (
size_t i = 0;
i <
cloud->points.size();
i++) {
294 pcl::PointNormal
p =
cloud->points[
i];
295 if (!std::isnan(
p.x) && !std::isnan(
p.y) && !std::isnan(
p.y)) {
296 Eigen::Vector4f
v =
p.getVector4fMap();
298 Eigen::Vector3f
n(
p.normal_x,
p.normal_y,
p.normal_z);
300 output.indices.push_back(
i);
305 output.header =
cloud->header;
312 const pcl::PointCloud<pcl::PointNormal>::Ptr cloud,
313 const pcl::PointIndices::Ptr indices,
314 const Eigen::Vector3f& normal,
315 pcl::PointIndices& output,
316 pcl::ModelCoefficients& coefficients)
318 pcl::SACSegmentation<pcl::PointNormal> seg;
319 seg.setOptimizeCoefficients (
true);
320 seg.setModelType (pcl::SACMODEL_PERPENDICULAR_PLANE);
321 seg.setMethodType (pcl::SAC_RANSAC);
326 seg.setInputCloud(
cloud);
327 seg.setIndices(indices);
330 output.header =
cloud->header;
337 pcl::PointCloud<pcl::PointNormal>::Ptr input_cloud,
340 pcl::PointIndices::Ptr candidate_inliers (
new pcl::PointIndices);
341 hintFilter(input_cloud, hint_convex, *candidate_inliers);
344 pcl::PointIndices::Ptr plane_inliers (
new pcl::PointIndices);
345 pcl::ModelCoefficients::Ptr plane_coefficients(
new pcl::ModelCoefficients);
347 hint_convex->getNormal(),
348 *plane_inliers, *plane_coefficients);
349 if (plane_inliers->indices.size() <
min_size_) {
350 NODELET_ERROR(
"failed to detect by plane fitting filtering");
354 Eigen::Vector3f plane_normal(plane_coefficients->values[0], plane_coefficients->values[1], plane_coefficients->values[2]);
355 if (plane_normal.dot(Eigen::Vector3f::UnitZ()) > 0) {
357 plane_coefficients->values[0] = -plane_coefficients->values[0];
358 plane_coefficients->values[1] = -plane_coefficients->values[1];
359 plane_coefficients->values[2] = -plane_coefficients->values[2];
360 plane_coefficients->values[3] = -plane_coefficients->values[3];
363 pcl::PointIndices::Ptr euclidean_filtered_indices(
new pcl::PointIndices);
365 *euclidean_filtered_indices);
366 if (euclidean_filtered_indices->indices.size() <
min_size_) {
370 pcl::PointIndices::Ptr density_filtered_indices (
new pcl::PointIndices);
372 input_cloud, euclidean_filtered_indices, *density_filtered_indices);
374 if (density_filtered_indices->indices.size() <
min_size_) {
379 = jsk_recognition_utils::convexFromCoefficientsAndInliers<pcl::PointNormal>(
380 input_cloud, density_filtered_indices, plane_coefficients);
383 input_cloud->header);
397 const pcl::PCLHeader&
header)
399 geometry_msgs::PolygonStamped ros_polygon;
400 ros_polygon.polygon = convex->toROSMsg();
402 jsk_recognition_msgs::PolygonArray ros_polygon_array;
404 ros_polygon_array.polygons.push_back(
406 pub_polygon_array.
publish(ros_polygon_array);
411 pcl::PointCloud<pcl::PointXYZ>::Ptr hint_cloud,
414 pcl::PointIndices::Ptr hint_inliers (
new pcl::PointIndices);
415 pcl::ModelCoefficients::Ptr hint_coefficients(
new pcl::ModelCoefficients);
416 pcl::SACSegmentation<pcl::PointXYZ> seg;
417 seg.setOptimizeCoefficients (
true);
418 seg.setModelType (pcl::SACMODEL_PLANE);
419 seg.setMethodType (pcl::SAC_RANSAC);
422 seg.setInputCloud(hint_cloud);
423 seg.segment(*hint_inliers, *hint_coefficients);
425 convex = jsk_recognition_utils::convexFromCoefficientsAndInliers<pcl::PointXYZ>(
426 hint_cloud, hint_inliers, hint_coefficients);