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