moveit2
The MoveIt Motion Planning Framework for ROS 2.
collision_env_distance_field.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2012, 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 
38 #include <rclcpp/clock.hpp>
39 #include <rclcpp/duration.hpp>
40 #include <rclcpp/logger.hpp>
41 #include <rclcpp/logging.hpp>
42 #include <rclcpp/time.hpp>
43 #include <tf2_eigen/tf2_eigen.hpp>
48 #include <functional>
49 #include <memory>
50 #include <utility>
51 #include <moveit/utils/logger.hpp>
52 
53 namespace collision_detection
54 {
55 const double EPSILON = 0.001f;
56 
58 
60  const moveit::core::RobotModelConstPtr& robot_model,
61  const std::map<std::string, std::vector<CollisionSphere>>& link_body_decompositions, double size_x, double size_y,
62  double size_z, const Eigen::Vector3d& origin, bool use_signed_distance_field, double resolution,
63  double collision_tolerance, double max_propogation_distance, double /*padding*/, double /*scale*/)
64  : CollisionEnv(robot_model), logger_(moveit::getLogger("collision_robot_distance_field"))
65 {
66  initialize(link_body_decompositions, Eigen::Vector3d(size_x, size_y, size_z), origin, use_signed_distance_field,
67  resolution, collision_tolerance, max_propogation_distance);
68 
69  setPadding(0.0);
70 
72 
73  // request notifications about changes to world
74  observer_handle_ = getWorld()->addObserver(
75  [this](const World::ObjectConstPtr& object, World::Action action) { return notifyObjectChange(object, action); });
76 }
77 
79  const moveit::core::RobotModelConstPtr& robot_model, const WorldPtr& world,
80  const std::map<std::string, std::vector<CollisionSphere>>& link_body_decompositions, double size_x, double size_y,
81  double size_z, const Eigen::Vector3d& origin, bool use_signed_distance_field, double resolution,
82  double collision_tolerance, double max_propogation_distance, double padding, double scale)
83  : CollisionEnv(robot_model, world, padding, scale), logger_(moveit::getLogger("collision_robot_distance_field"))
84 {
85  initialize(link_body_decompositions, Eigen::Vector3d(size_x, size_y, size_z), origin, use_signed_distance_field,
86  resolution, collision_tolerance, max_propogation_distance);
87 
89 
90  // request notifications about changes to world
91  observer_handle_ = getWorld()->addObserver(
92  [this](const World::ObjectConstPtr& object, World::Action action) { return notifyObjectChange(object, action); });
93 
94  getWorld()->notifyObserverAllObjects(observer_handle_, World::CREATE);
95 }
96 
98  : CollisionEnv(other, world), logger_(other.logger_)
99 {
100  size_ = other.size_;
101  origin_ = other.origin_;
102 
104  resolution_ = other.resolution_;
112  planning_scene_ = std::make_shared<planning_scene::PlanningScene>(robot_model_);
113 
114  // request notifications about changes to world
115  observer_handle_ = getWorld()->addObserver(
116  [this](const World::ObjectConstPtr& object, World::Action action) { return notifyObjectChange(object, action); });
117  getWorld()->notifyObserverAllObjects(observer_handle_, World::CREATE);
118 }
119 
121 {
122  getWorld()->removeObserver(observer_handle_);
123 }
124 
126  const std::map<std::string, std::vector<CollisionSphere>>& link_body_decompositions, const Eigen::Vector3d& size,
127  const Eigen::Vector3d& origin, bool use_signed_distance_field, double resolution, double collision_tolerance,
128  double max_propogation_distance)
129 {
130  size_ = size;
131  origin_ = origin;
132  use_signed_distance_field_ = use_signed_distance_field;
133  resolution_ = resolution;
134  collision_tolerance_ = collision_tolerance;
135  max_propogation_distance_ = max_propogation_distance;
136  addLinkBodyDecompositions(resolution_, link_body_decompositions);
138  planning_scene_ = std::make_shared<planning_scene::PlanningScene>(robot_model_);
139 
140  const std::vector<const moveit::core::JointModelGroup*>& jmg = robot_model_->getJointModelGroups();
141  for (const moveit::core::JointModelGroup* jm : jmg)
142  {
143  std::map<std::string, bool> updated_group_entry;
144  std::vector<std::string> links = jm->getUpdatedLinkModelsWithGeometryNames();
145  for (const std::string& link : links)
146  {
147  updated_group_entry[link] = true;
148  }
149  in_group_update_map_[jm->getName()] = updated_group_entry;
150  state.updateLinkTransforms();
151  DistanceFieldCacheEntryPtr dfce =
152  generateDistanceFieldCacheEntry(jm->getName(), state, &planning_scene_->getAllowedCollisionMatrix(), false);
154  }
155 }
156 
158  const std::string& group_name, const moveit::core::RobotState& state,
159  const collision_detection::AllowedCollisionMatrix* acm, GroupStateRepresentationPtr& gsr,
160  bool generate_distance_field) const
161 {
162  DistanceFieldCacheEntryConstPtr dfce = getDistanceFieldCacheEntry(group_name, state, acm);
163  if (!dfce || (generate_distance_field && !dfce->distance_field_))
164  {
165  // RCLCPP_DEBUG_NAMED("collision_distance_field", "Generating new
166  // DistanceFieldCacheEntry for CollisionRobot");
167  DistanceFieldCacheEntryPtr new_dfce =
168  generateDistanceFieldCacheEntry(group_name, state, acm, generate_distance_field);
169  std::scoped_lock slock(update_cache_lock_);
170  (const_cast<CollisionEnvDistanceField*>(this))->distance_field_cache_entry_ = new_dfce;
171  dfce = new_dfce;
172  }
173  getGroupStateRepresentation(dfce, state, gsr);
174 }
175 
178  const moveit::core::RobotState& state,
180  GroupStateRepresentationPtr& gsr) const
181 {
182  if (!gsr)
183  {
184  generateCollisionCheckingStructures(req.group_name, state, acm, gsr, true);
185  }
186  else
187  {
189  }
190  // ros::WallTime n = ros::WallTime::now();
191  bool done = getSelfCollisions(req, res, gsr);
192 
193  if (!done)
194  {
195  getIntraGroupCollisions(req, res, gsr);
196  if (res.collision)
197  RCLCPP_DEBUG(logger_, "Intra Group Collision found");
198  }
199 }
200 
201 DistanceFieldCacheEntryConstPtr
203  const moveit::core::RobotState& state,
205 {
206  DistanceFieldCacheEntryConstPtr ret;
208  {
209  RCLCPP_DEBUG(logger_, " No current Distance field cache entry");
210  return ret;
211  }
212  DistanceFieldCacheEntryConstPtr cur = distance_field_cache_entry_;
213  if (group_name != cur->group_name_)
214  {
215  RCLCPP_DEBUG(logger_, "No cache entry as group name changed from %s to %s", cur->group_name_.c_str(),
216  group_name.c_str());
217  return ret;
218  }
219  else if (!compareCacheEntryToState(cur, state))
220  {
221  // Regenerating distance field as state has changed from last time
222  // RCLCPP_DEBUG_NAMED("collision_distance_field", "Regenerating distance field as
223  // state has changed from last time");
224  return ret;
225  }
226  else if (acm && !compareCacheEntryToAllowedCollisionMatrix(cur, *acm))
227  {
228  RCLCPP_DEBUG(logger_, "Regenerating distance field as some relevant part of the acm changed");
229  return ret;
230  }
231  return cur;
232 }
233 
236  const moveit::core::RobotState& state) const
237 {
238  GroupStateRepresentationPtr gsr;
239  checkSelfCollisionHelper(req, res, state, nullptr, gsr);
240 }
241 
244  const moveit::core::RobotState& state,
245  GroupStateRepresentationPtr& gsr) const
246 {
247  checkSelfCollisionHelper(req, res, state, nullptr, gsr);
248 }
249 
252  const moveit::core::RobotState& state,
254 {
255  GroupStateRepresentationPtr gsr;
256  checkSelfCollisionHelper(req, res, state, &acm, gsr);
257 }
258 
261  const moveit::core::RobotState& state,
263  GroupStateRepresentationPtr& gsr) const
264 {
265  if (gsr)
266  {
267  RCLCPP_WARN(logger_, "Shouldn't be calling this function with initialized gsr - ACM "
268  "will be ignored");
269  }
270  checkSelfCollisionHelper(req, res, state, &acm, gsr);
271 }
272 
275  GroupStateRepresentationPtr& gsr) const
276 {
277  for (unsigned int i{ 0 }; i < gsr->dfce_->link_names_.size() + gsr->dfce_->attached_body_names_.size(); ++i)
278  {
279  bool is_link{ i < gsr->dfce_->link_names_.size() };
280  if ((is_link && !gsr->dfce_->link_has_geometry_[i]) || !gsr->dfce_->self_collision_enabled_[i])
281  continue;
282  const std::vector<CollisionSphere>* collision_spheres_1;
283  const EigenSTL::vector_Vector3d* sphere_centers_1;
284 
285  if (is_link)
286  {
287  collision_spheres_1 = &(gsr->link_body_decompositions_[i]->getCollisionSpheres());
288  sphere_centers_1 = &(gsr->link_body_decompositions_[i]->getSphereCenters());
289  }
290  else
291  {
292  collision_spheres_1 =
293  &(gsr->attached_body_decompositions_[i - gsr->dfce_->link_names_.size()]->getCollisionSpheres());
294  sphere_centers_1 = &(gsr->attached_body_decompositions_[i - gsr->dfce_->link_names_.size()]->getSphereCenters());
295  }
296 
297  if (req.contacts)
298  {
299  std::vector<unsigned int> colls;
300  bool coll =
301  getCollisionSphereCollision(gsr->dfce_->distance_field_.get(), *collision_spheres_1, *sphere_centers_1,
303  std::min(req.max_contacts_per_pair, req.max_contacts - res.contact_count), colls);
304  if (coll)
305  {
306  res.collision = true;
307  for (unsigned int col : colls)
308  {
310  if (is_link)
311  {
312  con.pos = gsr->link_body_decompositions_[i]->getSphereCenters()[col];
314  con.body_name_1 = gsr->dfce_->link_names_[i];
315  }
316  else
317  {
318  con.pos = gsr->attached_body_decompositions_[i - gsr->dfce_->link_names_.size()]->getSphereCenters()[col];
320  con.body_name_1 = gsr->dfce_->attached_body_names_[i - gsr->dfce_->link_names_.size()];
321  }
322 
323  RCLCPP_DEBUG(logger_, "Self collision detected for link %s ", con.body_name_1.c_str());
324 
326  con.body_name_2 = "self";
327  res.contact_count++;
328  res.contacts[std::pair<std::string, std::string>(con.body_name_1, con.body_name_2)].push_back(con);
329  gsr->gradients_[i].types[col] = SELF;
330  }
331  gsr->gradients_[i].collision = true;
332 
333  if (res.contact_count >= req.max_contacts)
334  {
335  return true;
336  }
337  }
338  }
339  else
340  {
341  bool coll = getCollisionSphereCollision(gsr->dfce_->distance_field_.get(), *collision_spheres_1,
342  *sphere_centers_1, max_propogation_distance_, collision_tolerance_);
343  if (coll)
344  {
345  RCLCPP_DEBUG(logger_, "Link %s in self collision", gsr->dfce_->link_names_[i].c_str());
346  res.collision = true;
347  return true;
348  }
349  }
350  }
351  return (res.contact_count >= req.max_contacts);
352 }
353 
354 bool CollisionEnvDistanceField::getSelfProximityGradients(GroupStateRepresentationPtr& gsr) const
355 {
356  bool in_collision = false;
357 
358  for (unsigned int i{ 0 }; i < gsr->dfce_->link_names_.size(); ++i)
359  {
360  const std::string& link_name = gsr->dfce_->link_names_[i];
361  bool is_link{ i < gsr->dfce_->link_names_.size() };
362  if ((is_link && !gsr->dfce_->link_has_geometry_[i]) || !gsr->dfce_->self_collision_enabled_[i])
363  {
364  continue;
365  }
366 
367  const std::vector<CollisionSphere>* collision_spheres_1;
368  const EigenSTL::vector_Vector3d* sphere_centers_1;
369  if (is_link)
370  {
371  collision_spheres_1 = &(gsr->link_body_decompositions_[i]->getCollisionSpheres());
372  sphere_centers_1 = &(gsr->link_body_decompositions_[i]->getSphereCenters());
373  }
374  else
375  {
376  collision_spheres_1 =
377  &(gsr->attached_body_decompositions_[i - gsr->dfce_->link_names_.size()]->getCollisionSpheres());
378  sphere_centers_1 = &(gsr->attached_body_decompositions_[i - gsr->dfce_->link_names_.size()]->getSphereCenters());
379  }
380 
381  // computing distance gradients by checking collisions against other mobile
382  // links as indicated by the AllowedCollisionMatrix
383  bool coll = false;
384  if (gsr->dfce_->acm_.getSize() > 0)
385  {
386  AllowedCollision::Type col_type;
387  for (unsigned int j{ 0 }; j < gsr->dfce_->link_names_.size(); ++j)
388  {
389  // on self collisions skip
390  if (link_name == gsr->dfce_->link_names_[j])
391  {
392  continue;
393  }
394 
395  // on collision exceptions skip
396  if (gsr->dfce_->acm_.getEntry(link_name, gsr->dfce_->link_names_[j], col_type) &&
397  col_type != AllowedCollision::NEVER)
398  {
399  continue;
400  }
401 
402  if (gsr->link_distance_fields_[j])
403  {
404  coll = gsr->link_distance_fields_[j]->getCollisionSphereGradients(
405  *collision_spheres_1, *sphere_centers_1, gsr->gradients_[i], collision_detection::SELF,
407 
408  if (coll)
409  {
410  in_collision = true;
411  }
412  }
413  }
414  }
415 
416  coll = getCollisionSphereGradients(gsr->dfce_->distance_field_.get(), *collision_spheres_1, *sphere_centers_1,
417  gsr->gradients_[i], collision_detection::SELF, collision_tolerance_, false,
419 
420  if (coll)
421  {
422  in_collision = true;
423  }
424  }
425 
426  return in_collision;
427 }
428 
431  GroupStateRepresentationPtr& gsr) const
432 {
433  unsigned int num_links = gsr->dfce_->link_names_.size();
434  unsigned int num_attached_bodies = gsr->dfce_->attached_body_names_.size();
435 
436  for (unsigned int i{ 0 }; i < num_links + num_attached_bodies; ++i)
437  {
438  for (unsigned int j{ i + 1 }; j < num_links + num_attached_bodies; ++j)
439  {
440  if (i == j)
441  continue;
442  bool i_is_link = i < num_links;
443  bool j_is_link = j < num_links;
444 
445  if ((i_is_link && !gsr->dfce_->link_has_geometry_[i]) || (j_is_link && !gsr->dfce_->link_has_geometry_[j]))
446  continue;
447 
448  if (!gsr->dfce_->intra_group_collision_enabled_[i][j])
449  continue;
450 
451  if (i_is_link && j_is_link &&
452  !doBoundingSpheresIntersect(gsr->link_body_decompositions_[i], gsr->link_body_decompositions_[j]))
453  {
454  // RCLCPP_DEBUG("Bounding spheres for " <<
455  // gsr->dfce_->link_names_[i] << " and " << gsr->dfce_->link_names_[j]
456  //<< " don't intersect");
457  continue;
458  }
459  else if (!i_is_link || !j_is_link)
460  {
461  bool all_ok = true;
462  if (!i_is_link && j_is_link)
463  {
464  for (unsigned int k = 0; k < gsr->attached_body_decompositions_[i - num_links]->getSize(); ++k)
465  {
467  gsr->link_body_decompositions_[j],
468  gsr->attached_body_decompositions_[i - num_links]->getPosedBodySphereDecomposition(k)))
469  {
470  all_ok = false;
471  break;
472  }
473  }
474  }
475  else if (i_is_link && !j_is_link)
476  {
477  for (unsigned int k = 0; k < gsr->attached_body_decompositions_[j - num_links]->getSize(); ++k)
478  {
480  gsr->link_body_decompositions_[i],
481  gsr->attached_body_decompositions_[j - num_links]->getPosedBodySphereDecomposition(k)))
482  {
483  all_ok = false;
484  break;
485  }
486  }
487  }
488  else
489  {
490  for (unsigned int k{ 0 }; k < gsr->attached_body_decompositions_[i - num_links]->getSize() && all_ok; ++k)
491  {
492  for (unsigned int l{ 0 }; l < gsr->attached_body_decompositions_[j - num_links]->getSize(); ++l)
493  {
495  gsr->attached_body_decompositions_[i - num_links]->getPosedBodySphereDecomposition(k),
496  gsr->attached_body_decompositions_[j - num_links]->getPosedBodySphereDecomposition(l)))
497  {
498  all_ok = false;
499  break;
500  }
501  }
502  }
503  }
504  if (all_ok)
505  {
506  continue;
507  }
508  // std::cerr << "Bounding spheres for " << gsr->dfce_->link_names_[i] <<
509  // " and " << gsr->dfce_->link_names_[j]
510  // << " intersect" << '\n';
511  }
512  int num_pair = -1;
513  std::string name_1;
514  std::string name_2;
515  if (i_is_link)
516  {
517  name_1 = gsr->dfce_->link_names_[i];
518  }
519  else
520  {
521  name_1 = gsr->dfce_->attached_body_names_[i - num_links];
522  }
523 
524  if (j_is_link)
525  {
526  name_2 = gsr->dfce_->link_names_[j];
527  }
528  else
529  {
530  name_2 = gsr->dfce_->attached_body_names_[j - num_links];
531  }
532  if (req.contacts)
533  {
534  collision_detection::CollisionResult::ContactMap::iterator it =
535  res.contacts.find(std::pair<std::string, std::string>(name_1, name_2));
536  if (it == res.contacts.end())
537  {
538  num_pair = 0;
539  }
540  else
541  {
542  num_pair = it->second.size();
543  }
544  }
545  const std::vector<CollisionSphere>* collision_spheres_1;
546  const std::vector<CollisionSphere>* collision_spheres_2;
547  const EigenSTL::vector_Vector3d* sphere_centers_1;
548  const EigenSTL::vector_Vector3d* sphere_centers_2;
549  if (i_is_link)
550  {
551  collision_spheres_1 = &(gsr->link_body_decompositions_[i]->getCollisionSpheres());
552  sphere_centers_1 = &(gsr->link_body_decompositions_[i]->getSphereCenters());
553  }
554  else
555  {
556  collision_spheres_1 = &(gsr->attached_body_decompositions_[i - num_links]->getCollisionSpheres());
557  sphere_centers_1 = &(gsr->attached_body_decompositions_[i - num_links]->getSphereCenters());
558  }
559  if (j_is_link)
560  {
561  collision_spheres_2 = &(gsr->link_body_decompositions_[j]->getCollisionSpheres());
562  sphere_centers_2 = &(gsr->link_body_decompositions_[j]->getSphereCenters());
563  }
564  else
565  {
566  collision_spheres_2 = &(gsr->attached_body_decompositions_[j - num_links]->getCollisionSpheres());
567  sphere_centers_2 = &(gsr->attached_body_decompositions_[j - num_links]->getSphereCenters());
568  }
569 
570  for (unsigned int k{ 0 };
571  k < collision_spheres_1->size() && num_pair < static_cast<int>(req.max_contacts_per_pair); ++k)
572  {
573  for (unsigned int l{ 0 };
574  l < collision_spheres_2->size() && num_pair < static_cast<int>(req.max_contacts_per_pair); ++l)
575  {
576  Eigen::Vector3d gradient = (*sphere_centers_1)[k] - (*sphere_centers_2)[l];
577  double dist = gradient.norm();
578  // std::cerr << "Dist is " << dist << " rad " <<
579  // (*collision_spheres_1)[k].radius_+(*collision_spheres_2)[l].radius_
580  // << '\n';
581 
582  if (dist < (*collision_spheres_1)[k].radius_ + (*collision_spheres_2)[l].radius_)
583  {
584  // RCLCPP_DEBUG(logger_,"Intra-group contact between %s and %s, d =
585  // %f < r1 = %f + r2 = %f", name_1.c_str(),
586  // name_2.c_str(),
587  // dist ,(*collision_spheres_1)[k].radius_
588  // ,(*collision_spheres_2)[l].radius_);
589  // Eigen::Vector3d sc1 = (*sphere_centers_1)[k];
590  // Eigen::Vector3d sc2 = (*sphere_centers_2)[l];
591  // RCLCPP_DEBUG(logger_,"sphere center 1:[ %f, %f, %f ], sphere
592  // center 2: [%f, %f,%f ], lbdc size =
593  // %i",sc1[0],sc1[1],sc1[2],
594  // sc2[0],sc2[1],sc2[2],int(gsr->link_body_decompositions_.size()));
595  res.collision = true;
596 
597  if (req.contacts)
598  {
600  con.pos = gsr->link_body_decompositions_[i]->getSphereCenters()[k];
601  con.body_name_1 = name_1;
602  con.body_name_2 = name_2;
603  if (i_is_link)
604  {
606  }
607  else
608  {
610  }
611  if (j_is_link)
612  {
614  }
615  else
616  {
618  }
619  res.contact_count++;
620  res.contacts[std::pair<std::string, std::string>(con.body_name_1, con.body_name_2)].push_back(con);
621  num_pair++;
622  gsr->gradients_[i].types[k] = INTRA;
623  gsr->gradients_[i].collision = true;
624  gsr->gradients_[j].types[l] = INTRA;
625  gsr->gradients_[j].collision = true;
626  if (res.contact_count >= req.max_contacts)
627  {
628  return true;
629  }
630  }
631  else
632  {
633  return true;
634  }
635  }
636  }
637  }
638  }
639  }
640  return false;
641 }
642 
643 bool CollisionEnvDistanceField::getIntraGroupProximityGradients(GroupStateRepresentationPtr& gsr) const
644 {
645  bool in_collision{ false };
646  unsigned int num_links = gsr->dfce_->link_names_.size();
647  unsigned int num_attached_bodies = gsr->dfce_->attached_body_names_.size();
648  // TODO - deal with attached bodies
649  for (unsigned int i{ 0 }; i < num_links + num_attached_bodies; ++i)
650  {
651  for (unsigned int j{ i + 1 }; j < num_links + num_attached_bodies; ++j)
652  {
653  if (i == j)
654  continue;
655  bool i_is_link = i < num_links;
656  bool j_is_link = j < num_links;
657  if ((i_is_link && !gsr->dfce_->link_has_geometry_[i]) || (j_is_link && !gsr->dfce_->link_has_geometry_[j]))
658  continue;
659  if (!gsr->dfce_->intra_group_collision_enabled_[i][j])
660  continue;
661  const std::vector<CollisionSphere>* collision_spheres_1;
662  const std::vector<CollisionSphere>* collision_spheres_2;
663  const EigenSTL::vector_Vector3d* sphere_centers_1;
664  const EigenSTL::vector_Vector3d* sphere_centers_2;
665  if (i_is_link)
666  {
667  collision_spheres_1 = &(gsr->link_body_decompositions_[i]->getCollisionSpheres());
668  sphere_centers_1 = &(gsr->link_body_decompositions_[i]->getSphereCenters());
669  }
670  else
671  {
672  collision_spheres_1 = &(gsr->attached_body_decompositions_[i - num_links]->getCollisionSpheres());
673  sphere_centers_1 = &(gsr->attached_body_decompositions_[i - num_links]->getSphereCenters());
674  }
675  if (j_is_link)
676  {
677  collision_spheres_2 = &(gsr->link_body_decompositions_[j]->getCollisionSpheres());
678  sphere_centers_2 = &(gsr->link_body_decompositions_[j]->getSphereCenters());
679  }
680  else
681  {
682  collision_spheres_2 = &(gsr->attached_body_decompositions_[j - num_links]->getCollisionSpheres());
683  sphere_centers_2 = &(gsr->attached_body_decompositions_[j - num_links]->getSphereCenters());
684  }
685  for (unsigned int k{ 0 }; k < collision_spheres_1->size(); ++k)
686  {
687  for (unsigned int l{ 0 }; l < collision_spheres_2->size(); ++l)
688  {
689  Eigen::Vector3d gradient = (*sphere_centers_1)[k] - (*sphere_centers_2)[l];
690  double dist = gradient.norm();
691  if (dist < gsr->gradients_[i].distances[k])
692  {
693  gsr->gradients_[i].distances[k] = dist;
694  gsr->gradients_[i].gradients[k] = gradient;
695  gsr->gradients_[i].types[k] = INTRA;
696  }
697  if (dist < gsr->gradients_[j].distances[l])
698  {
699  gsr->gradients_[j].distances[l] = dist;
700  gsr->gradients_[j].gradients[l] = -gradient;
701  gsr->gradients_[j].types[l] = INTRA;
702  }
703  }
704  }
705  }
706  }
707  return in_collision;
708 }
710  const std::string& group_name, const moveit::core::RobotState& state,
711  const collision_detection::AllowedCollisionMatrix* acm, bool generate_distance_field) const
712 {
713  DistanceFieldCacheEntryPtr dfce = std::make_shared<DistanceFieldCacheEntry>();
714 
715  if (robot_model_->getJointModelGroup(group_name) == nullptr)
716  {
717  RCLCPP_WARN(logger_, "No group %s", group_name.c_str());
718  return dfce;
719  }
720 
721  dfce->group_name_ = group_name;
722  dfce->state_ = std::make_shared<moveit::core::RobotState>(state);
723  if (acm)
724  {
725  dfce->acm_ = *acm;
726  }
727  else
728  {
729  RCLCPP_WARN(logger_, "Allowed Collision Matrix is null, enabling all collisions "
730  "in the DistanceFieldCacheEntry");
731  }
732 
733  // generateAllowedCollisionInformation(dfce);
734  dfce->link_names_ = robot_model_->getJointModelGroup(group_name)->getUpdatedLinkModelNames();
735  std::vector<const moveit::core::AttachedBody*> all_attached_bodies;
736  dfce->state_->getAttachedBodies(all_attached_bodies);
737  unsigned int att_count = 0;
738 
739  // may be bigger than necessary
740  std::vector<bool> all_true(dfce->link_names_.size() + all_attached_bodies.size(), true);
741  std::vector<bool> all_false(dfce->link_names_.size() + all_attached_bodies.size(), false);
742 
743  const std::vector<const moveit::core::LinkModel*>& lsv = state.getJointModelGroup(group_name)->getUpdatedLinkModels();
744  dfce->self_collision_enabled_.resize(dfce->link_names_.size() + all_attached_bodies.size(), true);
745  dfce->intra_group_collision_enabled_.resize(dfce->link_names_.size() + all_attached_bodies.size());
746 
747  for (unsigned int i{ 0 }; i < dfce->link_names_.size(); ++i)
748  {
749  std::string link_name = dfce->link_names_[i];
750  const moveit::core::LinkModel* link_state = dfce->state_->getLinkModel(link_name);
751  bool found{ false };
752 
753  for (unsigned int j{ 0 }; j < lsv.size(); ++j)
754  {
755  if (lsv[j]->getName() == link_name)
756  {
757  dfce->link_state_indices_.push_back(j);
758  found = true;
759  break;
760  }
761  }
762 
763  if (!found)
764  {
765  RCLCPP_DEBUG(logger_, "No link state found for link %s", dfce->link_names_[i].c_str());
766  continue;
767  }
768 
769  if (!link_state->getShapes().empty())
770  {
771  dfce->link_has_geometry_.push_back(true);
772  dfce->link_body_indices_.push_back(link_body_decomposition_index_map_.find(link_name)->second);
773 
774  if (acm)
775  {
777  if (acm->getEntry(link_name, link_name, t) && t == collision_detection::AllowedCollision::ALWAYS)
778  {
779  dfce->self_collision_enabled_[i] = false;
780  }
781 
782  dfce->intra_group_collision_enabled_[i] = all_true;
783  for (unsigned int j{ i + 1 }; j < dfce->link_names_.size(); ++j)
784  {
785  if (link_name == dfce->link_names_[j])
786  {
787  dfce->intra_group_collision_enabled_[i][j] = false;
788  continue;
789  }
790  if (acm->getEntry(link_name, dfce->link_names_[j], t) && t == collision_detection::AllowedCollision::ALWAYS)
791  {
792  dfce->intra_group_collision_enabled_[i][j] = false;
793  }
794  }
795 
796  std::vector<const moveit::core::AttachedBody*> link_attached_bodies;
797  state.getAttachedBodies(link_attached_bodies, link_state);
798  for (unsigned int j{ 0 }; j < link_attached_bodies.size(); ++j, ++att_count)
799  {
800  dfce->attached_body_names_.push_back(link_attached_bodies[j]->getName());
801  dfce->attached_body_link_state_indices_.push_back(dfce->link_state_indices_[i]);
802 
803  if (acm->getEntry(link_name, link_attached_bodies[j]->getName(), t))
804  {
806  {
807  dfce->intra_group_collision_enabled_[i][att_count + dfce->link_names_.size()] = false;
808  }
809  }
810  // std::cerr << "Checking touch links for " << link_name << " and " <<
811  // attached_bodies[j]->getName()
812  // << " num " << attached_bodies[j]->getTouchLinks().size()
813  // << '\n';
814  // touch links take priority
815  if (link_attached_bodies[j]->getTouchLinks().find(link_name) != link_attached_bodies[j]->getTouchLinks().end())
816  {
817  dfce->intra_group_collision_enabled_[i][att_count + dfce->link_names_.size()] = false;
818  // std::cerr << "Setting intra group for " << link_name << " and
819  // attached body " << link_attached_bodies[j]->getName() << " to
820  // false" << '\n';
821  }
822  }
823  }
824  else
825  {
826  dfce->self_collision_enabled_[i] = true;
827  dfce->intra_group_collision_enabled_[i] = all_true;
828  }
829  }
830  else
831  {
832  dfce->link_has_geometry_.push_back(false);
833  dfce->link_body_indices_.push_back(0);
834  dfce->self_collision_enabled_[i] = false;
835  dfce->intra_group_collision_enabled_[i] = all_false;
836  }
837  }
838 
839  for (unsigned int i = 0; i < dfce->attached_body_names_.size(); ++i)
840  {
841  dfce->intra_group_collision_enabled_[i + dfce->link_names_.size()] = all_true;
842  if (acm)
843  {
845  if (acm->getEntry(dfce->attached_body_names_[i], dfce->attached_body_names_[i], t) &&
847  {
848  dfce->self_collision_enabled_[i + dfce->link_names_.size()] = false;
849  }
850  for (unsigned int j{ i + 1 }; j < dfce->attached_body_names_.size(); ++j)
851  {
852  if (acm->getEntry(dfce->attached_body_names_[i], dfce->attached_body_names_[j], t) &&
854  {
855  dfce->intra_group_collision_enabled_[i + dfce->link_names_.size()][j + dfce->link_names_.size()] = false;
856  }
857  // TODO - allow for touch links to be attached bodies?
858  // else {
859  // std::cerr << "Setting not allowed for " << link_name << " and " <<
860  // dfce->link_names_[j] << '\n';
861  //}
862  }
863  }
864  }
865 
866  std::map<std::string, GroupStateRepresentationPtr>::const_iterator it =
867  pregenerated_group_state_representation_map_.find(dfce->group_name_);
869  {
870  dfce->pregenerated_group_state_representation_ = it->second;
871  }
872 
873  std::map<std::string, bool> updated_map;
874  if (!dfce->link_names_.empty())
875  {
876  const std::vector<const moveit::core::JointModel*>& child_joint_models =
877  dfce->state_->getJointModelGroup(dfce->group_name_)->getActiveJointModels();
878  for (const moveit::core::JointModel* child_joint_model : child_joint_models)
879  {
880  updated_map[child_joint_model->getName()] = true;
881  RCLCPP_DEBUG(logger_, "Joint %s has been added to updated list ", child_joint_model->getName().c_str());
882  }
883  }
884 
885  const std::vector<std::string>& state_variable_names = state.getVariableNames();
886  for (const std::string& state_variable_name : state_variable_names)
887  {
888  double val = state.getVariablePosition(state_variable_name);
889  dfce->state_values_.push_back(val);
890  if (updated_map.count(state_variable_name) == 0)
891  {
892  dfce->state_check_indices_.push_back(dfce->state_values_.size() - 1);
893  RCLCPP_DEBUG(logger_, "Non-group joint %p will be checked for state changes", state_variable_name.c_str());
894  }
895  }
896 
897  if (generate_distance_field)
898  {
899  if (dfce->distance_field_)
900  {
901  RCLCPP_DEBUG(logger_, "CollisionRobot skipping distance field generation, "
902  "will use existing one");
903  }
904  else
905  {
906  std::vector<PosedBodyPointDecompositionPtr> non_group_link_decompositions;
907  std::vector<PosedBodyPointDecompositionVectorPtr> non_group_attached_body_decompositions;
908  const std::map<std::string, bool>& updated_group_map = in_group_update_map_.find(group_name)->second;
909  for (const moveit::core::LinkModel* link_model : robot_model_->getLinkModelsWithCollisionGeometry())
910  {
911  const std::string& link_name = link_model->getName();
912  const moveit::core::LinkModel* link_state = dfce->state_->getLinkModel(link_name);
913  if (updated_group_map.find(link_name) != updated_group_map.end())
914  {
915  continue;
916  }
917 
918  // populating array with link that are not part of the planning group
919  non_group_link_decompositions.push_back(getPosedLinkBodyPointDecomposition(link_state));
920  non_group_link_decompositions.back()->updatePose(dfce->state_->getFrameTransform(link_state->getName()));
921 
922  std::vector<const moveit::core::AttachedBody*> attached_bodies;
923  dfce->state_->getAttachedBodies(attached_bodies, link_state);
924  for (const moveit::core::AttachedBody* attached_body : attached_bodies)
925  {
926  non_group_attached_body_decompositions.push_back(
928  }
929  }
930  dfce->distance_field_ = std::make_shared<distance_field::PropagationDistanceField>(
931  size_.x(), size_.y(), size_.z(), resolution_, origin_.x() - 0.5 * size_.x(), origin_.y() - 0.5 * size_.y(),
933 
934  // TODO - deal with AllowedCollisionMatrix
935  // now we need to actually set the points
936  // TODO - deal with shifted robot
937  EigenSTL::vector_Vector3d all_points;
938  for (collision_detection::PosedBodyPointDecompositionPtr& non_group_link_decomposition :
939  non_group_link_decompositions)
940  {
941  all_points.insert(all_points.end(), non_group_link_decomposition->getCollisionPoints().begin(),
942  non_group_link_decomposition->getCollisionPoints().end());
943  }
944 
945  for (collision_detection::PosedBodyPointDecompositionVectorPtr& non_group_attached_body_decomposition :
946  non_group_attached_body_decompositions)
947  {
948  const EigenSTL::vector_Vector3d collision_points = non_group_attached_body_decomposition->getCollisionPoints();
949  all_points.insert(all_points.end(), collision_points.begin(), collision_points.end());
950  }
951 
952  dfce->distance_field_->addPointsToField(all_points);
953  RCLCPP_DEBUG(logger_, "CollisionRobot distance field has been initialized with %zu points.", all_points.size());
954  }
955  }
956  return dfce;
957 }
958 
960 {
961  const std::vector<const moveit::core::LinkModel*>& link_models = robot_model_->getLinkModelsWithCollisionGeometry();
962  for (const moveit::core::LinkModel* link_model : link_models)
963  {
964  if (link_model->getShapes().empty())
965  {
966  RCLCPP_WARN(logger_, "No collision geometry for link model %s though there should be",
967  link_model->getName().c_str());
968  continue;
969  }
970 
971  RCLCPP_DEBUG(logger_, "Generating model for %s", link_model->getName().c_str());
972  BodyDecompositionConstPtr bd =
973  std::make_shared<const BodyDecomposition>(link_model->getShapes(), link_model->getCollisionOriginTransforms(),
974  resolution, getLinkPadding(link_model->getName()));
975  link_body_decomposition_vector_.push_back(bd);
976  link_body_decomposition_index_map_[link_model->getName()] = link_body_decomposition_vector_.size() - 1;
977  }
978 }
979 
981  visualization_msgs::msg::MarkerArray& model_markers) const
982 {
983  // creating colors
984  std_msgs::msg::ColorRGBA robot_color;
985  robot_color.r = 0;
986  robot_color.b = 0.8f;
987  robot_color.g = 0;
988  robot_color.a = 0.5;
989 
990  std_msgs::msg::ColorRGBA world_links_color;
991  world_links_color.r = 1;
992  world_links_color.g = 1;
993  world_links_color.b = 0;
994  world_links_color.a = 0.5;
995 
996  // creating sphere marker
997  visualization_msgs::msg::Marker sphere_marker;
998  sphere_marker.header.frame_id = robot_model_->getRootLinkName();
999  sphere_marker.header.stamp = rclcpp::Time(0);
1000  sphere_marker.ns = distance_field_cache_entry_->group_name_ + "_sphere_decomposition";
1001  sphere_marker.id = 0;
1002  sphere_marker.type = visualization_msgs::msg::Marker::SPHERE;
1003  sphere_marker.action = visualization_msgs::msg::Marker::ADD;
1004  sphere_marker.pose.orientation.x = 0;
1005  sphere_marker.pose.orientation.y = 0;
1006  sphere_marker.pose.orientation.z = 0;
1007  sphere_marker.pose.orientation.w = 1;
1008  sphere_marker.color = robot_color;
1009  sphere_marker.lifetime = rclcpp::Duration::from_seconds(0);
1010 
1011  unsigned int id{ 0 };
1012  const moveit::core::JointModelGroup* joint_group = state.getJointModelGroup(distance_field_cache_entry_->group_name_);
1013  const std::vector<std::string>& group_link_names = joint_group->getUpdatedLinkModelNames();
1014 
1015  std::map<std::string, unsigned int>::const_iterator map_iter;
1016  for (map_iter = link_body_decomposition_index_map_.begin(); map_iter != link_body_decomposition_index_map_.end();
1017  ++map_iter)
1018  {
1019  const std::string& link_name = map_iter->first;
1020  unsigned int link_index = map_iter->second;
1021 
1022  // selecting color
1023  if (std::find(group_link_names.begin(), group_link_names.end(), link_name) != group_link_names.end())
1024  {
1025  sphere_marker.color = robot_color;
1026  }
1027  else
1028  {
1029  sphere_marker.color = world_links_color;
1030  }
1031 
1032  collision_detection::PosedBodySphereDecompositionPtr sphere_representation(
1034  sphere_representation->updatePose(state.getGlobalLinkTransform(link_name));
1035  for (unsigned int j{ 0 }; j < sphere_representation->getCollisionSpheres().size(); ++j)
1036  {
1037  sphere_marker.pose.position = tf2::toMsg(sphere_representation->getSphereCenters()[j]);
1038  sphere_marker.scale.x = sphere_marker.scale.y = sphere_marker.scale.z =
1039  2 * sphere_representation->getCollisionSpheres()[j].radius_;
1040  sphere_marker.id = id;
1041  id++;
1042 
1043  model_markers.markers.push_back(sphere_marker);
1044  }
1045  }
1046 }
1047 
1049  double resolution, const std::map<std::string, std::vector<CollisionSphere>>& link_spheres)
1050 {
1051  assert(robot_model_);
1052  const std::vector<const moveit::core::LinkModel*>& link_models = robot_model_->getLinkModelsWithCollisionGeometry();
1053 
1054  for (const moveit::core::LinkModel* link_model : link_models)
1055  {
1056  if (link_model->getShapes().empty())
1057  {
1058  RCLCPP_WARN(logger_, "Skipping model generation for link %s since it contains no geometries",
1059  link_model->getName().c_str());
1060  continue;
1061  }
1062 
1063  BodyDecompositionPtr bd =
1064  std::make_shared<BodyDecomposition>(link_model->getShapes(), link_model->getCollisionOriginTransforms(),
1065  resolution, getLinkPadding(link_model->getName()));
1066 
1067  RCLCPP_DEBUG(logger_, "Generated model for %s", link_model->getName().c_str());
1068 
1069  if (link_spheres.find(link_model->getName()) != link_spheres.end())
1070  {
1071  bd->replaceCollisionSpheres(link_spheres.find(link_model->getName())->second, Eigen::Isometry3d::Identity());
1072  }
1073  link_body_decomposition_vector_.push_back(bd);
1074  link_body_decomposition_index_map_[link_model->getName()] = link_body_decomposition_vector_.size() - 1;
1075  }
1076  RCLCPP_DEBUG(logger_, " Finished ");
1077 }
1078 
1079 PosedBodySphereDecompositionPtr
1081  unsigned int ind) const
1082 {
1083  PosedBodySphereDecompositionPtr ret;
1084  ret = std::make_shared<PosedBodySphereDecomposition>(link_body_decomposition_vector_.at(ind));
1085  return ret;
1086 }
1087 
1088 PosedBodyPointDecompositionPtr
1090 {
1091  PosedBodyPointDecompositionPtr ret;
1092  std::map<std::string, unsigned int>::const_iterator it = link_body_decomposition_index_map_.find(ls->getName());
1093  if (it == link_body_decomposition_index_map_.end())
1094  {
1095  RCLCPP_ERROR(logger_, "No link body decomposition for link %s.", ls->getName().c_str());
1096  return ret;
1097  }
1098  ret = std::make_shared<PosedBodyPointDecomposition>(link_body_decomposition_vector_[it->second]);
1099  return ret;
1100 }
1101 
1103  GroupStateRepresentationPtr& gsr) const
1104 {
1105  for (unsigned int i{ 0 }; i < gsr->dfce_->link_names_.size(); ++i)
1106  {
1107  const moveit::core::LinkModel* ls = state.getLinkModel(gsr->dfce_->link_names_[i]);
1108  if (gsr->dfce_->link_has_geometry_[i])
1109  {
1110  gsr->link_body_decompositions_[i]->updatePose(state.getFrameTransform(ls->getName()));
1111  gsr->link_distance_fields_[i]->updatePose(state.getFrameTransform(ls->getName()));
1112  gsr->gradients_[i].closest_distance = DBL_MAX;
1113  gsr->gradients_[i].collision = false;
1114  gsr->gradients_[i].types.assign(gsr->link_body_decompositions_[i]->getCollisionSpheres().size(), NONE);
1115  gsr->gradients_[i].distances.assign(gsr->link_body_decompositions_[i]->getCollisionSpheres().size(), DBL_MAX);
1116  gsr->gradients_[i].gradients.assign(gsr->link_body_decompositions_[i]->getCollisionSpheres().size(),
1117  Eigen::Vector3d(0.0, 0.0, 0.0));
1118  gsr->gradients_[i].sphere_locations = gsr->link_body_decompositions_[i]->getSphereCenters();
1119  }
1120  }
1121 
1122  for (unsigned int i{ 0 }; i < gsr->dfce_->attached_body_names_.size(); ++i)
1123  {
1124  const moveit::core::AttachedBody* att = state.getAttachedBody(gsr->dfce_->attached_body_names_[i]);
1125  if (!att)
1126  {
1127  RCLCPP_WARN(logger_, "Attached body discrepancy");
1128  continue;
1129  }
1130 
1131  // TODO: This logic for checking attached body count might be incorrect
1132  if (gsr->attached_body_decompositions_.size() != att->getShapes().size())
1133  {
1134  RCLCPP_WARN(logger_, "Attached body size discrepancy");
1135  continue;
1136  }
1137 
1138  for (unsigned int j{ 0 }; j < att->getShapes().size(); ++j)
1139  {
1140  gsr->attached_body_decompositions_[i]->updatePose(j, att->getGlobalCollisionBodyTransforms()[j]);
1141  }
1142 
1143  gsr->gradients_[i + gsr->dfce_->link_names_.size()].closest_distance = DBL_MAX;
1144  gsr->gradients_[i + gsr->dfce_->link_names_.size()].collision = false;
1145  gsr->gradients_[i + gsr->dfce_->link_names_.size()].types.assign(
1146  gsr->attached_body_decompositions_[i]->getCollisionSpheres().size(), NONE);
1147  gsr->gradients_[i + gsr->dfce_->link_names_.size()].distances.assign(
1148  gsr->attached_body_decompositions_[i]->getCollisionSpheres().size(), DBL_MAX);
1149  gsr->gradients_[i + gsr->dfce_->link_names_.size()].gradients.assign(
1150  gsr->attached_body_decompositions_[i]->getCollisionSpheres().size(), Eigen::Vector3d(0.0, 0.0, 0.0));
1151  gsr->gradients_[i + gsr->dfce_->link_names_.size()].sphere_locations =
1152  gsr->attached_body_decompositions_[i]->getSphereCenters();
1153  }
1154 }
1155 
1156 void CollisionEnvDistanceField::getGroupStateRepresentation(const DistanceFieldCacheEntryConstPtr& dfce,
1157  const moveit::core::RobotState& state,
1158  GroupStateRepresentationPtr& gsr) const
1159 {
1160  if (!dfce->pregenerated_group_state_representation_)
1161  {
1162  RCLCPP_DEBUG(logger_, "Creating GroupStateRepresentation");
1163 
1164  // unsigned int count = 0;
1165  gsr = std::make_shared<GroupStateRepresentation>();
1166  gsr->dfce_ = dfce;
1167  gsr->gradients_.resize(dfce->link_names_.size() + dfce->attached_body_names_.size());
1168 
1169  Eigen::Vector3d link_size;
1170  Eigen::Vector3d link_origin;
1171  for (unsigned int i{ 0 }; i < dfce->link_names_.size(); ++i)
1172  {
1173  const moveit::core::LinkModel* ls = state.getLinkModel(dfce->link_names_[i]);
1174  if (dfce->link_has_geometry_[i])
1175  {
1176  // create link body geometric decomposition
1177  gsr->link_body_decompositions_.push_back(getPosedLinkBodySphereDecomposition(ls, dfce->link_body_indices_[i]));
1178 
1179  // create and fill link distance field
1180  PosedBodySphereDecompositionPtr& link_bd = gsr->link_body_decompositions_.back();
1181  double diameter = 2 * link_bd->getBoundingSphereRadius();
1182  link_size = Eigen::Vector3d(diameter, diameter, diameter);
1183  link_origin = link_bd->getBoundingSphereCenter() - 0.5 * link_size;
1184 
1185  RCLCPP_DEBUG(logger_, "Creating PosedDistanceField for link %s with size [%f, %f , %f] and origin %f %f %f ",
1186  dfce->link_names_[i].c_str(), link_size.x(), link_size.y(), link_size.z(), link_origin.x(),
1187  link_origin.y(), link_origin.z());
1188 
1189  gsr->link_distance_fields_.push_back(std::make_shared<PosedDistanceField>(
1191  gsr->link_distance_fields_.back()->addPointsToField(link_bd->getCollisionPoints());
1192  RCLCPP_DEBUG(logger_, "Created PosedDistanceField for link %s with %zu points", dfce->link_names_[i].c_str(),
1193  link_bd->getCollisionPoints().size());
1194 
1195  gsr->link_body_decompositions_.back()->updatePose(state.getFrameTransform(ls->getName()));
1196  gsr->link_distance_fields_.back()->updatePose(state.getFrameTransform(ls->getName()));
1197  gsr->gradients_[i].types.resize(gsr->link_body_decompositions_.back()->getCollisionSpheres().size(), NONE);
1198  gsr->gradients_[i].distances.resize(gsr->link_body_decompositions_.back()->getCollisionSpheres().size(),
1199  DBL_MAX);
1200  gsr->gradients_[i].gradients.resize(gsr->link_body_decompositions_.back()->getCollisionSpheres().size());
1201  gsr->gradients_[i].sphere_radii = gsr->link_body_decompositions_.back()->getSphereRadii();
1202  gsr->gradients_[i].joint_name = ls->getParentJointModel()->getName();
1203  }
1204  else
1205  {
1206  gsr->link_body_decompositions_.push_back(PosedBodySphereDecompositionPtr());
1207  gsr->link_distance_fields_.push_back(PosedDistanceFieldPtr());
1208  }
1209  }
1210  }
1211  else
1212  {
1213  gsr = std::make_shared<GroupStateRepresentation>(*(dfce->pregenerated_group_state_representation_));
1214  gsr->dfce_ = dfce;
1215  gsr->gradients_.resize(dfce->link_names_.size() + dfce->attached_body_names_.size());
1216  for (unsigned int i{ 0 }; i < dfce->link_names_.size(); ++i)
1217  {
1218  const moveit::core::LinkModel* ls = state.getLinkModel(dfce->link_names_[i]);
1219  if (dfce->link_has_geometry_[i])
1220  {
1221  gsr->link_body_decompositions_[i]->updatePose(state.getFrameTransform(ls->getName()));
1222  gsr->link_distance_fields_[i]->updatePose(state.getFrameTransform(ls->getName()));
1223  gsr->gradients_[i].sphere_locations = gsr->link_body_decompositions_[i]->getSphereCenters();
1224  }
1225  }
1226  }
1227 
1228  for (unsigned int i{ 0 }; i < dfce->attached_body_names_.size(); ++i)
1229  {
1230  int link_index = dfce->attached_body_link_state_indices_[i];
1231  const moveit::core::LinkModel* ls =
1232  state.getJointModelGroup(gsr->dfce_->group_name_)->getUpdatedLinkModels()[link_index];
1233  // const moveit::core::LinkModel* ls =
1234  // state.getLinkStateVector()[dfce->attached_body_link_state_indices_[i]];
1237  gsr->attached_body_decompositions_.push_back(
1238  getAttachedBodySphereDecomposition(state.getAttachedBody(dfce->attached_body_names_[i]), resolution_));
1239  gsr->gradients_[i + dfce->link_names_.size()].types.resize(
1240  gsr->attached_body_decompositions_.back()->getCollisionSpheres().size(), NONE);
1241  gsr->gradients_[i + dfce->link_names_.size()].distances.resize(
1242  gsr->attached_body_decompositions_.back()->getCollisionSpheres().size(), DBL_MAX);
1243  gsr->gradients_[i + dfce->link_names_.size()].gradients.resize(
1244  gsr->attached_body_decompositions_.back()->getCollisionSpheres().size());
1245  gsr->gradients_[i + dfce->link_names_.size()].sphere_locations =
1246  gsr->attached_body_decompositions_.back()->getSphereCenters();
1247  gsr->gradients_[i + dfce->link_names_.size()].sphere_radii =
1248  gsr->attached_body_decompositions_.back()->getSphereRadii();
1249  gsr->gradients_[i + dfce->link_names_.size()].joint_name = ls->getParentJointModel()->getName();
1250  }
1251 }
1252 
1253 bool CollisionEnvDistanceField::compareCacheEntryToState(const DistanceFieldCacheEntryConstPtr& dfce,
1254  const moveit::core::RobotState& state) const
1255 {
1256  std::vector<double> new_state_values(state.getVariableCount());
1257  for (unsigned int i{ 0 }; i < new_state_values.size(); ++i)
1258  {
1259  new_state_values[i] = state.getVariablePosition(i);
1260  }
1261 
1262  if (dfce->state_values_.size() != new_state_values.size())
1263  {
1264  RCLCPP_ERROR(logger_, " State value size mismatch");
1265  return false;
1266  }
1267 
1268  for (unsigned int i{ 0 }; i < dfce->state_check_indices_.size(); ++i)
1269  {
1270  double diff =
1271  fabs(dfce->state_values_[dfce->state_check_indices_[i]] - new_state_values[dfce->state_check_indices_[i]]);
1272  if (diff > EPSILON)
1273  {
1274  RCLCPP_WARN(logger_, "State for Variable %s has changed by %f radians",
1275  state.getVariableNames()[dfce->state_check_indices_[i]].c_str(), diff);
1276  return false;
1277  }
1278  }
1279  std::vector<const moveit::core::AttachedBody*> attached_bodies_dfce;
1280  std::vector<const moveit::core::AttachedBody*> attached_bodies_state;
1281  dfce->state_->getAttachedBodies(attached_bodies_dfce);
1282  state.getAttachedBodies(attached_bodies_state);
1283  if (attached_bodies_dfce.size() != attached_bodies_state.size())
1284  {
1285  return false;
1286  }
1287  // TODO - figure all the things that can change
1288  for (unsigned int i{ 0 }; i < attached_bodies_dfce.size(); ++i)
1289  {
1290  if (attached_bodies_dfce[i]->getName() != attached_bodies_state[i]->getName())
1291  {
1292  return false;
1293  }
1294  if (attached_bodies_dfce[i]->getTouchLinks() != attached_bodies_state[i]->getTouchLinks())
1295  {
1296  return false;
1297  }
1298  if (attached_bodies_dfce[i]->getShapes().size() != attached_bodies_state[i]->getShapes().size())
1299  {
1300  return false;
1301  }
1302  for (unsigned int j = 0; j < attached_bodies_dfce[i]->getShapes().size(); ++j)
1303  {
1304  if (attached_bodies_dfce[i]->getShapes()[j] != attached_bodies_state[i]->getShapes()[j])
1305  {
1306  return false;
1307  }
1308  }
1309  }
1310  return true;
1311 }
1312 
1314  const DistanceFieldCacheEntryConstPtr& dfce, const collision_detection::AllowedCollisionMatrix& acm) const
1315 {
1316  if (dfce->acm_.getSize() != acm.getSize())
1317  {
1318  RCLCPP_DEBUG(logger_, "Allowed collision matrix size mismatch");
1319  return false;
1320  }
1321  std::vector<const moveit::core::AttachedBody*> attached_bodies;
1322  dfce->state_->getAttachedBodies(attached_bodies);
1323  for (unsigned int i{ 0 }; i < dfce->link_names_.size(); ++i)
1324  {
1325  std::string link_name = dfce->link_names_[i];
1326  if (dfce->link_has_geometry_[i])
1327  {
1328  bool self_collision_enabled{ true };
1330  if (acm.getEntry(link_name, link_name, t))
1331  {
1333  {
1334  self_collision_enabled = false;
1335  }
1336  }
1337  if (self_collision_enabled != dfce->self_collision_enabled_[i])
1338  {
1339  return false;
1340  }
1341  for (unsigned int j{ i }; j < dfce->link_names_.size(); ++j)
1342  {
1343  if (i == j)
1344  continue;
1345  if (dfce->link_has_geometry_[j])
1346  {
1347  bool intra_collision_enabled = true;
1348  if (acm.getEntry(link_name, dfce->link_names_[j], t))
1349  {
1351  {
1352  intra_collision_enabled = false;
1353  }
1354  }
1355  if (dfce->intra_group_collision_enabled_[i][j] != intra_collision_enabled)
1356  {
1357  // std::cerr << "Intra collision for " << dfce->link_names_[i] << "
1358  // " << dfce->link_names_[j]
1359  // << " went from " <<
1360  // dfce->intra_group_collision_enabled_[i][j] << " to " <<
1361  // intra_collision_enabled << '\n';
1362  return false;
1363  }
1364  }
1365  }
1366  }
1367  }
1368  return true;
1369 }
1370 
1371 // void
1372 // CollisionEnvDistanceField::generateAllowedCollisionInformation(CollisionEnvDistanceField::DistanceFieldCacheEntryPtr&
1373 // dfce)
1374 // {
1375 // for(unsigned int i = 0; i < dfce.link_names_.size(); ++i) {
1376 // for(unsigned int j = 0; j <
1377 // if(dfce->acm.find
1378 // }
1379 // }
1380 
1382  const moveit::core::RobotState& state) const
1383 {
1384  GroupStateRepresentationPtr gsr;
1385  checkCollision(req, res, state, gsr);
1386 }
1387 
1389  const moveit::core::RobotState& state,
1390  GroupStateRepresentationPtr& gsr) const
1391 {
1392  if (!gsr)
1393  {
1394  generateCollisionCheckingStructures(req.group_name, state, nullptr, gsr, true);
1395  }
1396  else
1397  {
1399  }
1400  bool done = getSelfCollisions(req, res, gsr);
1401  if (!done)
1402  {
1403  done = getIntraGroupCollisions(req, res, gsr);
1404  }
1405  if (!done)
1406  {
1407  getEnvironmentCollisions(req, res, distance_field_cache_entry_world_->distance_field_, gsr);
1408  }
1409 
1410  (const_cast<CollisionEnvDistanceField*>(this))->last_gsr_ = gsr;
1411 }
1412 
1414  const moveit::core::RobotState& state,
1415  const AllowedCollisionMatrix& acm) const
1416 {
1417  GroupStateRepresentationPtr gsr;
1418  checkCollision(req, res, state, acm, gsr);
1419 }
1420 
1422  const moveit::core::RobotState& state, const AllowedCollisionMatrix& acm,
1423  GroupStateRepresentationPtr& gsr) const
1424 {
1425  if (!gsr)
1426  {
1427  generateCollisionCheckingStructures(req.group_name, state, &acm, gsr, true);
1428  }
1429  else
1430  {
1432  }
1433  bool done = getSelfCollisions(req, res, gsr);
1434  if (!done)
1435  {
1436  done = getIntraGroupCollisions(req, res, gsr);
1437  }
1438  if (!done)
1439  {
1440  getEnvironmentCollisions(req, res, distance_field_cache_entry_world_->distance_field_, gsr);
1441  }
1442 
1443  (const_cast<CollisionEnvDistanceField*>(this))->last_gsr_ = gsr;
1444 }
1445 
1447  const moveit::core::RobotState& state) const
1448 {
1449  GroupStateRepresentationPtr gsr;
1450  checkRobotCollision(req, res, state, gsr);
1451 }
1452 
1454  const moveit::core::RobotState& state,
1455  GroupStateRepresentationPtr& gsr) const
1456 {
1457  distance_field::DistanceFieldConstPtr env_distance_field = distance_field_cache_entry_world_->distance_field_;
1458  if (!gsr)
1459  {
1460  generateCollisionCheckingStructures(req.group_name, state, nullptr, gsr, false);
1461  }
1462  else
1463  {
1465  }
1466  getEnvironmentCollisions(req, res, env_distance_field, gsr);
1467  (const_cast<CollisionEnvDistanceField*>(this))->last_gsr_ = gsr;
1468 
1469  // checkRobotCollisionHelper(req, res, robot, state, &acm);
1470 }
1471 
1473  const moveit::core::RobotState& state,
1474  const AllowedCollisionMatrix& acm) const
1475 {
1476  GroupStateRepresentationPtr gsr;
1477  checkRobotCollision(req, res, state, acm, gsr);
1478 }
1479 
1481  const moveit::core::RobotState& state,
1482  const AllowedCollisionMatrix& acm,
1483  GroupStateRepresentationPtr& gsr) const
1484 {
1485  distance_field::DistanceFieldConstPtr env_distance_field = distance_field_cache_entry_world_->distance_field_;
1486 
1487  if (!gsr)
1488  {
1489  generateCollisionCheckingStructures(req.group_name, state, &acm, gsr, true);
1490  }
1491  else
1492  {
1494  }
1495  getEnvironmentCollisions(req, res, env_distance_field, gsr);
1496  (const_cast<CollisionEnvDistanceField*>(this))->last_gsr_ = gsr;
1497 
1498  // checkRobotCollisionHelper(req, res, robot, state, &acm);
1499 }
1500 
1502  const moveit::core::RobotState& /*state1*/,
1503  const moveit::core::RobotState& /*state2*/,
1504  const AllowedCollisionMatrix& /*acm*/) const
1505 {
1506  RCLCPP_ERROR(logger_, "Continuous collision checking not implemented");
1507 }
1508 
1510  const moveit::core::RobotState& /*state1*/,
1511  const moveit::core::RobotState& /*state2*/) const
1512 {
1513  RCLCPP_ERROR(logger_, "Continuous collision checking not implemented");
1514 }
1515 
1517  const moveit::core::RobotState& state,
1518  const AllowedCollisionMatrix* acm,
1519  GroupStateRepresentationPtr& gsr) const
1520 {
1521  distance_field::DistanceFieldConstPtr env_distance_field = distance_field_cache_entry_world_->distance_field_;
1522 
1523  if (!gsr)
1524  {
1525  generateCollisionCheckingStructures(req.group_name, state, acm, gsr, true);
1526  }
1527  else
1528  {
1530  }
1531 
1534  getEnvironmentProximityGradients(env_distance_field, gsr);
1535 
1536  (const_cast<CollisionEnvDistanceField*>(this))->last_gsr_ = gsr;
1537 }
1538 
1540  const moveit::core::RobotState& state,
1541  const AllowedCollisionMatrix* acm,
1542  GroupStateRepresentationPtr& gsr) const
1543 {
1544  if (!gsr)
1545  {
1546  generateCollisionCheckingStructures(req.group_name, state, acm, gsr, true);
1547  }
1548  else
1549  {
1551  }
1552  getSelfCollisions(req, res, gsr);
1553  getIntraGroupCollisions(req, res, gsr);
1554  distance_field::DistanceFieldConstPtr env_distance_field = distance_field_cache_entry_world_->distance_field_;
1555  getEnvironmentCollisions(req, res, env_distance_field, gsr);
1556 
1557  (const_cast<CollisionEnvDistanceField*>(this))->last_gsr_ = gsr;
1558 }
1559 
1561  const distance_field::DistanceFieldConstPtr& env_distance_field,
1562  GroupStateRepresentationPtr& gsr) const
1563 {
1564  for (unsigned int i{ 0 }; i < gsr->dfce_->link_names_.size() + gsr->dfce_->attached_body_names_.size(); ++i)
1565  {
1566  bool is_link = i < gsr->dfce_->link_names_.size();
1567  std::string link_name = i < gsr->dfce_->link_names_.size() ? gsr->dfce_->link_names_[i] : "attached";
1568  if (is_link && !gsr->dfce_->link_has_geometry_[i])
1569  {
1570  continue;
1571  }
1572 
1573  const std::vector<CollisionSphere>* collision_spheres_1;
1574  const EigenSTL::vector_Vector3d* sphere_centers_1;
1575 
1576  if (is_link)
1577  {
1578  collision_spheres_1 = &(gsr->link_body_decompositions_[i]->getCollisionSpheres());
1579  sphere_centers_1 = &(gsr->link_body_decompositions_[i]->getSphereCenters());
1580  }
1581  else
1582  {
1583  collision_spheres_1 =
1584  &(gsr->attached_body_decompositions_[i - gsr->dfce_->link_names_.size()]->getCollisionSpheres());
1585  sphere_centers_1 = &(gsr->attached_body_decompositions_[i - gsr->dfce_->link_names_.size()]->getSphereCenters());
1586  }
1587 
1588  if (req.contacts)
1589  {
1590  std::vector<unsigned int> colls;
1591  bool coll =
1592  getCollisionSphereCollision(env_distance_field.get(), *collision_spheres_1, *sphere_centers_1,
1594  std::min(req.max_contacts_per_pair, req.max_contacts - res.contact_count), colls);
1595  if (coll)
1596  {
1597  res.collision = true;
1598  for (unsigned int col : colls)
1599  {
1600  Contact con;
1601  if (is_link)
1602  {
1603  con.pos = gsr->link_body_decompositions_[i]->getSphereCenters()[col];
1605  con.body_name_1 = gsr->dfce_->link_names_[i];
1606  }
1607  else
1608  {
1609  con.pos = gsr->attached_body_decompositions_[i - gsr->dfce_->link_names_.size()]->getSphereCenters()[col];
1611  con.body_name_1 = gsr->dfce_->attached_body_names_[i - gsr->dfce_->link_names_.size()];
1612  }
1613 
1615  con.body_name_2 = "environment";
1616  res.contact_count++;
1617  res.contacts[std::pair<std::string, std::string>(con.body_name_1, con.body_name_2)].push_back(con);
1618  gsr->gradients_[i].types[col] = ENVIRONMENT;
1619  // RCLCPP_DEBUG("Link " << dfce->link_names_[i] << " sphere " <<
1620  // colls[j] << " in env collision");
1621  }
1622 
1623  gsr->gradients_[i].collision = true;
1624  if (res.contact_count >= req.max_contacts)
1625  {
1626  return true;
1627  }
1628  }
1629  }
1630  else
1631  {
1632  bool coll = getCollisionSphereCollision(env_distance_field.get(), *collision_spheres_1, *sphere_centers_1,
1634  if (coll)
1635  {
1636  res.collision = true;
1637  return true;
1638  }
1639  }
1640  }
1641  return (res.contact_count >= req.max_contacts);
1642 }
1643 
1645  const distance_field::DistanceFieldConstPtr& env_distance_field, GroupStateRepresentationPtr& gsr) const
1646 {
1647  bool in_collision = false;
1648  for (unsigned int i{ 0 }; i < gsr->dfce_->link_names_.size(); ++i)
1649  {
1650  bool is_link = i < gsr->dfce_->link_names_.size();
1651 
1652  if (is_link && !gsr->dfce_->link_has_geometry_[i])
1653  {
1654  continue;
1655  }
1656 
1657  const std::vector<CollisionSphere>* collision_spheres_1;
1658  const EigenSTL::vector_Vector3d* sphere_centers_1;
1659  if (is_link)
1660  {
1661  collision_spheres_1 = &(gsr->link_body_decompositions_[i]->getCollisionSpheres());
1662  sphere_centers_1 = &(gsr->link_body_decompositions_[i]->getSphereCenters());
1663  }
1664  else
1665  {
1666  collision_spheres_1 =
1667  &(gsr->attached_body_decompositions_[i - gsr->dfce_->link_names_.size()]->getCollisionSpheres());
1668  sphere_centers_1 = &(gsr->attached_body_decompositions_[i - gsr->dfce_->link_names_.size()]->getSphereCenters());
1669  }
1670 
1671  bool coll = getCollisionSphereGradients(env_distance_field.get(), *collision_spheres_1, *sphere_centers_1,
1672  gsr->gradients_[i], ENVIRONMENT, collision_tolerance_, false,
1673  max_propogation_distance_, false);
1674  if (coll)
1675  {
1676  in_collision = true;
1677  }
1678  }
1679  return in_collision;
1680 }
1681 
1682 void CollisionEnvDistanceField::setWorld(const WorldPtr& world)
1683 {
1684  if (world == getWorld())
1685  return;
1686 
1687  // turn off notifications about old world
1688  getWorld()->removeObserver(observer_handle_);
1689 
1690  // clear out objects from old world
1691  distance_field_cache_entry_world_->distance_field_->reset();
1692 
1693  CollisionEnv::setWorld(world);
1694 
1695  // request notifications about changes to new world
1696  observer_handle_ = getWorld()->addObserver(
1697  [this](const World::ObjectConstPtr& object, World::Action action) { return notifyObjectChange(object, action); });
1698 
1699  // get notifications any objects already in the new world
1700  getWorld()->notifyObserverAllObjects(observer_handle_, World::CREATE);
1701 }
1702 
1704 {
1705  rclcpp::Clock clock;
1706  rclcpp::Time start_time = clock.now();
1707 
1708  EigenSTL::vector_Vector3d add_points;
1709  EigenSTL::vector_Vector3d subtract_points;
1710  updateDistanceObject(obj->id_, distance_field_cache_entry_world_, add_points, subtract_points);
1711 
1712  if (action == World::DESTROY)
1713  {
1714  distance_field_cache_entry_world_->distance_field_->removePointsFromField(subtract_points);
1715  }
1717  {
1718  distance_field_cache_entry_world_->distance_field_->removePointsFromField(subtract_points);
1719  distance_field_cache_entry_world_->distance_field_->addPointsToField(add_points);
1720  }
1721  else
1722  {
1723  distance_field_cache_entry_world_->distance_field_->addPointsToField(add_points);
1724  }
1725 
1726  RCLCPP_DEBUG(logger_, "Modifying object %s took %lf s", obj->id_.c_str(), (clock.now() - start_time).seconds());
1727 }
1728 
1729 void CollisionEnvDistanceField::updateDistanceObject(const std::string& id, DistanceFieldCacheEntryWorldPtr& dfce,
1730  EigenSTL::vector_Vector3d& add_points,
1731  EigenSTL::vector_Vector3d& subtract_points)
1732 {
1733  std::map<std::string, std::vector<PosedBodyPointDecompositionPtr>>::iterator cur_it =
1734  dfce->posed_body_point_decompositions_.find(id);
1735  if (cur_it != dfce->posed_body_point_decompositions_.end())
1736  {
1737  for (collision_detection::PosedBodyPointDecompositionPtr& posed_body_point_decomposition : cur_it->second)
1738  {
1739  subtract_points.insert(subtract_points.end(), posed_body_point_decomposition->getCollisionPoints().begin(),
1740  posed_body_point_decomposition->getCollisionPoints().end());
1741  }
1742  }
1743 
1744  World::ObjectConstPtr object = getWorld()->getObject(id);
1745  if (object)
1746  {
1747  RCLCPP_DEBUG(logger_, "Updating/Adding Object '%s' with %lu shapes to CollisionEnvDistanceField",
1748  object->id_.c_str(), object->shapes_.size());
1749  std::vector<PosedBodyPointDecompositionPtr> shape_points;
1750  for (unsigned int i{ 0 }; i < object->shapes_.size(); ++i)
1751  {
1752  shapes::ShapeConstPtr shape = object->shapes_[i];
1753  if (shape->type == shapes::OCTREE)
1754  {
1755  const shapes::OcTree* octree_shape = static_cast<const shapes::OcTree*>(shape.get());
1756  std::shared_ptr<const octomap::OcTree> octree = octree_shape->octree;
1757 
1758  shape_points.push_back(std::make_shared<PosedBodyPointDecomposition>(octree));
1759  }
1760  else
1761  {
1762  BodyDecompositionConstPtr bd = getBodyDecompositionCacheEntry(shape, resolution_);
1763  shape_points.push_back(
1764  std::make_shared<PosedBodyPointDecomposition>(bd, getWorld()->getGlobalShapeTransform(id, i)));
1765  }
1766 
1767  add_points.insert(add_points.end(), shape_points.back()->getCollisionPoints().begin(),
1768  shape_points.back()->getCollisionPoints().end());
1769  }
1770 
1771  dfce->posed_body_point_decompositions_[id] = shape_points;
1772  }
1773  else
1774  {
1775  RCLCPP_DEBUG(logger_, "Removing Object '%s' from CollisionEnvDistanceField", id.c_str());
1776  dfce->posed_body_point_decompositions_.erase(id);
1777  }
1778 }
1779 
1780 CollisionEnvDistanceField::DistanceFieldCacheEntryWorldPtr
1782 {
1783  DistanceFieldCacheEntryWorldPtr dfce = std::make_shared<DistanceFieldCacheEntryWorld>();
1784  dfce->distance_field_ = std::make_shared<distance_field::PropagationDistanceField>(
1785  size_.x(), size_.y(), size_.z(), resolution_, origin_.x() - 0.5 * size_.x(), origin_.y() - 0.5 * size_.y(),
1787 
1788  EigenSTL::vector_Vector3d add_points;
1789  EigenSTL::vector_Vector3d subtract_points;
1790  for (const std::pair<const std::string, ObjectPtr>& object : *getWorld())
1791  {
1792  updateDistanceObject(object.first, dfce, add_points, subtract_points);
1793  }
1794  dfce->distance_field_->addPointsToField(add_points);
1795  return dfce;
1796 }
1797 } // namespace collision_detection
Definition of a structure for the allowed collision matrix. All elements in the collision world are r...
bool getEntry(const std::string &name1, const std::string &name2, AllowedCollision::Type &allowed_collision_type) const
Get the type of the allowed collision between two elements. Return true if the entry is included in t...
std::size_t getSize() const
Get the size of the allowed collision matrix (number of specified entries)
DistanceFieldCacheEntryWorldPtr distance_field_cache_entry_world_
void checkRobotCollision(const CollisionRequest &req, CollisionResult &res, const moveit::core::RobotState &state) const override
Check whether the robot model is in collision with the world. Any collisions between a robot link and...
DistanceFieldCacheEntryConstPtr getDistanceFieldCacheEntry(const std::string &group_name, const moveit::core::RobotState &state, const collision_detection::AllowedCollisionMatrix *acm) const
DistanceFieldCacheEntryPtr generateDistanceFieldCacheEntry(const std::string &group_name, const moveit::core::RobotState &state, const collision_detection::AllowedCollisionMatrix *acm, bool generate_distance_field) const
std::map< std::string, std::map< std::string, bool > > in_group_update_map_
void initialize(const std::map< std::string, std::vector< CollisionSphere >> &link_body_decompositions, const Eigen::Vector3d &size, const Eigen::Vector3d &origin, bool use_signed_distance_field, double resolution, double collision_tolerance, double max_propogation_distance)
EIGEN_MAKE_ALIGNED_OPERATOR_NEW CollisionEnvDistanceField(const moveit::core::RobotModelConstPtr &robot_model, const std::map< std::string, std::vector< CollisionSphere >> &link_body_decompositions=std::map< std::string, std::vector< CollisionSphere >>(), double size_x=DEFAULT_SIZE_X, double size_y=DEFAULT_SIZE_Y, double size_z=DEFAULT_SIZE_Z, const Eigen::Vector3d &origin=Eigen::Vector3d(0, 0, 0), bool use_signed_distance_field=DEFAULT_USE_SIGNED_DISTANCE_FIELD, double resolution=DEFAULT_RESOLUTION, double collision_tolerance=DEFAULT_COLLISION_TOLERANCE, double max_propogation_distance=DEFAULT_MAX_PROPOGATION_DISTANCE, double padding=0.0, double scale=1.0)
DistanceFieldCacheEntryWorldPtr generateDistanceFieldCacheEntryWorld()
bool getSelfCollisions(const collision_detection::CollisionRequest &req, collision_detection::CollisionResult &res, GroupStateRepresentationPtr &gsr) const
bool compareCacheEntryToAllowedCollisionMatrix(const DistanceFieldCacheEntryConstPtr &dfce, const collision_detection::AllowedCollisionMatrix &acm) const
std::map< std::string, unsigned int > link_body_decomposition_index_map_
bool getIntraGroupCollisions(const collision_detection::CollisionRequest &req, collision_detection::CollisionResult &res, GroupStateRepresentationPtr &gsr) const
void checkSelfCollisionHelper(const collision_detection::CollisionRequest &req, collision_detection::CollisionResult &res, const moveit::core::RobotState &state, const collision_detection::AllowedCollisionMatrix *acm, GroupStateRepresentationPtr &gsr) const
void generateCollisionCheckingStructures(const std::string &group_name, const moveit::core::RobotState &state, const collision_detection::AllowedCollisionMatrix *acm, GroupStateRepresentationPtr &gsr, bool generate_distance_field) const
bool compareCacheEntryToState(const DistanceFieldCacheEntryConstPtr &dfce, const moveit::core::RobotState &state) const
std::vector< BodyDecompositionConstPtr > link_body_decomposition_vector_
bool getEnvironmentProximityGradients(const distance_field::DistanceFieldConstPtr &env_distance_field, GroupStateRepresentationPtr &gsr) const
std::map< std::string, GroupStateRepresentationPtr > pregenerated_group_state_representation_map_
bool getSelfProximityGradients(GroupStateRepresentationPtr &gsr) const
bool getEnvironmentCollisions(const CollisionRequest &req, CollisionResult &res, const distance_field::DistanceFieldConstPtr &env_distance_field, GroupStateRepresentationPtr &gsr) const
void checkCollision(const CollisionRequest &req, CollisionResult &res, const moveit::core::RobotState &state) const override
Check whether the robot model is in collision with itself or the world at a particular state....
PosedBodySphereDecompositionPtr getPosedLinkBodySphereDecomposition(const moveit::core::LinkModel *ls, unsigned int ind) const
void updateGroupStateRepresentationState(const moveit::core::RobotState &state, GroupStateRepresentationPtr &gsr) const
bool getIntraGroupProximityGradients(GroupStateRepresentationPtr &gsr) const
void updateDistanceObject(const std::string &id, CollisionEnvDistanceField::DistanceFieldCacheEntryWorldPtr &dfce, EigenSTL::vector_Vector3d &add_points, EigenSTL::vector_Vector3d &subtract_points)
void getAllCollisions(const CollisionRequest &req, CollisionResult &res, const moveit::core::RobotState &state, const AllowedCollisionMatrix *acm, GroupStateRepresentationPtr &gsr) const
PosedBodyPointDecompositionPtr getPosedLinkBodyPointDecomposition(const moveit::core::LinkModel *ls) const
void notifyObjectChange(const ObjectConstPtr &obj, World::Action action)
void createCollisionModelMarker(const moveit::core::RobotState &state, visualization_msgs::msg::MarkerArray &model_markers) const
void checkSelfCollision(const collision_detection::CollisionRequest &req, collision_detection::CollisionResult &res, const moveit::core::RobotState &state) const override
Check for robot self collision. Any collision between any pair of links is checked for,...
void getGroupStateRepresentation(const DistanceFieldCacheEntryConstPtr &dfce, const moveit::core::RobotState &state, GroupStateRepresentationPtr &gsr) const
void getCollisionGradients(const CollisionRequest &req, CollisionResult &res, const moveit::core::RobotState &state, const AllowedCollisionMatrix *acm, GroupStateRepresentationPtr &gsr) const
Provides the interface to the individual collision checking libraries.
Definition: collision_env.h:52
virtual void setWorld(const WorldPtr &world)
moveit::core::RobotModelConstPtr robot_model_
The kinematic model corresponding to this collision model.
void setPadding(double padding)
Set the link padding (for every link)
World::ObjectConstPtr ObjectConstPtr
const std::map< std::string, double > & getLinkPadding() const
Get the link paddings as a map (from link names to padding value)
Represents an action that occurred on an object in the world. Several bits may be set indicating seve...
Definition: world.h:265
Object defining bodies that can be attached to robot links.
Definition: attached_body.h:58
const EigenSTL::vector_Isometry3d & getGlobalCollisionBodyTransforms() const
Get the global transforms (in world frame) for the collision bodies. The returned transforms are guar...
const std::vector< shapes::ShapeConstPtr > & getShapes() const
Get the shapes that make up this attached body.
const std::vector< std::string > & getUpdatedLinkModelNames() const
Get the names of the links returned by getUpdatedLinkModels()
const std::vector< const LinkModel * > & getUpdatedLinkModels() const
Get the names of the links that are to be updated when the state of this group changes....
A joint from the robot. Models the transform that this joint applies in the kinematic chain....
Definition: joint_model.h:117
const std::string & getName() const
Get the name of the joint.
Definition: joint_model.h:145
A link from the robot. Contains the constant transform applied to the link and its geometry.
Definition: link_model.h:72
const std::vector< shapes::ShapeConstPtr > & getShapes() const
Get shape associated to the collision geometry for this link.
Definition: link_model.h:176
const JointModel * getParentJointModel() const
Get the joint model whose child this link is. There will always be a parent joint.
Definition: link_model.h:108
const std::string & getName() const
The name of this link.
Definition: link_model.h:86
Representation of a robot's state. This includes position, velocity, acceleration and effort.
Definition: robot_state.h:90
const LinkModel * getLinkModel(const std::string &link) const
Get the model of a particular link.
Definition: robot_state.h:122
const Eigen::Isometry3d & getGlobalLinkTransform(const std::string &link_name)
Get the link transform w.r.t. the root link (model frame) of the RobotModel. This is typically the ro...
Definition: robot_state.h:1246
void getAttachedBodies(std::vector< const AttachedBody * > &attached_bodies) const
Get all bodies attached to the model corresponding to this state.
const JointModelGroup * getJointModelGroup(const std::string &group) const
Get the model of a particular joint group.
Definition: robot_state.h:134
void updateLinkTransforms()
Update the reference frame transforms for links. This call is needed before using the transforms of l...
const Eigen::Isometry3d & getFrameTransform(const std::string &frame_id, bool *frame_found=nullptr)
Get the transformation matrix from the model frame (root of model) to the frame identified by frame_i...
double getVariablePosition(const std::string &variable) const
Get the position of a particular variable. An exception is thrown if the variable is not known.
Definition: robot_state.h:207
const AttachedBody * getAttachedBody(const std::string &name) const
Get the attached body named name. Return nullptr if not found.
std::size_t getVariableCount() const
Get the number of variables that make up this state.
Definition: robot_state.h:110
const std::vector< std::string > & getVariableNames() const
Get the names of the variables that make up this state, in the order they are stored in memory.
Definition: robot_state.h:116
@ NEVER
Collisions between the pair of bodies is never ok, i.e., if two bodies are in contact in a particular...
@ ALWAYS
Collisions between a particular pair of bodies does not imply that the robot configuration is in coll...
@ ROBOT_LINK
A link on the robot.
@ ROBOT_ATTACHED
A body attached to a robot link.
@ WORLD_OBJECT
A body in the environment.
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)
PosedBodySphereDecompositionVectorPtr getAttachedBodySphereDecomposition(const moveit::core::AttachedBody *att, double resolution)
BodyDecompositionConstPtr getBodyDecompositionCacheEntry(const shapes::ShapeConstPtr &shape, double resolution)
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)
PosedBodyPointDecompositionVectorPtr getAttachedBodyPointDecomposition(const moveit::core::AttachedBody *att, double resolution)
Vec3fX< details::Vec3Data< double > > Vector3d
Definition: fcl_compat.h:89
Main namespace for MoveIt.
Definition: exceptions.h:43
Representation of a collision checking request.
std::string group_name
The group name to check collisions for (optional; if empty, assume the complete robot)....
bool contacts
If true, compute contacts. Otherwise only a binary collision yes/no is reported.
std::size_t max_contacts
Overall maximum number of contacts to compute.
std::size_t max_contacts_per_pair
Maximum number of contacts to compute per pair of bodies (multiple bodies may be in contact at differ...
Representation of a collision checking result.
bool collision
True if collision was found, false otherwise.
std::size_t contact_count
Number of contacts returned.
Definition of a contact point.
std::string body_name_2
The id of the second body involved in the contact.
std::string body_name_1
The id of the first body involved in the contact.
BodyType body_type_1
The type of the first body involved in the contact.
BodyType body_type_2
The type of the second body involved in the contact.
EIGEN_MAKE_ALIGNED_OPERATOR_NEW Eigen::Vector3d pos
contact position