moveit2
The MoveIt Motion Planning Framework for ROS 2.
collision_distance_field_types.h
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2010, Willow Garage, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of the Willow Garage nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *********************************************************************/
34 
35 /* Author: E. Gil Jones */
36 
37 #pragma once
38 
39 #include <vector>
40 #include <string>
41 #include <algorithm>
42 #include <memory>
43 #include <float.h>
44 
45 #include <geometric_shapes/shapes.h>
46 #include <geometric_shapes/bodies.h>
47 #include <octomap/OcTree.h>
48 
52 #include <visualization_msgs/msg/marker_array.hpp>
53 #include <rclcpp/duration.hpp>
54 #include <rclcpp/logging.hpp>
55 #include <rclcpp/clock.hpp>
56 #include <rclcpp/rclcpp.hpp>
57 #include <rclcpp/time.hpp>
58 #include <rclcpp/utilities.hpp>
59 
60 namespace collision_detection
61 {
63 {
64  NONE = 0,
65  SELF = 1,
66  INTRA = 2,
68 };
69 
71 {
72  CollisionSphere(const Eigen::Vector3d& rel, double radius)
73  {
74  relative_vec_ = rel;
75  radius_ = radius;
76  }
78 
80  double radius_;
81 };
82 
84 {
86  {
87  }
88 
90 
92  bool collision;
93  EigenSTL::vector_Vector3d sphere_locations;
94  std::vector<double> distances;
95  EigenSTL::vector_Vector3d gradients;
96  std::vector<CollisionType> types;
97  std::vector<double> sphere_radii;
98  std::string joint_name;
99 
100  void clear()
101  {
102  closest_distance = DBL_MAX;
103  collision = false;
104  sphere_locations.clear();
105  distances.clear();
106  gradients.clear();
107  sphere_radii.clear();
108  joint_name.clear();
109  }
110 };
111 
112 // Defines ConstPtr, WeakPtr... etc
119 
121 {
122 public:
124 
125  PosedDistanceField(const Eigen::Vector3d& size, const Eigen::Vector3d& origin, double resolution, double max_distance,
126  bool propagate_negative_distances = false)
127  : distance_field::PropagationDistanceField(size.x(), size.y(), size.z(), resolution, origin.x(), origin.y(),
128  origin.z(), max_distance, propagate_negative_distances)
129  , pose_(Eigen::Isometry3d::Identity())
130  {
131  }
132 
133  void updatePose(const Eigen::Isometry3d& transform)
134  {
135  pose_ = transform;
136  }
137 
138  const Eigen::Isometry3d& getPose() const
139  {
140  return pose_;
141  }
142 
162  double getDistanceGradient(double x, double y, double z, double& gradient_x, double& gradient_y, double& gradient_z,
163  bool& in_bounds) const
164  {
165  // Transpose of a rotation matrix equals its inverse, but computationally cheaper
166  Eigen::Vector3d rel_pos = pose_.linear().transpose() * Eigen::Vector3d(x, y, z);
167  double gx, gy, gz;
168  double res = distance_field::PropagationDistanceField::getDistanceGradient(rel_pos.x(), rel_pos.y(), rel_pos.z(),
169  gx, gy, gz, in_bounds);
170  Eigen::Vector3d grad = pose_ * Eigen::Vector3d(gx, gy, gz);
171  gradient_x = grad.x();
172  gradient_y = grad.y();
173  gradient_z = grad.z();
174  return res;
175  }
176 
177  /*
178  * @brief determines a set of gradients of the given collision spheres in the
179  * distance field
180  * @param sphere_list vector of the spheres that approximate a links geometry
181  * @param sphere_centers vector of points which indicate the center of each
182  * sphere in sphere_list
183  * @param gradient output argument to be populated with the resulting gradient
184  * calculation
185  * @param tolerance
186  * @param subtract_radii distance to the sphere centers will be computed by
187  * subtracting the sphere radius from the nearest point
188  * @param maximum_value
189  * @param stop_at_first_collision when true the computation is terminated when
190  * the first collision is found
191  */
192  bool getCollisionSphereGradients(const std::vector<CollisionSphere>& sphere_list,
193  const EigenSTL::vector_Vector3d& sphere_centers, GradientInfo& gradient,
194  const CollisionType& type, double tolerance, bool subtract_radii,
195  double maximum_value, bool stop_at_first_collision);
196 
197 protected:
198  Eigen::Isometry3d pose_;
199 };
200 
201 // determines set of collision spheres given a posed body; this is BAD!
202 // Allocation errors will happen; change this function so it does not return
203 // that vector by value
204 std::vector<CollisionSphere> determineCollisionSpheres(const bodies::Body* body, Eigen::Isometry3d& relativeTransform);
205 
206 // determines a set of gradients of the given collision spheres in the distance
207 // field
209  const std::vector<CollisionSphere>& sphere_list,
210  const EigenSTL::vector_Vector3d& sphere_centers, GradientInfo& gradient,
211  const CollisionType& type, double tolerance, bool subtract_radii, double maximum_value,
212  bool stop_at_first_collision);
213 
215  const std::vector<CollisionSphere>& sphere_list,
216  const EigenSTL::vector_Vector3d& sphere_centers, double maximum_value,
217  double tolerance);
218 
220  const std::vector<CollisionSphere>& sphere_list,
221  const EigenSTL::vector_Vector3d& sphere_centers, double maximum_value,
222  double tolerance, unsigned int num_coll, std::vector<unsigned int>& colls);
223 
224 // forward declaration required for friending apparently
225 class BodyDecompositionVector;
226 
228 {
230 
231 public:
233 
234  BodyDecomposition(const shapes::ShapeConstPtr& shape, double resolution, double padding = 0.01);
235 
236  BodyDecomposition(const std::vector<shapes::ShapeConstPtr>& shapes, const EigenSTL::vector_Isometry3d& poses,
237  double resolution, double padding);
238 
240 
241  Eigen::Isometry3d relative_cylinder_pose_;
242 
243  void replaceCollisionSpheres(const std::vector<CollisionSphere>& new_collision_spheres,
244  const Eigen::Isometry3d& new_relative_cylinder_pose)
245  {
246  // std::cerr << "Replacing " << collision_spheres_.size() << " with " <<
247  // new_collision_spheres.size() << '\n';
248  collision_spheres_ = new_collision_spheres;
249  relative_cylinder_pose_ = new_relative_cylinder_pose;
250  }
251 
252  const std::vector<CollisionSphere>& getCollisionSpheres() const
253  {
254  return collision_spheres_;
255  }
256 
257  const std::vector<double>& getSphereRadii() const
258  {
259  return sphere_radii_;
260  }
261 
262  const EigenSTL::vector_Vector3d& getCollisionPoints() const
263  {
265  }
266 
267  const bodies::Body* getBody(unsigned int i) const
268  {
269  return bodies_.getBody(i);
270  }
271 
272  unsigned int getBodiesCount()
273  {
274  return bodies_.getCount();
275  }
276 
277  Eigen::Isometry3d getRelativeCylinderPose() const
278  {
280  }
281 
282  const bodies::BoundingSphere& getRelativeBoundingSphere() const
283  {
285  }
286 
287 protected:
288  void init(const std::vector<shapes::ShapeConstPtr>& shapes, const EigenSTL::vector_Isometry3d& poses,
289  double resolution, double padding);
290 
291 protected:
292  bodies::BodyVector bodies_;
293 
294  bodies::BoundingSphere relative_bounding_sphere_;
295  std::vector<double> sphere_radii_;
296  std::vector<CollisionSphere> collision_spheres_;
297  EigenSTL::vector_Vector3d relative_collision_points_;
298 };
299 
301 {
302 public:
304 
305  PosedBodySphereDecomposition(const BodyDecompositionConstPtr& body_decomposition);
306 
307  const std::vector<CollisionSphere>& getCollisionSpheres() const
308  {
309  return body_decomposition_->getCollisionSpheres();
310  }
311 
312  const EigenSTL::vector_Vector3d& getSphereCenters() const
313  {
314  return sphere_centers_;
315  }
316 
317  const EigenSTL::vector_Vector3d& getCollisionPoints() const
318  {
320  }
321 
322  const std::vector<double>& getSphereRadii() const
323  {
324  return body_decomposition_->getSphereRadii();
325  }
327  {
329  }
330 
331  double getBoundingSphereRadius() const
332  {
333  return body_decomposition_->getRelativeBoundingSphere().radius;
334  }
335 
336  // assumed to be in reference frame, updates the pose of the body,
337  // the collision spheres, and the posed collision points
338  void updatePose(const Eigen::Isometry3d& linkTransform);
339 
340 protected:
341  BodyDecompositionConstPtr body_decomposition_;
343  EigenSTL::vector_Vector3d posed_collision_points_;
344  EigenSTL::vector_Vector3d sphere_centers_;
345 };
346 
348 {
349 public:
351 
352  PosedBodyPointDecomposition(const BodyDecompositionConstPtr& body_decomposition);
353 
354  PosedBodyPointDecomposition(const BodyDecompositionConstPtr& body_decomposition, const Eigen::Isometry3d& pose);
355 
356  PosedBodyPointDecomposition(const std::shared_ptr<const octomap::OcTree>& octree);
357 
358  const EigenSTL::vector_Vector3d& getCollisionPoints() const
359  {
361  }
362  // the collision spheres, and the posed collision points
363  void updatePose(const Eigen::Isometry3d& linkTransform);
364 
365 protected:
366  BodyDecompositionConstPtr body_decomposition_;
367  EigenSTL::vector_Vector3d posed_collision_points_;
368 };
369 
371 {
372 public:
374 
376  {
377  }
378 
379  const std::vector<CollisionSphere>& getCollisionSpheres() const
380  {
381  return collision_spheres_;
382  }
383 
384  const EigenSTL::vector_Vector3d& getSphereCenters() const
385  {
386  return posed_collision_spheres_;
387  }
388 
389  const std::vector<double>& getSphereRadii() const
390  {
391  return sphere_radii_;
392  }
393 
394  void addToVector(PosedBodySphereDecompositionPtr& bd)
395  {
396  sphere_index_map_[decomp_vector_.size()] = collision_spheres_.size();
397  decomp_vector_.push_back(bd);
398  collision_spheres_.insert(collision_spheres_.end(), bd->getCollisionSpheres().begin(),
399  bd->getCollisionSpheres().end());
400  posed_collision_spheres_.insert(posed_collision_spheres_.end(), bd->getSphereCenters().begin(),
401  bd->getSphereCenters().end());
402  sphere_radii_.insert(sphere_radii_.end(), bd->getSphereRadii().begin(), bd->getSphereRadii().end());
403  }
404 
405  unsigned int getSize() const
406  {
407  return decomp_vector_.size();
408  }
409 
410  PosedBodySphereDecompositionConstPtr getPosedBodySphereDecomposition(unsigned int i) const
411  {
412  if (i >= decomp_vector_.size())
413  {
414  RCLCPP_INFO(LOGGER, "No body decomposition");
415  return empty_ptr_;
416  }
417  return decomp_vector_[i];
418  }
419 
420  void updatePose(unsigned int ind, const Eigen::Isometry3d& pose)
421  {
422  if (ind >= decomp_vector_.size())
423  {
424  RCLCPP_WARN(LOGGER, "Can't update pose");
425  return;
426  }
427  decomp_vector_[ind]->updatePose(pose);
428  for (unsigned int i = 0; i < decomp_vector_[ind]->getSphereCenters().size(); ++i)
429  {
430  posed_collision_spheres_[sphere_index_map_[ind] + i] = decomp_vector_[ind]->getSphereCenters()[i];
431  }
432  }
433 
434 private:
435  static const rclcpp::Logger LOGGER;
436  PosedBodySphereDecompositionConstPtr empty_ptr_;
437  std::vector<PosedBodySphereDecompositionPtr> decomp_vector_;
438  std::vector<CollisionSphere> collision_spheres_;
439  EigenSTL::vector_Vector3d posed_collision_spheres_;
440  std::vector<double> sphere_radii_;
441  std::map<unsigned int, unsigned int> sphere_index_map_;
442 };
443 
445 {
446 public:
448 
450  {
451  }
452 
453  EigenSTL::vector_Vector3d getCollisionPoints() const
454  {
455  EigenSTL::vector_Vector3d ret_points;
456  for (const PosedBodyPointDecompositionPtr& decomp : decomp_vector_)
457  {
458  ret_points.insert(ret_points.end(), decomp->getCollisionPoints().begin(), decomp->getCollisionPoints().end());
459  }
460  return ret_points;
461  }
462 
463  void addToVector(PosedBodyPointDecompositionPtr& bd)
464  {
465  decomp_vector_.push_back(bd);
466  }
467 
468  unsigned int getSize() const
469  {
470  return decomp_vector_.size();
471  }
472 
473  PosedBodyPointDecompositionConstPtr getPosedBodyDecomposition(unsigned int i) const
474  {
475  if (i >= decomp_vector_.size())
476  {
477  RCLCPP_INFO(LOGGER, "No body decomposition");
478  return empty_ptr_;
479  }
480  return decomp_vector_[i];
481  }
482 
483  void updatePose(unsigned int ind, const Eigen::Isometry3d& pose)
484  {
485  if (ind < decomp_vector_.size())
486  {
487  decomp_vector_[ind]->updatePose(pose);
488  }
489  else
490  {
491  RCLCPP_WARN(LOGGER, "Can't update pose");
492  return;
493  }
494  }
495 
496 protected:
497  static const rclcpp::Logger LOGGER;
498 
499 private:
500  PosedBodyPointDecompositionPtr empty_ptr_;
501  std::vector<PosedBodyPointDecompositionPtr> decomp_vector_;
502 };
503 
505 {
507 
508  std::string link_name;
509  std::string attached_object_name;
510  double proximity;
511  unsigned int sphere_index;
512  unsigned int att_index;
515 };
516 
517 bool doBoundingSpheresIntersect(const PosedBodySphereDecompositionConstPtr& p1,
518  const PosedBodySphereDecompositionConstPtr& p2);
519 
520 void getCollisionSphereMarkers(const std_msgs::msg::ColorRGBA& color, const std::string& frame_id,
521  const std::string& ns, const rclcpp::Duration& dur,
522  const std::vector<PosedBodySphereDecompositionPtr>& posed_decompositions,
523  visualization_msgs::msg::MarkerArray& arr);
524 
525 void getProximityGradientMarkers(const std::string& frame_id, const std::string& ns, const rclcpp::Duration& dur,
526  const std::vector<PosedBodySphereDecompositionPtr>& posed_decompositions,
527  const std::vector<PosedBodySphereDecompositionVectorPtr>& posed_vector_decompositions,
528  const std::vector<GradientInfo>& gradients, visualization_msgs::msg::MarkerArray& arr);
529 
530 void getCollisionMarkers(const std::string& frame_id, const std::string& ns, const rclcpp::Duration& dur,
531  const std::vector<PosedBodySphereDecompositionPtr>& posed_decompositions,
532  const std::vector<PosedBodySphereDecompositionVectorPtr>& posed_vector_decompositions,
533  const std::vector<GradientInfo>& gradients, visualization_msgs::msg::MarkerArray& arr);
534 } // namespace collision_detection
ROS/KDL based interface for the inverse kinematics of the PR2 arm.
const std::vector< double > & getSphereRadii() const
EIGEN_MAKE_ALIGNED_OPERATOR_NEW BodyDecomposition(const shapes::ShapeConstPtr &shape, double resolution, double padding=0.01)
void init(const std::vector< shapes::ShapeConstPtr > &shapes, const EigenSTL::vector_Isometry3d &poses, double resolution, double padding)
const EigenSTL::vector_Vector3d & getCollisionPoints() const
const bodies::Body * getBody(unsigned int i) const
const std::vector< CollisionSphere > & getCollisionSpheres() const
void replaceCollisionSpheres(const std::vector< CollisionSphere > &new_collision_spheres, const Eigen::Isometry3d &new_relative_cylinder_pose)
const bodies::BoundingSphere & getRelativeBoundingSphere() const
PosedBodyPointDecompositionConstPtr getPosedBodyDecomposition(unsigned int i) const
void updatePose(unsigned int ind, const Eigen::Isometry3d &pose)
const EigenSTL::vector_Vector3d & getCollisionPoints() const
EIGEN_MAKE_ALIGNED_OPERATOR_NEW PosedBodyPointDecomposition(const BodyDecompositionConstPtr &body_decomposition)
void updatePose(const Eigen::Isometry3d &linkTransform)
const std::vector< CollisionSphere > & getCollisionSpheres() const
void updatePose(unsigned int ind, const Eigen::Isometry3d &pose)
PosedBodySphereDecompositionConstPtr getPosedBodySphereDecomposition(unsigned int i) const
const std::vector< CollisionSphere > & getCollisionSpheres() const
EIGEN_MAKE_ALIGNED_OPERATOR_NEW PosedBodySphereDecomposition(const BodyDecompositionConstPtr &body_decomposition)
const EigenSTL::vector_Vector3d & getCollisionPoints() const
void updatePose(const Eigen::Isometry3d &linkTransform)
const EigenSTL::vector_Vector3d & getSphereCenters() const
double getDistanceGradient(double x, double y, double z, double &gradient_x, double &gradient_y, double &gradient_z, bool &in_bounds) const
Gets not only the distance to the nearest cell but the gradient direction. The point defined by the x...
void updatePose(const Eigen::Isometry3d &transform)
bool getCollisionSphereGradients(const std::vector< CollisionSphere > &sphere_list, const EigenSTL::vector_Vector3d &sphere_centers, GradientInfo &gradient, const CollisionType &type, double tolerance, bool subtract_radii, double maximum_value, bool stop_at_first_collision)
EIGEN_MAKE_ALIGNED_OPERATOR_NEW PosedDistanceField(const Eigen::Vector3d &size, const Eigen::Vector3d &origin, double resolution, double max_distance, bool propagate_negative_distances=false)
DistanceField is an abstract base class for computing distances from sets of 3D obstacle points....
double getDistanceGradient(double x, double y, double z, double &gradient_x, double &gradient_y, double &gradient_z, bool &in_bounds) const
Gets not only the distance to the nearest cell but the gradient direction. The gradient is computed a...
A DistanceField implementation that uses a vector propagation method. Distances propagate outward fro...
PropagationDistanceField(double size_x, double size_y, double size_z, double resolution, double origin_x, double origin_y, double origin_z, double max_distance, bool propagate_negative_distances=false)
Constructor that initializes entire distance field to empty - all cells will be assigned maximum dist...
void getProximityGradientMarkers(const std::string &frame_id, const std::string &ns, const rclcpp::Duration &dur, const std::vector< PosedBodySphereDecompositionPtr > &posed_decompositions, const std::vector< PosedBodySphereDecompositionVectorPtr > &posed_vector_decompositions, const std::vector< GradientInfo > &gradients, visualization_msgs::msg::MarkerArray &arr)
std::vector< CollisionSphere > determineCollisionSpheres(const bodies::Body *body, Eigen::Isometry3d &relativeTransform)
void getCollisionMarkers(const std::string &frame_id, const std::string &ns, const rclcpp::Duration &dur, const std::vector< PosedBodySphereDecompositionPtr > &posed_decompositions, const std::vector< PosedBodySphereDecompositionVectorPtr > &posed_vector_decompositions, const std::vector< GradientInfo > &gradients, visualization_msgs::msg::MarkerArray &arr)
void getCollisionSphereMarkers(const std_msgs::msg::ColorRGBA &color, const std::string &frame_id, const std::string &ns, const rclcpp::Duration &dur, const std::vector< PosedBodySphereDecompositionPtr > &posed_decompositions, visualization_msgs::msg::MarkerArray &arr)
bool getCollisionSphereCollision(const distance_field::DistanceField *distance_field, const std::vector< CollisionSphere > &sphere_list, const EigenSTL::vector_Vector3d &sphere_centers, double maximum_value, double tolerance)
MOVEIT_CLASS_FORWARD(AllowedCollisionMatrix)
bool doBoundingSpheresIntersect(const PosedBodySphereDecompositionConstPtr &p1, const PosedBodySphereDecompositionConstPtr &p2)
bool getCollisionSphereGradients(const distance_field::DistanceField *distance_field, const std::vector< CollisionSphere > &sphere_list, const EigenSTL::vector_Vector3d &sphere_centers, GradientInfo &gradient, const CollisionType &type, double tolerance, bool subtract_radii, double maximum_value, bool stop_at_first_collision)
Namespace for holding classes that generate distance fields.
Vec3fX< details::Vec3Data< double > > Vector3d
Definition: fcl_compat.h:89
frame_id
Definition: pick.py:63
x
Definition: pick.py:64
y
Definition: pick.py:65
z
Definition: pick.py:66
Definition: world.h:49
CollisionSphere(const Eigen::Vector3d &rel, double radius)
EIGEN_MAKE_ALIGNED_OPERATOR_NEW Eigen::Vector3d relative_vec_
EIGEN_MAKE_ALIGNED_OPERATOR_NEW double closest_distance
EIGEN_MAKE_ALIGNED_OPERATOR_NEW std::string link_name