35 #define BOOST_PARAMETER_MAX_ARITY 7
38 #include <pcl/sample_consensus/method_types.h>
39 #include <pcl/sample_consensus/model_types.h>
40 #include <pcl/segmentation/sac_segmentation.h>
41 #include <pcl/filters/project_inliers.h>
42 #include <pcl/filters/extract_indices.h>
43 #include <pcl/features/normal_3d_omp.h>
44 #include <visualization_msgs/Marker.h>
45 #include <geometry_msgs/PoseStamped.h>
51 DiagnosticNodelet::onInit();
52 srv_ = boost::make_shared <dynamic_reconfigure::Server<Config> > (*pnh_);
53 typename dynamic_reconfigure::Server<Config>::CallbackType
f =
55 srv_->setCallback (
f);
60 *pnh_,
"debug/line_filtered_indices", 1);
62 *pnh_,
"debug/line_filtered_normal", 1);
64 *pnh_,
"debug/cylinder_marker", 1);
66 *pnh_,
"output/cylinder_pose", 1);
68 *pnh_,
"output/inliers", 1);
70 *pnh_,
"output/coefficients", 1);
91 sync_ = boost::make_shared<message_filters::Synchronizer<ASyncPolicy> >(100);
108 const sensor_msgs::PointCloud2::ConstPtr& cloud_msg)
123 const geometry_msgs::PolygonStamped::ConstPtr& hint_msg)
130 const sensor_msgs::CameraInfo::ConstPtr& info_msg)
152 const geometry_msgs::PolygonStamped::ConstPtr& polygon_msg,
153 const sensor_msgs::CameraInfo::ConstPtr& camera_info_msg,
154 const sensor_msgs::PointCloud2::ConstPtr& cloud_msg)
160 model.fromCameraInfo(camera_info_msg);
161 pcl::PointCloud<pcl::PointXYZ>::Ptr
cloud
162 (
new pcl::PointCloud<pcl::PointXYZ>);
165 Eigen::Vector3f
a,
b;
167 pcl::PointIndices::Ptr candidate_indices
168 (
new pcl::PointIndices);
171 pcl::PointCloud<pcl::Normal>::Ptr normals
172 (
new pcl::PointCloud<pcl::Normal>);
173 pcl::PointCloud<pcl::PointXYZ>::Ptr normals_cloud
174 (
new pcl::PointCloud<pcl::PointXYZ>);
180 pcl::PointCloud<pcl::Normal>::Ptr all_normals
181 (
new pcl::PointCloud<pcl::Normal>);
183 pcl::ExtractIndices<pcl::PointXYZ> xyz_extract;
184 xyz_extract.setInputCloud(
cloud);
185 xyz_extract.setIndices(candidate_indices);
186 xyz_extract.filter(*normals_cloud);
188 pcl::ExtractIndices<pcl::Normal> normal_extract;
189 normal_extract.setInputCloud(all_normals);
190 normal_extract.setIndices(candidate_indices);
191 normal_extract.filter(*normals);
199 const pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud,
200 const pcl::PointIndices::Ptr indices,
201 pcl::PointCloud<pcl::Normal>& normals,
202 pcl::PointCloud<pcl::PointXYZ>& normals_cloud)
204 pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> ne;
205 ne.setInputCloud(
cloud);
206 ne.setIndices(indices);
207 pcl::search::KdTree<pcl::PointXYZ>::Ptr
tree
208 (
new pcl::search::KdTree<pcl::PointXYZ> ());
209 ne.setSearchMethod(
tree);
210 ne.setRadiusSearch (0.03);
211 ne.compute (normals);
212 pcl::ExtractIndices<pcl::PointXYZ>
ex;
214 ex.setIndices(indices);
215 ex.filter(normals_cloud);
220 const Eigen::Vector3f& a,
221 const Eigen::Vector3f& b)
223 Eigen::Vector3f hint_dir((
b -
a));
225 hint_dir.normalize();
226 Eigen::Vector3f cylinder_dir(cylinder->getDirection());
228 cylinder_dir.normalize();
229 double ang = acos(cylinder_dir.dot(hint_dir));
235 const pcl::PointCloud<pcl::PointXYZ>::Ptr& filtered_cloud,
236 const pcl::PointCloud<pcl::Normal>::Ptr& cloud_normals,
237 const Eigen::Vector3f& a,
238 const Eigen::Vector3f& b)
240 pcl::SACSegmentationFromNormals<pcl::PointXYZ, pcl::Normal> seg;
241 pcl::PointIndices::Ptr inliers (
new pcl::PointIndices);
242 pcl::ModelCoefficients::Ptr
coefficients(
new pcl::ModelCoefficients);
243 Eigen::Vector3f normal = (
a -
b).normalized();
244 seg.setOptimizeCoefficients (
true);
245 seg.setModelType (pcl::SACMODEL_CYLINDER);
246 seg.setMethodType (pcl::SAC_RANSAC);
249 seg.setNormalDistanceWeight (0.1);
254 seg.setInputCloud(filtered_cloud);
255 seg.setInputNormals(cloud_normals);
262 if (dir.dot(Eigen::Vector3f(0, -1, 0)) < 0) {
271 pcl::PointIndices::Ptr cylinder_indices
272 (
new pcl::PointIndices);
273 cylinder->filterPointCloud(*filtered_cloud,
277 Eigen::Vector3f center;
278 cylinder->estimateCenterAndHeight(
279 *filtered_cloud, *cylinder_indices,
282 Eigen::Vector3f uz = Eigen::Vector3f(
285 visualization_msgs::Marker
marker;
289 geometry_msgs::PoseStamped
pose;
299 ros_coefficients.values.push_back(center[0]);
300 ros_coefficients.values.push_back(center[1]);
301 ros_coefficients.values.push_back(center[2]);
302 ros_coefficients.values.push_back(dir[0]);
303 ros_coefficients.values.push_back(dir[1]);
304 ros_coefficients.values.push_back(dir[2]);
305 ros_coefficients.values.push_back(
coefficients->values[6]);
306 ros_coefficients.values.push_back(
height);
316 const pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud,
318 pcl::PointIndices& output_indices)
320 output_indices.indices.clear();
321 for (
size_t i = 0;
i <
cloud->points.size();
i++) {
322 pcl::PointXYZ
p =
cloud->points[
i];
323 if (!std::isnan(
p.x) && !std::isnan(
p.y) && !std::isnan(
p.z)) {
324 if (
polygon->isProjectableInside(
p.getVector3fMap())) {
326 output_indices.indices.push_back(
i);
331 output_indices.header =
cloud->header;
339 const geometry_msgs::PolygonStamped::ConstPtr& polygon_msg,
344 cv::Point2d point_a(
polygon_msg->polygon.points[0].x,
346 cv::Point2d point_b(
polygon_msg->polygon.points[1].x,
348 cv::Point3d ray_a =
model.projectPixelTo3dRay(point_a);
349 cv::Point3d ray_b =
model.projectPixelTo3dRay(point_b);
350 a = Eigen::Vector3f(ray_a.x, ray_a.y, ray_a.z);
351 b = Eigen::Vector3f(ray_b.x, ray_b.y, ray_b.z);
353 Eigen::Vector3f far_a = 20.0 *
a;
354 Eigen::Vector3f far_b = 20.0 *
b;
355 Eigen::Vector3f O(0, 0, 0);
357 vertices.push_back(O);
358 vertices.push_back(far_a);
359 vertices.push_back(far_b);