environment_plane_modeling_nodelet.cpp
Go to the documentation of this file.
1 // -*- mode: c++ -*-
2 /*********************************************************************
3  * Software License Agreement (BSD License)
4  *
5  * Copyright (c) 2014, JSK Lab
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  * * Neither the name of the JSK Lab nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *********************************************************************/
35 
36 #define BOOST_PARAMETER_MAX_ARITY 7
37 
39 #include <pcl/filters/extract_indices.h>
40 #include <pcl/common/distances.h>
42 #include <pcl/filters/project_inliers.h>
43 #include <pcl/surface/convex_hull.h>
44 #include <pcl/filters/project_inliers.h>
45 #include <jsk_recognition_msgs/SparseOccupancyGridArray.h>
46 
48 #include <geometry_msgs/PoseArray.h>
50 #include "jsk_pcl_ros/grid_map.h"
51 #include <jsk_topic_tools/rosparam_utils.h>
52 namespace jsk_pcl_ros
53 {
55  {
56  DiagnosticNodelet::onInit();
57 
58  srv_ = boost::make_shared <dynamic_reconfigure::Server<Config> > (*pnh_);
59  typename dynamic_reconfigure::Server<Config>::CallbackType f =
60  boost::bind (&EnvironmentPlaneModeling::configCallback, this, _1, _2);
61  srv_->setCallback (f);
62 
63  pnh_->param("complete_footprint_region", complete_footprint_region_, false);
65  = pnh_->advertise<jsk_recognition_msgs::PolygonArray>(
66  "debug/magnified_polygons", 1);
68  = pnh_->advertise<sensor_msgs::PointCloud2>(
69  "debug/convex_cloud", 1);
71  = pnh_->advertise<jsk_recognition_msgs::SimpleOccupancyGridArray>(
72  "debug/raw_grid_map", 1);
74  = pnh_->advertise<jsk_recognition_msgs::SimpleOccupancyGridArray>(
75  "debug/noeroded_grid_map", 1);
77  = pnh_->advertise<geometry_msgs::PoseArray>(
78  "debug/plane_poses", 1);
80  = pnh_->advertise<geometry_msgs::PoseArray>(
81  "debug/magnified_plane_poses", 1);
83  = pnh_->advertise<jsk_recognition_msgs::SimpleOccupancyGridArray>(
84  "output", 1, true);
85  pub_snapped_move_base_simple_goal_ = pnh_->advertise<geometry_msgs::PoseStamped>(
86  "/footstep_simple/goal", 1);
87  pub_non_plane_indices_ = pnh_->advertise<PCLIndicesMsg>(
88  "output/non_plane_indices", 1);
91 
92  sub_leg_bbox_ = pnh_->subscribe(
93  "input/leg_bounding_box", 1,
95 
96  jsk_topic_tools::readVectorParameter(
97  *pnh_, "footprint_frames", footprint_frames_);
98 
99  }
100  sub_move_base_simple_goal_ = pnh_->subscribe(
101  "/move_base_simple/goal", 1,
103  sub_cloud_.subscribe(*pnh_, "input", 1);
104  sub_full_cloud_.subscribe(*pnh_, "input/full_cloud", 1);
105  sub_indices_.subscribe(*pnh_, "input/indices", 1);
106  sub_polygons_.subscribe(*pnh_, "input/polygons", 1);
107  sub_coefficients_.subscribe(*pnh_, "input/coefficients", 1);
108  sync_ = boost::make_shared<message_filters::Synchronizer<SyncPolicy> >(100);
111  sync_->registerCallback(
113  this, _1, _2, _3, _4, _5));
114 
115  onInitPostProcess();
116  }
117 
119  // message_filters::Synchronizer needs to be called reset
120  // before message_filters::Subscriber is freed.
121  // Calling reset fixes the following error on shutdown of the nodelet:
122  // terminate called after throwing an instance of
123  // 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::lock_error> >'
124  // what(): boost: mutex lock failed in pthread_mutex_lock: Invalid argument
125  // Also see https://github.com/ros/ros_comm/issues/720 .
126  sync_.reset();
127  }
128 
129  void EnvironmentPlaneModeling::configCallback(Config &config, uint32_t level)
130  {
131  boost::mutex::scoped_lock lock(mutex_);
132  magnify_distance_ = config.magnify_distance;
133  distance_threshold_ = config.distance_threshold;
134  normal_threshold_ = config.normal_threshold;
135  resolution_ = config.resolution;
136  morphological_filter_size_ = config.morphological_filter_size;
137  erode_filter_size_ = config.erode_filter_size;
138  footprint_plane_angular_threshold_ = config.footprint_plane_angular_threshold;
139  footprint_plane_distance_threshold_ = config.footprint_plane_distance_threshold;
140  }
141 
143  const sensor_msgs::PointCloud2::ConstPtr& cloud_msg,
144  const sensor_msgs::PointCloud2::ConstPtr& full_cloud_msg,
145  const jsk_recognition_msgs::PolygonArray::ConstPtr& polygon_msg,
146  const jsk_recognition_msgs::ModelCoefficientsArray::ConstPtr& coefficients_msg,
147  const jsk_recognition_msgs::ClusterPointIndices::ConstPtr& indices_msg)
148  {
149  NODELET_INFO("Input data --");
150  NODELET_INFO(" Number of points -- %d", cloud_msg->width * cloud_msg->height);
151  NODELET_INFO(" Number of full points -- %d", full_cloud_msg->width * full_cloud_msg->height);
152  NODELET_INFO(" Number of clusters: -- %lu", indices_msg->cluster_indices.size());
153  NODELET_INFO(" Frame Id: %s", cloud_msg->header.frame_id.c_str());
154  NODELET_INFO(" Complete Footprint: %s", complete_footprint_region_? "true": "false");
155  }
156 
158  const sensor_msgs::PointCloud2::ConstPtr& cloud_msg,
159  const sensor_msgs::PointCloud2::ConstPtr& full_cloud_msg,
160  const jsk_recognition_msgs::PolygonArray::ConstPtr& polygon_msg,
161  const jsk_recognition_msgs::ModelCoefficientsArray::ConstPtr& coefficients_msg,
162  const jsk_recognition_msgs::ClusterPointIndices::ConstPtr& indices_msg)
163  {
164  std::string frame_id = cloud_msg->header.frame_id;
165  if (full_cloud_msg->header.frame_id != frame_id) {
166  return false;
167  }
168  if (polygon_msg->header.frame_id != frame_id) {
169  return false;
170  }
171  for (size_t i = 0; i < polygon_msg->polygons.size(); i++) {
172  if (polygon_msg->polygons[i].header.frame_id != frame_id) {
173  return false;
174  }
175  }
176  if (coefficients_msg->header.frame_id != frame_id) {
177  return false;
178  }
179  for (size_t i = 0; i < coefficients_msg->coefficients.size(); i++) {
180  if (coefficients_msg->coefficients[i].header.frame_id != frame_id) {
181  return false;
182  }
183  }
184  if (indices_msg->header.frame_id != frame_id) {
185  return false;
186  }
187  for (size_t i = 0; i < indices_msg->cluster_indices.size(); i++) {
188  if (indices_msg->cluster_indices[i].header.frame_id != frame_id) {
189  return false;
190  }
191  }
192  return true;
193  }
194 
196  const geometry_msgs::PoseStamped::ConstPtr& msg)
197  {
198  boost::mutex::scoped_lock lock(mutex_);
199  if (latest_grid_maps_.size() == 0) {
200  NODELET_WARN("not yet grid maps are available");
201  return;
202  }
203 
205  tf_listener_,
206  latest_global_header_.frame_id,
207  msg->header.frame_id,
208  latest_global_header_.stamp,
209  ros::Duration(1.0));
210 
211  Eigen::Affine3f local_coords, transform;
212  tf::poseMsgToEigen(msg->pose, local_coords);
213  tf::transformTFToEigen(tf_transform, transform);
214  Eigen::Affine3f global_coords = transform * local_coords;
215 
216  // lookup suitable grid
217  double max_height = - DBL_MAX;
218  GridPlane::Ptr max_grid;
219  Eigen::Affine3f max_projected_coords = Eigen::Affine3f::Identity();
220  for (size_t i = 0; i < latest_grid_maps_.size(); i++) {
221  GridPlane::Ptr target_grid = latest_grid_maps_[i];
222  Eigen::Affine3f projected_coords;
223  target_grid->getPolygon()->projectOnPlane(global_coords, projected_coords);
224  Eigen::Vector3f projected_point(projected_coords.translation());
225  if (target_grid->isOccupiedGlobal(projected_point)) {
226  double height = projected_point[2];
227  if (max_height < height) {
228  max_height = height;
229  max_grid = target_grid;
230  max_projected_coords = projected_coords;
231  }
232  }
233  }
234  if (max_grid) {
235  // publish it
236  geometry_msgs::PoseStamped ros_coords;
237  tf::poseEigenToMsg(max_projected_coords, ros_coords.pose);
238  ros_coords.header.stamp = msg->header.stamp;
239  ros_coords.header.frame_id = latest_global_header_.frame_id;
241  }
242  else {
243  NODELET_ERROR("Failed to find corresponding grid");
244  }
245  }
246 
248  const jsk_recognition_msgs::BoundingBox::ConstPtr& box)
249  {
250  boost::mutex::scoped_lock lock(mutex_);
252  }
253 
255  const sensor_msgs::PointCloud2::ConstPtr& cloud_msg,
256  const sensor_msgs::PointCloud2::ConstPtr& full_cloud_msg,
257  const jsk_recognition_msgs::PolygonArray::ConstPtr& polygon_msg,
258  const jsk_recognition_msgs::ModelCoefficientsArray::ConstPtr& coefficients_msg,
259  const jsk_recognition_msgs::ClusterPointIndices::ConstPtr& indices_msg)
260  {
261  boost::mutex::scoped_lock lock(mutex_);
262  try {
263  // check frame_id
264  if (!isValidFrameIds(cloud_msg, full_cloud_msg, polygon_msg, coefficients_msg, indices_msg)) {
265  NODELET_FATAL("frame_id is not correct");
266  return;
267  }
269  NODELET_ERROR("Bounding Box for Footprint is not yet ready");
270  return;
271  }
272  // first, print all the information about ~inputs
273  printInputData(cloud_msg, full_cloud_msg, polygon_msg, coefficients_msg, indices_msg);
274 
275 
276  pcl::PointCloud<pcl::PointNormal>::Ptr cloud (new pcl::PointCloud<pcl::PointNormal>);
277  pcl::fromROSMsg(*cloud_msg, *cloud);
278 
279  pcl::PointCloud<pcl::PointNormal>::Ptr full_cloud (new pcl::PointCloud<pcl::PointNormal>);
280  pcl::fromROSMsg(*full_cloud_msg, *full_cloud);
281 
282  // convert to jsk_recognition_utils::ConvexPolygon
283  std::vector<jsk_recognition_utils::ConvexPolygon::Ptr> convexes = convertToConvexPolygons(cloud, indices_msg, coefficients_msg);
284  // magnify convexes
285  std::vector<jsk_recognition_utils::ConvexPolygon::Ptr> magnified_convexes = magnifyConvexes(convexes);
286  publishConvexPolygonsBoundaries(pub_debug_convex_point_cloud_, cloud_msg->header, magnified_convexes);
287  // Publish magnified convexes for debug
288  publishConvexPolygons(pub_debug_magnified_polygons_, cloud_msg->header, magnified_convexes);
289  // publish pose_array for debug
290  {
291  geometry_msgs::PoseArray pose_array;
292  pose_array.header = cloud_msg->header;
293  for (size_t i = 0; i < convexes.size(); i++) {
294  Eigen::Affine3f pose = convexes[i]->coordinates();
295  geometry_msgs::Pose ros_pose;
296  tf::poseEigenToMsg(pose, ros_pose);
297  pose_array.poses.push_back(ros_pose);
298  }
299  pub_debug_plane_coords_.publish(pose_array);
300  }
301  {
302  geometry_msgs::PoseArray pose_array;
303  pose_array.header = cloud_msg->header;
304  for (size_t i = 0; i < magnified_convexes.size(); i++) {
305  Eigen::Affine3f pose = magnified_convexes[i]->coordinates();
306  geometry_msgs::Pose ros_pose;
307  tf::poseEigenToMsg(pose, ros_pose);
308  pose_array.poses.push_back(ros_pose);
309  }
311  }
312 
313  // build GridMaps
314  std::set<int> non_plane_indices;
315  std::vector<GridPlane::Ptr> raw_grid_planes = buildGridPlanes(full_cloud, magnified_convexes, non_plane_indices);
316 
317  publishGridMaps(pub_debug_raw_grid_map_, cloud_msg->header, raw_grid_planes);
318  PCLIndicesMsg ros_non_plane_indices;
319  ros_non_plane_indices.indices = std::vector<int>(non_plane_indices.begin(),
320  non_plane_indices.end());
321  ros_non_plane_indices.header = cloud_msg->header;
322  pub_non_plane_indices_.publish(ros_non_plane_indices);
323  std::vector<GridPlane::Ptr> morphological_filtered_grid_planes
324  = morphologicalFiltering(raw_grid_planes);
325 
327  morphological_filtered_grid_planes);
328 
329  std::vector<GridPlane::Ptr> eroded_grid_planes
330  = erodeFiltering(morphological_filtered_grid_planes);
331  std::vector<GridPlane::Ptr> result_grid_planes;
332 
333  if (complete_footprint_region_) { // complete footprint region if needed
334  result_grid_planes
335  = completeFootprintRegion(cloud_msg->header,
336  eroded_grid_planes);
337  }
338  else {
339  result_grid_planes = eroded_grid_planes;
340  }
341 
342  publishGridMaps(pub_grid_map_, cloud_msg->header,
343  result_grid_planes);
344 
345  latest_global_header_ = cloud_msg->header;
346  latest_grid_maps_ = result_grid_planes;
347  }
348  catch (tf2::TransformException& e) {
349  NODELET_ERROR("Failed to lookup transformation: %s", e.what());
350  }
351  }
352 
353  std::vector<GridPlane::Ptr> EnvironmentPlaneModeling::erodeFiltering(
354  std::vector<GridPlane::Ptr>& grid_maps)
355  {
356  std::vector<GridPlane::Ptr> ret;
357  for (size_t i = 0; i < grid_maps.size(); i++) {
358  GridPlane::Ptr eroded_grid_map = grid_maps[i]->erode(erode_filter_size_);
359  ret.push_back(eroded_grid_map);
360  }
361  return ret;
362  }
363 
365  const Eigen::Affine3f& pose, const std::vector<GridPlane::Ptr>& grid_maps)
366  {
367  Eigen::Vector3f foot_z = (pose.rotation() * Eigen::Vector3f::UnitZ()).normalized();
368  Eigen::Vector3f foot_p(pose.translation());
369  double min_distance = DBL_MAX;
370  int min_index = -1;
371  for (size_t i = 0; i < grid_maps.size(); i++) {
372  GridPlane::Ptr grid = grid_maps[i];
373  Eigen::Vector3f normal = grid->getPolygon()->getNormal();
374  if (std::abs(normal.dot(foot_z)) > cos(footprint_plane_angular_threshold_)) {
375  // compare distance
376  if (grid->getPolygon()->distanceToPoint(foot_p) < footprint_plane_distance_threshold_) {
377  Eigen::Vector3f foot_center(pose.translation());
378  if (!grid->isOccupiedGlobal(foot_center)) {
379  // check distance to point
380  double d = grid->getPolygon()->distanceFromVertices(foot_center);
381  if (d < min_distance) {
382  min_distance = d;
383  min_index = i;
384  }
385  }
386  else {
387  NODELET_INFO("Foot print is already occupied");
388  return -1;
389  }
390  // NB: else break?
391  }
392  }
393  }
394  return min_index;
395  }
396 
398  const std::string& footprint_frame, const std_msgs::Header& header,
399  const std::vector<GridPlane::Ptr>& grid_maps)
400  {
401  // first, lookup location of frames
404  header.frame_id, footprint_frame,
405  header.stamp,
406  ros::Duration(1.0));
407  Eigen::Affine3f eigen_transform;
408  tf::transformTFToEigen(transform, eigen_transform);
409  // lookup ground plane for the foot
410  return lookupGroundPlaneForFootprint(eigen_transform, grid_maps);
411  }
412 
414  const jsk_recognition_msgs::BoundingBox::ConstPtr& box,
415  const std_msgs::Header& header,
416  GridPlane::Ptr grid_map)
417  {
418  // resolve tf
420  tf_listener_,
421  header.frame_id,
422  box->header.frame_id,
423  header.stamp,
424  ros::Duration(1.0));
425  Eigen::Affine3f transform;
426  tf::transformTFToEigen(tf_transform, transform);
427  Eigen::Affine3f local_pose;
428  tf::poseMsgToEigen(box->pose, local_pose);
429  Eigen::Affine3f global_pose = transform * local_pose;
430  std::vector<double> dimensions;
431  dimensions.push_back(box->dimensions.x);
432  dimensions.push_back(box->dimensions.y);
433  dimensions.push_back(box->dimensions.z);
434  jsk_recognition_utils::Cube::Ptr cube (new Cube(Eigen::Vector3f(global_pose.translation()),
435  Eigen::Quaternionf(global_pose.rotation()),
436  dimensions));
437  GridPlane::Ptr completed_grid_map = grid_map->clone();
438  completed_grid_map->fillCellsFromCube(*cube);
439  return completed_grid_map;
440  }
441 
443  const std_msgs::Header& header, std::vector<GridPlane::Ptr>& grid_maps)
444  {
445  try {
446  std::vector<GridPlane::Ptr> completed_grid_maps(grid_maps.size());
447  std::set<int> ground_plane_indices;
448  for (size_t i = 0; i < footprint_frames_.size(); i++) {
449  std::string footprint_frame = footprint_frames_[i];
450  int grid_index = lookupGroundPlaneForFootprint(
451  footprint_frame, header, grid_maps);
452  if (grid_index != -1) {
453  NODELET_INFO("Found ground plane for %s: %d", footprint_frame.c_str(), grid_index);
454  ground_plane_indices.insert(grid_index);
455  }
456  else {
457  NODELET_WARN("Cannnot find ground plane for %s: %d", footprint_frame.c_str(), grid_index);
458  }
459  }
460  for (size_t i = 0; i < grid_maps.size(); i++) {
461  if (ground_plane_indices.find(i) == ground_plane_indices.end()) {
462  // It's not a ground plane, just copy the original
463  completed_grid_maps[i] = grid_maps[i];
464  }
465  else {
466  completed_grid_maps[i] = completeGridMapByBoundingBox(
467  latest_leg_bounding_box_, header, grid_maps[i]);
468  }
469  }
470  return completed_grid_maps;
471  }
472  catch (tf2::TransformException& e) {
473  NODELET_FATAL("Failed to lookup transformation: %s", e.what());
474  return std::vector<GridPlane::Ptr>();
475  }
476  }
477 
479  std::vector<GridPlane::Ptr>& raw_grid_maps)
480  {
481  std::vector<GridPlane::Ptr> ret;
482  for (size_t i = 0; i < raw_grid_maps.size(); i++) {
483  GridPlane::Ptr dilated_grid_map = raw_grid_maps[i]->dilate(morphological_filter_size_);
484  GridPlane::Ptr eroded_grid_map = dilated_grid_map->erode(morphological_filter_size_);
485  ret.push_back(eroded_grid_map);
486  }
487  return ret;
488  }
489 
490 
493  const std_msgs::Header& header,
494  std::vector<jsk_recognition_utils::ConvexPolygon::Ptr>& convexes)
495  {
496  pcl::PointCloud<pcl::PointXYZ>::Ptr
497  boundary_cloud (new pcl::PointCloud<pcl::PointXYZ>);
498  for (size_t i = 0; i < convexes.size(); i++) {
499  pcl::PointCloud<pcl::PointXYZ>::Ptr
500  one_boundary_cloud (new pcl::PointCloud<pcl::PointXYZ>);
501  convexes[i]->boundariesToPointCloud<pcl::PointXYZ>(
502  *one_boundary_cloud);
503  *boundary_cloud = *boundary_cloud + *one_boundary_cloud;
504  }
505  sensor_msgs::PointCloud2 ros_cloud;
506  pcl::toROSMsg(*boundary_cloud, ros_cloud);
507  ros_cloud.header = header;
508  pub.publish(ros_cloud);
509  }
510 
513  const std_msgs::Header& header,
514  std::vector<GridPlane::Ptr>& grids)
515  {
516  jsk_recognition_msgs::SimpleOccupancyGridArray grid_array;
517  grid_array.header = header;
518  for (size_t i = 0; i < grids.size(); i++) {
519  jsk_recognition_msgs::SimpleOccupancyGrid grid = grids[i]->toROSMsg();
520  grid.header = header;
521  grid_array.grids.push_back(grid);
522  }
523  pub.publish(grid_array);
524  }
525 
526 
527  std::vector<GridPlane::Ptr> EnvironmentPlaneModeling::buildGridPlanes(
528  pcl::PointCloud<pcl::PointNormal>::Ptr& cloud,
529  std::vector<jsk_recognition_utils::ConvexPolygon::Ptr> convexes,
530  std::set<int>& non_plane_indices)
531  {
532  std::vector<GridPlane::Ptr> ret(convexes.size());
533 //#pragma omp parallel for
534  for (size_t i = 0; i < convexes.size(); i++) {
535  GridPlane::Ptr grid(new GridPlane(convexes[i], resolution_));
536  size_t num = grid->fillCellsFromPointCloud(cloud, distance_threshold_,
538  non_plane_indices);
539  NODELET_INFO("%lu plane contains %lu points",
540  i, num);
541  ret[i] = grid;
542  }
543  return ret;
544  }
545 
546 
547 
550  const std_msgs::Header& header,
551  std::vector<jsk_recognition_utils::ConvexPolygon::Ptr>& convexes)
552  {
553  jsk_recognition_msgs::PolygonArray polygon_array;
554  polygon_array.header = header;
555  for (size_t i = 0; i < convexes.size(); i++) {
556  geometry_msgs::PolygonStamped polygon;
557  polygon.polygon = convexes[i]->toROSMsg();
558  polygon.header = header;
559  polygon_array.polygons.push_back(polygon);
560  }
561  pub.publish(polygon_array);
562  }
563 
564  std::vector<jsk_recognition_utils::ConvexPolygon::Ptr> EnvironmentPlaneModeling::magnifyConvexes(
565  std::vector<jsk_recognition_utils::ConvexPolygon::Ptr>& convexes)
566  {
567  std::vector<jsk_recognition_utils::ConvexPolygon::Ptr> ret(0);
568  for (size_t i = 0; i < convexes.size(); i++) {
569  jsk_recognition_utils::ConvexPolygon::Ptr vertices_convex(new jsk_recognition_utils::ConvexPolygon(convexes[i]->getVertices()));
570  jsk_recognition_utils::ConvexPolygon::Ptr new_convex = vertices_convex->magnifyByDistance(magnify_distance_);
571  // check orientation
572  if (new_convex->getNormalFromVertices().dot(Eigen::Vector3f::UnitZ()) < 0) {
573  new_convex = boost::make_shared<jsk_recognition_utils::ConvexPolygon>(new_convex->flipConvex());
574  }
575  ret.push_back(new_convex);
576  }
577  return ret;
578  }
579 
580  std::vector<jsk_recognition_utils::ConvexPolygon::Ptr> EnvironmentPlaneModeling::convertToConvexPolygons(
581  const pcl::PointCloud<pcl::PointNormal>::Ptr& cloud,
582  const jsk_recognition_msgs::ClusterPointIndices::ConstPtr& indices_msg,
583  const jsk_recognition_msgs::ModelCoefficientsArray::ConstPtr& coefficients_msg)
584  {
585  std::vector<jsk_recognition_utils::ConvexPolygon::Ptr> convexes(0);
586  for (size_t i = 0; i < indices_msg->cluster_indices.size(); i++) {
587  pcl::PointIndices::Ptr inliers (new pcl::PointIndices);
588  inliers->indices = indices_msg->cluster_indices[i].indices;
589  pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);
590  coefficients->values = coefficients_msg->coefficients[i].values;
592  = jsk_recognition_utils::convexFromCoefficientsAndInliers<pcl::PointNormal>(
593  cloud, inliers, coefficients);
594  convexes.push_back(convex);
595  }
596 
597  return convexes;
598  }
599 
600 }
601 
tf::poseMsgToEigen
void poseMsgToEigen(const geometry_msgs::Pose &m, Eigen::Affine3d &e)
jsk_pcl_ros::EnvironmentPlaneModeling::erodeFiltering
virtual std::vector< GridPlane::Ptr > erodeFiltering(std::vector< GridPlane::Ptr > &grid_maps)
Definition: environment_plane_modeling_nodelet.cpp:353
jsk_recognition_utils::GridPlane
NODELET_FATAL
#define NODELET_FATAL(...)
jsk_pcl_ros::EnvironmentPlaneModeling::footprint_plane_angular_threshold_
double footprint_plane_angular_threshold_
Definition: environment_plane_modeling.h:313
NODELET_ERROR
#define NODELET_ERROR(...)
jsk_pcl_ros::EnvironmentPlaneModeling::sub_full_cloud_
message_filters::Subscriber< sensor_msgs::PointCloud2 > sub_full_cloud_
Definition: environment_plane_modeling.h:281
jsk_pcl_ros::EnvironmentPlaneModeling::sub_indices_
message_filters::Subscriber< jsk_recognition_msgs::ClusterPointIndices > sub_indices_
Definition: environment_plane_modeling.h:282
depth_error_calibration.lock
lock
Definition: depth_error_calibration.py:32
jsk_pcl_ros::EnvironmentPlaneModeling::isValidFrameIds
virtual bool isValidFrameIds(const sensor_msgs::PointCloud2::ConstPtr &cloud_msg, const sensor_msgs::PointCloud2::ConstPtr &full_cloud_msg, const jsk_recognition_msgs::PolygonArray::ConstPtr &polygon_msg, const jsk_recognition_msgs::ModelCoefficientsArray::ConstPtr &coefficients_msg, const jsk_recognition_msgs::ClusterPointIndices::ConstPtr &indices_msg)
Definition: environment_plane_modeling_nodelet.cpp:157
ros::Publisher
_2
boost::arg< 2 > _2
jsk_recognition_utils::ConvexPolygon
jsk_pcl_ros::EnvironmentPlaneModeling::pub_grid_map_
ros::Publisher pub_grid_map_
Definition: environment_plane_modeling.h:293
jsk_pcl_ros::EnvironmentPlaneModeling::tf_listener_
tf::TransformListener * tf_listener_
Definition: environment_plane_modeling.h:297
sample_simulate_tabletop_cloud.polygon
polygon
Definition: sample_simulate_tabletop_cloud.py:167
jsk_pcl_ros::EnvironmentPlaneModeling
Nodelet implementation of jsk_pcl/EnvironmentPlaneModeling.
Definition: environment_plane_modeling.h:112
_3
boost::arg< 3 > _3
boost::shared_ptr
i
int i
sample_simulate_tabletop_cloud.header
header
Definition: sample_simulate_tabletop_cloud.py:162
jsk_pcl_ros::EnvironmentPlaneModeling::pub_debug_magnified_polygons_
ros::Publisher pub_debug_magnified_polygons_
Definition: environment_plane_modeling.h:287
jsk_pcl_ros::EnvironmentPlaneModeling::buildGridPlanes
virtual std::vector< GridPlane::Ptr > buildGridPlanes(pcl::PointCloud< pcl::PointNormal >::Ptr &cloud, std::vector< jsk_recognition_utils::ConvexPolygon::Ptr > convexes, std::set< int > &non_plane_indices)
make GridPlane from jsk_recognition_utils::ConvexPolygon and PointCloud
Definition: environment_plane_modeling_nodelet.cpp:527
jsk_pcl_ros::EnvironmentPlaneModeling::pub_debug_convex_point_cloud_
ros::Publisher pub_debug_convex_point_cloud_
Definition: environment_plane_modeling.h:288
jsk_pcl_ros::EnvironmentPlaneModeling::morphologicalFiltering
virtual std::vector< GridPlane::Ptr > morphologicalFiltering(std::vector< GridPlane::Ptr > &raw_grid_maps)
Definition: environment_plane_modeling_nodelet.cpp:478
jsk_pcl_ros::EnvironmentPlaneModeling::magnifyConvexes
virtual std::vector< jsk_recognition_utils::ConvexPolygon::Ptr > magnifyConvexes(std::vector< jsk_recognition_utils::ConvexPolygon::Ptr > &convexes)
Magnify jsk_recognition_utils::ConvexPolygons according to maginify_distance_ parameter.
Definition: environment_plane_modeling_nodelet.cpp:564
PCLIndicesMsg
pcl::PointIndices PCLIndicesMsg
cube
Cube cube(Eigen::Vector3f(1, 0, 0), Eigen::Quaternionf(0.108755, 0.088921, 0.108755, 0.984092), Eigen::Vector3f(0.3, 0.3, 0.3))
dump_depth_error.grid
float grid
Definition: dump_depth_error.py:8
jsk_pcl_ros::EnvironmentPlaneModeling::sync_
boost::shared_ptr< message_filters::Synchronizer< SyncPolicy > > sync_
Definition: environment_plane_modeling.h:279
geo_util.h
jsk_pcl_ros::EnvironmentPlaneModeling::latest_global_header_
std_msgs::Header latest_global_header_
Definition: environment_plane_modeling.h:301
NODELET_WARN
#define NODELET_WARN(...)
jsk_pcl_ros::EnvironmentPlaneModeling::sub_move_base_simple_goal_
ros::Subscriber sub_move_base_simple_goal_
Definition: environment_plane_modeling.h:286
attention_pose_set.pub
pub
Definition: attention_pose_set.py:8
jsk_pcl_ros::EnvironmentPlaneModeling::magnify_distance_
double magnify_distance_
Definition: environment_plane_modeling.h:305
jsk_pcl_ros::EnvironmentPlaneModeling::latest_leg_bounding_box_
jsk_recognition_msgs::BoundingBox::ConstPtr latest_leg_bounding_box_
Definition: environment_plane_modeling.h:298
jsk_pcl_ros::EnvironmentPlaneModeling::normal_threshold_
double normal_threshold_
Definition: environment_plane_modeling.h:307
jsk_pcl_ros::EnvironmentPlaneModeling::~EnvironmentPlaneModeling
virtual ~EnvironmentPlaneModeling()
Definition: environment_plane_modeling_nodelet.cpp:118
transform
template Halfspace< double > transform(const Halfspace< double > &a, const Transform3< double > &tf)
tf::StampedTransform
pcl::fromROSMsg
void fromROSMsg(const sensor_msgs::PointCloud2 &cloud, pcl::PointCloud< T > &pcl_cloud)
ros::Publisher::publish
void publish(const boost::shared_ptr< M > &message) const
jsk_pcl_ros::EnvironmentPlaneModeling::pub_debug_noeroded_grid_map_
ros::Publisher pub_debug_noeroded_grid_map_
Definition: environment_plane_modeling.h:290
jsk_pcl_ros::EnvironmentPlaneModeling::latest_grid_maps_
std::vector< GridPlane::Ptr > latest_grid_maps_
Definition: environment_plane_modeling.h:300
cloud
cloud
pose
pose
jsk_pcl_ros::EnvironmentPlaneModeling::resolution_
double resolution_
Definition: environment_plane_modeling.h:308
class_list_macros.h
jsk_pcl_ros::EnvironmentPlaneModeling::boundingBoxCallback
virtual void boundingBoxCallback(const jsk_recognition_msgs::BoundingBox::ConstPtr &box_array)
Definition: environment_plane_modeling_nodelet.cpp:247
attention_pose_set.box
box
Definition: attention_pose_set.py:14
jsk_pcl_ros::EnvironmentPlaneModeling::pub_debug_plane_coords_
ros::Publisher pub_debug_plane_coords_
Definition: environment_plane_modeling.h:291
jsk_pcl_ros::EnvironmentPlaneModeling::inputCallback
virtual void inputCallback(const sensor_msgs::PointCloud2::ConstPtr &cloud_msg, const sensor_msgs::PointCloud2::ConstPtr &full_cloud_msg, const jsk_recognition_msgs::PolygonArray::ConstPtr &polygon_msg, const jsk_recognition_msgs::ModelCoefficientsArray::ConstPtr &coefficients_msg, const jsk_recognition_msgs::ClusterPointIndices::ConstPtr &indices_msg)
main callback function
Definition: environment_plane_modeling_nodelet.cpp:254
jsk_pcl_ros::EnvironmentPlaneModeling::complete_footprint_region_
bool complete_footprint_region_
Definition: environment_plane_modeling.h:310
jsk_pcl_ros::EnvironmentPlaneModeling::lookupGroundPlaneForFootprint
virtual int lookupGroundPlaneForFootprint(const std::string &footprint_frame_id, const std_msgs::Header &header, const std::vector< GridPlane::Ptr > &grid_maps)
Definition: environment_plane_modeling_nodelet.cpp:397
jsk_pcl_ros::EnvironmentPlaneModeling::mutex_
boost::mutex mutex_
Definition: environment_plane_modeling.h:278
jsk_pcl_ros::EnvironmentPlaneModeling::publishGridMaps
virtual void publishGridMaps(ros::Publisher &pub, const std_msgs::Header &header, std::vector< GridPlane::Ptr > &grids)
Publish array of GridPlane::Ptr by using specified publisher.
Definition: environment_plane_modeling_nodelet.cpp:511
jsk_pcl_ros::EnvironmentPlaneModeling::sub_polygons_
message_filters::Subscriber< jsk_recognition_msgs::PolygonArray > sub_polygons_
Definition: environment_plane_modeling.h:283
jsk_pcl_ros
Definition: add_color_from_image.h:51
jsk_pcl_ros::EnvironmentPlaneModeling::printInputData
virtual void printInputData(const sensor_msgs::PointCloud2::ConstPtr &cloud_msg, const sensor_msgs::PointCloud2::ConstPtr &full_cloud_msg, const jsk_recognition_msgs::PolygonArray::ConstPtr &polygon_msg, const jsk_recognition_msgs::ModelCoefficientsArray::ConstPtr &coefficients_msg, const jsk_recognition_msgs::ClusterPointIndices::ConstPtr &indices_msg)
Definition: environment_plane_modeling_nodelet.cpp:142
_5
boost::arg< 5 > _5
grid_map.h
tf::transformTFToEigen
void transformTFToEigen(const tf::Transform &t, Eigen::Affine3f &eigen)
jsk_pcl_ros::EnvironmentPlaneModeling::completeFootprintRegion
virtual std::vector< GridPlane::Ptr > completeFootprintRegion(const std_msgs::Header &header, std::vector< GridPlane::Ptr > &grid_maps)
Definition: environment_plane_modeling_nodelet.cpp:442
_1
boost::arg< 1 > _1
d
d
jsk_pcl_ros::EnvironmentPlaneModeling::publishConvexPolygonsBoundaries
virtual void publishConvexPolygonsBoundaries(ros::Publisher &pub, const std_msgs::Header &header, std::vector< jsk_recognition_utils::ConvexPolygon::Ptr > &convexes)
Definition: environment_plane_modeling_nodelet.cpp:491
jsk_pcl_ros::EnvironmentPlaneModeling::sub_cloud_
message_filters::Subscriber< sensor_msgs::PointCloud2 > sub_cloud_
Definition: environment_plane_modeling.h:280
jsk_pcl_ros::EnvironmentPlaneModeling::erode_filter_size_
int erode_filter_size_
Definition: environment_plane_modeling.h:311
tf::poseEigenToMsg
void poseEigenToMsg(const Eigen::Affine3d &e, geometry_msgs::Pose &m)
jsk_pcl_ros::EnvironmentPlaneModeling::configCallback
virtual void configCallback(Config &config, uint32_t level)
Callback method of dynamic reconfigure.
Definition: environment_plane_modeling_nodelet.cpp:129
jsk_pcl_ros::EnvironmentPlaneModeling::morphological_filter_size_
int morphological_filter_size_
Definition: environment_plane_modeling.h:309
environment_plane_modeling.h
jsk_pcl_ros::EnvironmentPlaneModeling::pub_debug_raw_grid_map_
ros::Publisher pub_debug_raw_grid_map_
Definition: environment_plane_modeling.h:289
jsk_pcl_ros::EnvironmentPlaneModeling::pub_debug_magnified_plane_coords_
ros::Publisher pub_debug_magnified_plane_coords_
Definition: environment_plane_modeling.h:292
num
num
message_filters::Subscriber::subscribe
void subscribe()
NODELET_INFO
#define NODELET_INFO(...)
jsk_pcl_ros::EnvironmentPlaneModeling::srv_
boost::shared_ptr< dynamic_reconfigure::Server< Config > > srv_
Definition: environment_plane_modeling.h:296
PLUGINLIB_EXPORT_CLASS
PLUGINLIB_EXPORT_CLASS(jsk_pcl_ros::EnvironmentPlaneModeling, nodelet::Nodelet)
nodelet::Nodelet
jsk_pcl_ros::EnvironmentPlaneModeling::sub_coefficients_
message_filters::Subscriber< jsk_recognition_msgs::ModelCoefficientsArray > sub_coefficients_
Definition: environment_plane_modeling.h:284
jsk_pcl_ros::EnvironmentPlaneModeling::publishConvexPolygons
virtual void publishConvexPolygons(ros::Publisher &pub, const std_msgs::Header &header, std::vector< jsk_recognition_utils::ConvexPolygon::Ptr > &convexes)
Publish array of jsk_recognition_utils::ConvexPolygon::Ptr by using specified publisher.
Definition: environment_plane_modeling_nodelet.cpp:548
jsk_pcl_ros::EnvironmentPlaneModeling::moveBaseSimpleGoalCallback
virtual void moveBaseSimpleGoalCallback(const geometry_msgs::PoseStamped::ConstPtr &msg)
Definition: environment_plane_modeling_nodelet.cpp:195
dump_depth_error.f
f
Definition: dump_depth_error.py:39
_4
boost::arg< 4 > _4
cos
double cos()
coefficients
coefficients
pcl::toROSMsg
void toROSMsg(const pcl::PointCloud< T > &cloud, sensor_msgs::Image &msg)
jsk_recognition_utils::Cube
jsk_pcl_ros::EnvironmentPlaneModeling::footprint_plane_distance_threshold_
double footprint_plane_distance_threshold_
Definition: environment_plane_modeling.h:312
jsk_pcl_ros::EnvironmentPlaneModeling::distance_threshold_
double distance_threshold_
Definition: environment_plane_modeling.h:306
jsk_pcl_ros::EnvironmentPlaneModeling::footprint_frames_
std::vector< std::string > footprint_frames_
Definition: environment_plane_modeling.h:299
jsk_recognition_utils::TfListenerSingleton::getInstance
static tf::TransformListener * getInstance()
jsk_pcl_ros::EnvironmentPlaneModeling::pub_non_plane_indices_
ros::Publisher pub_non_plane_indices_
Definition: environment_plane_modeling.h:294
height
height
lookupTransformWithDuration
tf::StampedTransform lookupTransformWithDuration(tf::TransformListener *listener, const std::string &to_frame, const std::string &from_frame, const ros::Time &stamp, ros::Duration duration)
attention_pose_set.frame_id
frame_id
Definition: attention_pose_set.py:16
jsk_pcl_ros::EnvironmentPlaneModeling::pub_snapped_move_base_simple_goal_
ros::Publisher pub_snapped_move_base_simple_goal_
Definition: environment_plane_modeling.h:295
tf2::TransformException
jsk_pcl_ros::EnvironmentPlaneModeling::Config
EnvironmentPlaneModelingConfig Config
Definition: environment_plane_modeling.h:147
config
config
polygon_msg
jsk_recognition_msgs::PolygonArray::ConstPtr polygon_msg
ros::Duration
pose_with_covariance_sample.msg
msg
Definition: pose_with_covariance_sample.py:22
jsk_pcl_ros::EnvironmentPlaneModeling::convertToConvexPolygons
virtual std::vector< jsk_recognition_utils::ConvexPolygon::Ptr > convertToConvexPolygons(const pcl::PointCloud< pcl::PointNormal >::Ptr &cloud, const jsk_recognition_msgs::ClusterPointIndices::ConstPtr &indices_msg, const jsk_recognition_msgs::ModelCoefficientsArray::ConstPtr &coefficients_msg)
Definition: environment_plane_modeling_nodelet.cpp:580
jsk_pcl_ros::EnvironmentPlaneModeling::sub_leg_bbox_
ros::Subscriber sub_leg_bbox_
Definition: environment_plane_modeling.h:285
jsk_pcl_ros::EnvironmentPlaneModeling::onInit
virtual void onInit()
Definition: environment_plane_modeling_nodelet.cpp:54
jsk_pcl_ros::EnvironmentPlaneModeling::completeGridMapByBoundingBox
virtual GridPlane::Ptr completeGridMapByBoundingBox(const jsk_recognition_msgs::BoundingBox::ConstPtr &box, const std_msgs::Header &header, GridPlane::Ptr grid_map)
Definition: environment_plane_modeling_nodelet.cpp:413
pcl_conversions.h


jsk_pcl_ros
Author(s): Yohei Kakiuchi
autogenerated on Tue Jan 7 2025 04:05:44