38 #include <geometric_shapes/body_operations.h>
41 #include <rclcpp/clock.hpp>
42 #include <rclcpp/logger.hpp>
43 #include <rclcpp/time.hpp>
46 const static double EPSILON = 0.0001;
50 static const rclcpp::Logger LOGGER =
51 rclcpp::get_logger(
"moveit_collision_distance_field.collision_distance_field_types");
55 std::vector<CollisionSphere> css;
57 if (body->getType() == shapes::ShapeType::SPHERE)
64 bodies::BoundingCylinder cyl;
65 body->computeBoundingCylinder(cyl);
66 unsigned int num_points = ceil(cyl.length / (cyl.radius / 2.0));
67 double spacing = cyl.length / ((num_points * 1.0) - 1.0);
68 relative_transform = cyl.pose;
70 for (
unsigned int i = 1; i < num_points - 1; i++)
73 relative_transform *
Eigen::Vector3d(0, 0, (-cyl.length / 2.0) + i * spacing), cyl.radius);
82 const EigenSTL::vector_Vector3d& sphere_centers,
84 double tolerance,
bool subtract_radii,
double maximum_value,
85 bool stop_at_first_collision)
89 bool in_collision =
false;
90 for (
unsigned int i = 0; i < sphere_list.size(); ++i)
95 double dist = this->
getDistanceGradient(p.x(),
p.y(),
p.z(), grad.x(), grad.y(), grad.z(), in_bounds);
96 if (!in_bounds && grad.norm() > 0)
102 if (dist < maximum_value)
106 dist -= sphere_list[i].radius_;
108 if ((dist < 0) && (-dist >= tolerance))
113 dist = std::abs(dist);
117 if (sphere_list[i].radius_ - dist > tolerance)
136 if (stop_at_first_collision && in_collision)
145 const std::vector<CollisionSphere>& sphere_list,
146 const EigenSTL::vector_Vector3d& sphere_centers,
GradientInfo& gradient,
147 const CollisionType&
type,
double tolerance,
bool subtract_radii,
double maximum_value,
148 bool stop_at_first_collision)
152 bool in_collision =
false;
153 for (
unsigned int i = 0; i < sphere_list.size(); ++i)
158 double dist =
distance_field->getDistanceGradient(
p.x(),
p.y(),
p.z(), grad.x(), grad.y(), grad.z(), in_bounds);
159 if (!in_bounds && grad.norm() >
EPSILON)
161 RCLCPP_DEBUG(LOGGER,
"Collision sphere point is out of bounds %lf, %lf, %lf",
p.x(),
p.y(),
p.z());
165 if (dist < maximum_value)
169 dist -= sphere_list[i].radius_;
171 if ((dist < 0) && (-dist >= tolerance))
178 if (sphere_list[i].radius_ - dist > tolerance)
197 if (stop_at_first_collision && in_collision)
206 const std::vector<CollisionSphere>& sphere_list,
207 const EigenSTL::vector_Vector3d& sphere_centers,
double maximum_value,
210 for (
unsigned int i = 0; i < sphere_list.size(); ++i)
214 bool in_bounds =
true;
215 double dist =
distance_field->getDistanceGradient(
p.x(),
p.y(),
p.z(), grad.x(), grad.y(), grad.z(), in_bounds);
217 if (!in_bounds && grad.norm() > 0)
219 RCLCPP_DEBUG(LOGGER,
"Collision sphere point is out of bounds");
223 if ((maximum_value > dist) && (sphere_list[i].radius_ - dist > tolerance))
233 const std::vector<CollisionSphere>& sphere_list,
234 const EigenSTL::vector_Vector3d& sphere_centers,
double maximum_value,
235 double tolerance,
unsigned int num_coll, std::vector<unsigned int>& colls)
238 for (
unsigned int i = 0; i < sphere_list.size(); ++i)
242 bool in_bounds =
true;
243 double dist =
distance_field->getDistanceGradient(
p.x(),
p.y(),
p.z(), grad.x(), grad.y(), grad.z(), in_bounds);
244 if (!in_bounds && (grad.norm() > 0))
246 RCLCPP_DEBUG(LOGGER,
"Collision sphere point is out of bounds");
249 if (maximum_value > dist && (sphere_list[i].radius_ - dist > tolerance))
257 if (colls.size() >= num_coll)
264 return !colls.empty();
273 std::vector<shapes::ShapeConstPtr>
shapes;
274 EigenSTL::vector_Isometry3d poses(1, Eigen::Isometry3d::Identity());
281 const EigenSTL::vector_Isometry3d& poses,
double resolution,
double padding)
287 double resolution,
double padding)
290 for (
unsigned int i = 0; i <
shapes.size(); ++i)
298 std::vector<CollisionSphere> body_spheres;
299 EigenSTL::vector_Vector3d body_collision_points;
300 for (
unsigned int i = 0; i <
bodies_.getCount(); ++i)
302 body_spheres.clear();
303 body_collision_points.clear();
310 body_collision_points.end());
320 std::vector<bodies::BoundingSphere> bounding_spheres(
bodies_.getCount());
321 for (
unsigned int i = 0; i <
bodies_.getCount(); ++i)
323 bodies_.getBody(i)->computeBoundingSphere(bounding_spheres[i]);
327 RCLCPP_DEBUG(LOGGER,
"BodyDecomposition generated %zu collision spheres out of %zu shapes",
collision_spheres_.size(),
337 : body_decomposition_(body_decomposition)
343 const Eigen::Isometry3d& trans)
344 : body_decomposition_(body_decomposition)
350 : body_decomposition_()
352 int num_nodes = octree->getNumLeafNodes();
354 for (octomap::OcTree::tree_iterator tree_iter = octree->begin_tree(); tree_iter != octree->end_tree(); ++tree_iter)
375 : body_decomposition_(body_decomposition)
403 const PosedBodySphereDecompositionConstPtr& p2)
407 double p1_radius = p1->getBoundingSphereRadius();
408 double p2_radius = p2->getBoundingSphereRadius();
410 double dist = (p1_sphere_center - p2_sphere_center).squaredNorm();
411 return dist < (p1_radius + p2_radius);
415 const std::string& ns,
const rclcpp::Duration& dur,
416 const std::vector<PosedBodySphereDecompositionPtr>& posed_decompositions,
417 visualization_msgs::msg::MarkerArray& arr)
419 unsigned int count = 0;
420 rclcpp::Clock ros_clock;
421 for (
const auto& posed_decomposition : posed_decompositions)
423 if (posed_decomposition)
425 for (
unsigned int j = 0; j < posed_decomposition->getCollisionSpheres().size(); ++j)
427 visualization_msgs::msg::Marker sphere;
428 sphere.type = visualization_msgs::msg::Marker::SPHERE;
429 sphere.header.stamp = ros_clock.now();
433 sphere.lifetime = dur;
434 sphere.color = color;
435 sphere.scale.x = sphere.scale.y = sphere.scale.z = posed_decomposition->getCollisionSpheres()[j].radius_ * 2.0;
436 sphere.pose.position.x = posed_decomposition->getSphereCenters()[j].x();
437 sphere.pose.position.y = posed_decomposition->getSphereCenters()[j].y();
438 sphere.pose.position.z = posed_decomposition->getSphereCenters()[j].z();
439 arr.markers.push_back(sphere);
446 const std::vector<PosedBodySphereDecompositionPtr>& posed_decompositions,
447 const std::vector<PosedBodySphereDecompositionVectorPtr>& posed_vector_decompositions,
448 const std::vector<GradientInfo>& gradients, visualization_msgs::msg::MarkerArray& arr)
450 rclcpp::Clock ros_clock;
451 if (gradients.size() != posed_decompositions.size() + posed_vector_decompositions.size())
453 RCLCPP_WARN(LOGGER,
"Size mismatch between gradients %u and decompositions %u", (
unsigned int)gradients.size(),
454 (
unsigned int)(posed_decompositions.size() + posed_vector_decompositions.size()));
457 for (
unsigned int i = 0; i < gradients.size(); ++i)
459 for (
unsigned int j = 0; j < gradients[i].distances.size(); ++j)
461 visualization_msgs::msg::Marker arrow_mark;
462 arrow_mark.header.frame_id =
frame_id;
463 arrow_mark.header.stamp = rclcpp::Clock(RCL_ROS_TIME).now();
466 arrow_mark.ns =
"self_coll_gradients";
472 arrow_mark.id = i * 1000 + j;
476 if (gradients[i].distances[j] > 0.0 && gradients[i].distances[j] != DBL_MAX)
478 if (gradients[i].gradients[j].norm() > 0.0)
480 xscale = gradients[i].gradients[j].x() / gradients[i].gradients[j].norm();
481 yscale = gradients[i].gradients[j].y() / gradients[i].gradients[j].norm();
482 zscale = gradients[i].gradients[j].z() / gradients[i].gradients[j].norm();
486 RCLCPP_DEBUG(LOGGER,
"Negative length for %u %d %lf", i, arrow_mark.id, gradients[i].gradients[j].norm());
491 RCLCPP_DEBUG(LOGGER,
"Negative dist %lf for %u %d", gradients[i].distances[j], i, arrow_mark.id);
493 arrow_mark.points.resize(2);
494 if (i < posed_decompositions.size())
496 arrow_mark.points[1].x = posed_decompositions[i]->getSphereCenters()[j].x();
497 arrow_mark.points[1].y = posed_decompositions[i]->getSphereCenters()[j].y();
498 arrow_mark.points[1].z = posed_decompositions[i]->getSphereCenters()[j].z();
502 arrow_mark.points[1].x =
503 posed_vector_decompositions[i - posed_decompositions.size()]->getSphereCenters()[j].x();
504 arrow_mark.points[1].y =
505 posed_vector_decompositions[i - posed_decompositions.size()]->getSphereCenters()[j].y();
506 arrow_mark.points[1].z =
507 posed_vector_decompositions[i - posed_decompositions.size()]->getSphereCenters()[j].z();
509 arrow_mark.points[0] = arrow_mark.points[1];
510 arrow_mark.points[0].x -= xscale * gradients[i].distances[j];
511 arrow_mark.points[0].y -= yscale * gradients[i].distances[j];
512 arrow_mark.points[0].z -= zscale * gradients[i].distances[j];
513 arrow_mark.scale.x = 0.01;
514 arrow_mark.scale.y = 0.03;
515 arrow_mark.color.a = 1.0;
516 if (gradients[i].types[j] ==
SELF)
518 arrow_mark.color.r = 1.0;
519 arrow_mark.color.g = 0.2;
520 arrow_mark.color.b = .5;
522 else if (gradients[i].types[j] ==
INTRA)
524 arrow_mark.color.r = .2;
525 arrow_mark.color.g = 1.0;
526 arrow_mark.color.b = .5;
530 arrow_mark.color.r = .2;
531 arrow_mark.color.g = .5;
532 arrow_mark.color.b = 1.0;
534 else if (gradients[i].types[j] ==
NONE)
536 arrow_mark.color.r = 1.0;
537 arrow_mark.color.g = .2;
538 arrow_mark.color.b = 1.0;
540 arr.markers.push_back(arrow_mark);
546 const std::vector<PosedBodySphereDecompositionPtr>& posed_decompositions,
547 const std::vector<PosedBodySphereDecompositionVectorPtr>& posed_vector_decompositions,
548 const std::vector<GradientInfo>& gradients, visualization_msgs::msg::MarkerArray& arr)
550 rclcpp::Clock ros_clock;
551 if (gradients.size() != posed_decompositions.size() + posed_vector_decompositions.size())
553 RCLCPP_WARN(LOGGER,
"Size mismatch between gradients %zu and decompositions %zu", gradients.size(),
554 posed_decompositions.size() + posed_vector_decompositions.size());
557 for (
unsigned int i = 0; i < gradients.size(); ++i)
559 for (
unsigned int j = 0; j < gradients[i].types.size(); ++j)
561 visualization_msgs::msg::Marker sphere_mark;
562 sphere_mark.type = visualization_msgs::msg::Marker::SPHERE;
563 sphere_mark.header.frame_id =
frame_id;
564 sphere_mark.header.stamp = rclcpp::Clock(RCL_ROS_TIME).now();
567 sphere_mark.ns =
"distance_collisions";
573 sphere_mark.id = i * 1000 + j;
574 if (i < posed_decompositions.size())
576 sphere_mark.scale.x = sphere_mark.scale.y = sphere_mark.scale.z =
577 posed_decompositions[i]->getCollisionSpheres()[j].radius_ * 2.0;
578 sphere_mark.pose.position.x = posed_decompositions[i]->getSphereCenters()[j].x();
579 sphere_mark.pose.position.y = posed_decompositions[i]->getSphereCenters()[j].y();
580 sphere_mark.pose.position.z = posed_decompositions[i]->getSphereCenters()[j].z();
584 sphere_mark.scale.x = sphere_mark.scale.y = sphere_mark.scale.z =
585 posed_vector_decompositions[i - posed_decompositions.size()]->getCollisionSpheres()[j].radius_ * 2.0;
586 sphere_mark.pose.position.x =
587 posed_vector_decompositions[i - posed_decompositions.size()]->getSphereCenters()[j].x();
588 sphere_mark.pose.position.y =
589 posed_vector_decompositions[i - posed_decompositions.size()]->getSphereCenters()[j].y();
590 sphere_mark.pose.position.z =
591 posed_vector_decompositions[i - posed_decompositions.size()]->getSphereCenters()[j].z();
593 sphere_mark.pose.orientation.w = 1.0;
594 sphere_mark.color.a = 1.0;
595 if (gradients[i].types[j] ==
SELF)
597 sphere_mark.color.r = 1.0;
598 sphere_mark.color.g = 0.2;
599 sphere_mark.color.b = .5;
601 else if (gradients[i].types[j] ==
INTRA)
603 sphere_mark.color.r = .2;
604 sphere_mark.color.g = 1.0;
605 sphere_mark.color.b = .5;
609 sphere_mark.color.r = .2;
610 sphere_mark.color.g = .5;
611 sphere_mark.color.b = 1.0;
615 sphere_mark.color.r = 1.0;
616 sphere_mark.color.g = .2;
617 sphere_mark.color.b = 1.0;
619 arr.markers.push_back(sphere_mark);
625 const rclcpp::Logger collision_detection::PosedBodySphereDecompositionVector::LOGGER = collision_detection::LOGGER;
std::vector< CollisionSphere > collision_spheres_
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)
bodies::BoundingSphere relative_bounding_sphere_
Eigen::Isometry3d relative_cylinder_pose_
EigenSTL::vector_Vector3d relative_collision_points_
bodies::BodyVector bodies_
std::vector< double > sphere_radii_
static const rclcpp::Logger LOGGER
EIGEN_MAKE_ALIGNED_OPERATOR_NEW PosedBodyPointDecomposition(const BodyDecompositionConstPtr &body_decomposition)
void updatePose(const Eigen::Isometry3d &linkTransform)
EigenSTL::vector_Vector3d posed_collision_points_
BodyDecompositionConstPtr body_decomposition_
EIGEN_MAKE_ALIGNED_OPERATOR_NEW PosedBodySphereDecomposition(const BodyDecompositionConstPtr &body_decomposition)
Eigen::Vector3d posed_bounding_sphere_center_
EigenSTL::vector_Vector3d posed_collision_points_
BodyDecompositionConstPtr body_decomposition_
void updatePose(const Eigen::Isometry3d &linkTransform)
EigenSTL::vector_Vector3d sphere_centers_
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...
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)
DistanceField is an abstract base class for computing distances from sets of 3D obstacle points....
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)
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.
void findInternalPointsConvex(const bodies::Body &body, double resolution, EigenSTL::vector_Vector3d &points)
Find all points on a regular grid that are internal to the body, assuming the body is a convex shape....
Vec3fX< details::Vec3Data< double > > Vector3d
EIGEN_MAKE_ALIGNED_OPERATOR_NEW double closest_distance
EigenSTL::vector_Vector3d gradients
std::vector< double > distances
std::vector< CollisionType > types