moveit2
The MoveIt Motion Planning Framework for ROS 2.
bullet_utils.h
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD-2-Clause)
3  *
4  * Copyright (c) 2017, Southwest Research Institute
5  * Copyright (c) 2013, John Schulman
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *********************************************************************/
32 
33 /* Authors: John Schulman, Levi Armstrong */
34 
35 #pragma once
36 
37 #include <btBulletCollisionCommon.h>
38 #include <geometric_shapes/mesh_operations.h>
39 #include <rclcpp/logging.hpp>
40 
46 
48 {
49 #define METERS
50 
51 const btScalar BULLET_MARGIN = 0.0f;
52 const btScalar BULLET_SUPPORT_FUNC_TOLERANCE = 0.01f METERS;
53 const btScalar BULLET_LENGTH_TOLERANCE = 0.001f METERS;
54 const btScalar BULLET_EPSILON = 1e-3f; // numerical precision limit
55 const btScalar BULLET_DEFAULT_CONTACT_DISTANCE = 0.00f; // All pairs closer than this distance get reported
57 
59 
61 bool acmCheck(const std::string& body_1, const std::string& body_2,
63 
65 inline btVector3 convertEigenToBt(const Eigen::Vector3d& v)
66 {
67  return btVector3(static_cast<btScalar>(v[0]), static_cast<btScalar>(v[1]), static_cast<btScalar>(v[2]));
68 }
69 
71 inline Eigen::Vector3d convertBtToEigen(const btVector3& v)
72 {
73  return Eigen::Vector3d(static_cast<double>(v.x()), static_cast<double>(v.y()), static_cast<double>(v.z()));
74 }
75 
77 inline btQuaternion convertEigenToBt(const Eigen::Quaterniond& q)
78 {
79  return btQuaternion(static_cast<btScalar>(q.x()), static_cast<btScalar>(q.y()), static_cast<btScalar>(q.z()),
80  static_cast<btScalar>(q.w()));
81 }
82 
84 inline btMatrix3x3 convertEigenToBt(const Eigen::Matrix3d& r)
85 {
86  return btMatrix3x3(static_cast<btScalar>(r(0, 0)), static_cast<btScalar>(r(0, 1)), static_cast<btScalar>(r(0, 2)),
87  static_cast<btScalar>(r(1, 0)), static_cast<btScalar>(r(1, 1)), static_cast<btScalar>(r(1, 2)),
88  static_cast<btScalar>(r(2, 0)), static_cast<btScalar>(r(2, 1)), static_cast<btScalar>(r(2, 2)));
89 }
90 
92 inline btTransform convertEigenToBt(const Eigen::Isometry3d& t)
93 {
94  const Eigen::Matrix3d& rot = t.matrix().block<3, 3>(0, 0);
95  const Eigen::Vector3d& tran = t.translation();
96 
97  btMatrix3x3 mat = convertEigenToBt(rot);
98  btVector3 translation = convertEigenToBt(tran);
99 
100  return btTransform(mat, translation);
101 }
102 
109 class CollisionObjectWrapper : public btCollisionObject
110 {
111 public:
113 
117  CollisionObjectWrapper(const std::string& name, const collision_detection::BodyType& type_id,
118  const std::vector<shapes::ShapeConstPtr>& shapes,
119  const AlignedVector<Eigen::Isometry3d>& shape_poses,
120  const std::vector<CollisionObjectType>& collision_object_types, bool active = true);
121 
125  CollisionObjectWrapper(const std::string& name, const collision_detection::BodyType& type_id,
126  const std::vector<shapes::ShapeConstPtr>& shapes,
127  const AlignedVector<Eigen::Isometry3d>& shape_poses,
128  const std::vector<CollisionObjectType>& collision_object_types,
129  const std::set<std::string>& touch_links);
130 
133 
136 
138  bool m_enabled{ true };
139 
141  std::set<std::string> m_touch_links;
142 
144  const std::string& getName() const
145  {
146  return m_name;
147  }
148 
151  {
152  return m_type_id;
153  }
154 
157  bool sameObject(const CollisionObjectWrapper& other) const
158  {
159  return m_name == other.m_name && m_type_id == other.m_type_id && m_shapes.size() == other.m_shapes.size() &&
160  m_shape_poses.size() == other.m_shape_poses.size() &&
161  std::equal(m_shapes.begin(), m_shapes.end(), other.m_shapes.begin()) &&
162  std::equal(m_shape_poses.begin(), m_shape_poses.end(), other.m_shape_poses.begin(),
163  [](const Eigen::Isometry3d& t1, const Eigen::Isometry3d& t2) { return t1.isApprox(t2); });
164  }
165 
169  void getAABB(btVector3& aabb_min, btVector3& aabb_max) const
170  {
171  getCollisionShape()->getAabb(getWorldTransform(), aabb_min, aabb_max);
172  const btScalar& distance = getContactProcessingThreshold();
173  // note that bullet expands each AABB by 4 cm
174  btVector3 contact_threshold(distance, distance, distance);
175  aabb_min -= contact_threshold;
176  aabb_max += contact_threshold;
177  }
178 
181  std::shared_ptr<CollisionObjectWrapper> clone()
182  {
183  std::shared_ptr<CollisionObjectWrapper> clone_cow(
185  clone_cow->setCollisionShape(getCollisionShape());
186  clone_cow->setWorldTransform(getWorldTransform());
187  clone_cow->m_collisionFilterGroup = m_collisionFilterGroup;
188  clone_cow->m_collisionFilterMask = m_collisionFilterMask;
189  clone_cow->m_enabled = m_enabled;
190  clone_cow->setBroadphaseHandle(nullptr);
191  clone_cow->m_touch_links = m_touch_links;
192  clone_cow->setContactProcessingThreshold(this->getContactProcessingThreshold());
193  return clone_cow;
194  }
195 
197  template <class T>
198  void manage(T* t)
199  {
200  m_data.push_back(std::shared_ptr<T>(t));
201  }
202 
204  template <class T>
205  void manage(std::shared_ptr<T> t)
206  {
207  m_data.push_back(t);
208  }
209 
210 protected:
212  CollisionObjectWrapper(const std::string& name, const collision_detection::BodyType& type_id,
213  const std::vector<shapes::ShapeConstPtr>& shapes,
214  const AlignedVector<Eigen::Isometry3d>& shape_poses,
215  const std::vector<CollisionObjectType>& collision_object_types,
216  const std::vector<std::shared_ptr<void>>& data);
217 
219  std::string m_name;
220 
222 
224  std::vector<shapes::ShapeConstPtr> m_shapes;
225 
228 
230  std::vector<CollisionObjectType> m_collision_object_types;
231 
233  std::vector<std::shared_ptr<void>> m_data;
234 };
235 
240 struct CastHullShape : public btConvexShape
241 {
242 public:
244  btConvexShape* m_shape;
245 
247  btTransform m_shape_transform;
248 
249  CastHullShape(btConvexShape* shape, const btTransform& t01) : m_shape(shape), m_shape_transform(t01)
250  {
251  m_shapeType = CUSTOM_CONVEX_SHAPE_TYPE;
252  }
253 
254  void updateCastTransform(const btTransform& cast_transform)
255  {
256  m_shape_transform = cast_transform;
257  }
258 
260  btVector3 localGetSupportingVertex(const btVector3& vec) const override
261  {
262  btVector3 support_vector_0 = m_shape->localGetSupportingVertex(vec);
263  btVector3 support_vector_1 =
264  m_shape_transform * m_shape->localGetSupportingVertex(vec * m_shape_transform.getBasis());
265  return (vec.dot(support_vector_0) > vec.dot(support_vector_1)) ? support_vector_0 : support_vector_1;
266  }
267 
268  void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* /*vectors*/,
269  btVector3* /*supportVerticesOut*/,
270  int /*numVectors*/) const override
271  {
272  throw std::runtime_error("not implemented");
273  }
274 
278  void getAabb(const btTransform& transform_world, btVector3& aabbMin, btVector3& aabbMax) const override
279  {
280  m_shape->getAabb(transform_world, aabbMin, aabbMax);
281  btVector3 min1, max1;
282  m_shape->getAabb(transform_world * m_shape_transform, min1, max1);
283  aabbMin.setMin(min1);
284  aabbMax.setMax(max1);
285  }
286 
287  void getAabbSlow(const btTransform& /*t*/, btVector3& /*aabbMin*/, btVector3& /*aabbMax*/) const override
288  {
289  throw std::runtime_error("shouldn't happen");
290  }
291 
292  void setLocalScaling(const btVector3& /*scaling*/) override
293  {
294  }
295 
296  const btVector3& getLocalScaling() const override
297  {
298  static btVector3 out(1, 1, 1);
299  return out;
300  }
301 
302  void setMargin(btScalar /*margin*/) override
303  {
304  }
305 
306  btScalar getMargin() const override
307  {
308  return 0;
309  }
310 
312  {
313  return 0;
314  }
315 
316  void getPreferredPenetrationDirection(int /*index*/, btVector3& /*penetrationVector*/) const override
317  {
318  throw std::runtime_error("not implemented");
319  }
320 
321  void calculateLocalInertia(btScalar /*mass*/, btVector3& /*inertia*/) const override
322  {
323  throw std::runtime_error("not implemented");
324  }
325 
326  const char* getName() const override
327  {
328  return "CastHull";
329  }
330 
331  btVector3 localGetSupportingVertexWithoutMargin(const btVector3& v) const override
332  {
333  return localGetSupportingVertex(v);
334  }
335 };
336 
345 inline void getAverageSupport(const btConvexShape* shape, const btVector3& localNormal, float& outsupport,
346  btVector3& outpt)
347 {
348  btVector3 pt_sum(0, 0, 0);
349  float pt_count = 0;
350  float max_support = -1000;
351 
352  const btPolyhedralConvexShape* pshape = dynamic_cast<const btPolyhedralConvexShape*>(shape);
353  if (pshape)
354  {
355  int n_pts = pshape->getNumVertices();
356 
357  for (int i = 0; i < n_pts; ++i)
358  {
359  btVector3 pt;
360  pshape->getVertex(i, pt);
361 
362  float sup = pt.dot(localNormal);
363  if (sup > max_support + BULLET_EPSILON)
364  {
365  pt_count = 1;
366  pt_sum = pt;
367  max_support = sup;
368  }
369  else if (sup < max_support - BULLET_EPSILON) {}
370  else
371  {
372  pt_count += 1;
373  pt_sum += pt;
374  }
375  }
376  outsupport = max_support;
377  outpt = pt_sum / pt_count;
378  }
379  else
380  {
381  outpt = shape->localGetSupportingVertexWithoutMargin(localNormal);
382  outsupport = localNormal.dot(outpt);
383  }
384 }
385 
387 inline btScalar addDiscreteSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,
388  const btCollisionObjectWrapper* colObj1Wrap, ContactTestData& collisions)
389 {
390  assert(dynamic_cast<const CollisionObjectWrapper*>(colObj0Wrap->getCollisionObject()) != nullptr);
391  assert(dynamic_cast<const CollisionObjectWrapper*>(colObj1Wrap->getCollisionObject()) != nullptr);
392  const CollisionObjectWrapper* cd0 = static_cast<const CollisionObjectWrapper*>(colObj0Wrap->getCollisionObject());
393  const CollisionObjectWrapper* cd1 = static_cast<const CollisionObjectWrapper*>(colObj1Wrap->getCollisionObject());
394 
395  std::pair<std::string, std::string> pc = getObjectPairKey(cd0->getName(), cd1->getName());
396 
397  const auto& it = collisions.res.contacts.find(pc);
398  bool found = (it != collisions.res.contacts.end());
399 
401  contact.body_name_1 = cd0->getName();
402  contact.body_name_2 = cd1->getName();
403  contact.depth = static_cast<double>(cp.m_distance1);
404  contact.normal = convertBtToEigen(-1 * cp.m_normalWorldOnB);
405  contact.pos = convertBtToEigen(cp.m_positionWorldOnA);
406  contact.nearest_points[0] = contact.pos;
407  contact.nearest_points[1] = convertBtToEigen(cp.m_positionWorldOnB);
408 
409  contact.body_type_1 = cd0->getTypeID();
410  contact.body_type_2 = cd1->getTypeID();
411 
412  if (!processResult(collisions, contact, pc, found))
413  {
414  return 0;
415  }
416 
417  return 1;
418 }
419 
420 inline btScalar addCastSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap, int /*index0*/,
421  const btCollisionObjectWrapper* colObj1Wrap, int /*index1*/,
422  ContactTestData& collisions)
423 {
424  assert(dynamic_cast<const CollisionObjectWrapper*>(colObj0Wrap->getCollisionObject()) != nullptr);
425  assert(dynamic_cast<const CollisionObjectWrapper*>(colObj1Wrap->getCollisionObject()) != nullptr);
426 
427  const CollisionObjectWrapper* cd0 = static_cast<const CollisionObjectWrapper*>(colObj0Wrap->getCollisionObject());
428  const CollisionObjectWrapper* cd1 = static_cast<const CollisionObjectWrapper*>(colObj1Wrap->getCollisionObject());
429 
430  std::pair<std::string, std::string> pc = getObjectPairKey(cd0->getName(), cd1->getName());
431 
432  const auto& it = collisions.res.contacts.find(pc);
433  bool found = (it != collisions.res.contacts.end());
434 
436  contact.body_name_1 = cd0->getName();
437  contact.body_name_2 = cd1->getName();
438  contact.depth = static_cast<double>(cp.m_distance1);
439  contact.normal = convertBtToEigen(-1 * cp.m_normalWorldOnB);
440  contact.pos = convertBtToEigen(cp.m_positionWorldOnA);
441 
442  contact.body_type_1 = cd0->getTypeID();
443  contact.body_type_2 = cd1->getTypeID();
444 
445  collision_detection::Contact* col = processResult(collisions, contact, pc, found);
446 
447  if (!col)
448  {
449  return 0;
450  }
451 
452  assert(!((cd0->m_collisionFilterGroup == btBroadphaseProxy::KinematicFilter) &&
453  (cd1->m_collisionFilterGroup == btBroadphaseProxy::KinematicFilter)));
454 
455  bool cast_shape_is_first = cd0->m_collisionFilterGroup == btBroadphaseProxy::KinematicFilter;
456 
457  btVector3 normal_world_from_cast = (cast_shape_is_first ? -1 : 1) * cp.m_normalWorldOnB;
458  const btCollisionObjectWrapper* first_col_obj_wrap = (cast_shape_is_first ? colObj0Wrap : colObj1Wrap);
459 
460  // we want the contact information of the non-casted object come first, therefore swap values
461  if (cast_shape_is_first)
462  {
463  std::swap(col->nearest_points[0], col->nearest_points[1]);
464  contact.pos = convertBtToEigen(cp.m_positionWorldOnB);
465  std::swap(col->body_name_1, col->body_name_2);
466  std::swap(col->body_type_1, col->body_type_2);
467  col->normal *= -1;
468  }
469 
470  btTransform tf_world0, tf_world1;
471  const CastHullShape* shape = static_cast<const CastHullShape*>(first_col_obj_wrap->getCollisionShape());
472 
473  tf_world0 = first_col_obj_wrap->getWorldTransform();
474  tf_world1 = first_col_obj_wrap->getWorldTransform() * shape->m_shape_transform;
475 
476  // transform normals into pose local coordinate systems
477  btVector3 normal_local0 = normal_world_from_cast * tf_world0.getBasis();
478  btVector3 normal_local1 = normal_world_from_cast * tf_world1.getBasis();
479 
480  btVector3 pt_local0;
481  float localsup0;
482  getAverageSupport(shape->m_shape, normal_local0, localsup0, pt_local0);
483  btVector3 pt_world0 = tf_world0 * pt_local0;
484  btVector3 pt_local1;
485  float localsup1;
486  getAverageSupport(shape->m_shape, normal_local1, localsup1, pt_local1);
487  btVector3 pt_world1 = tf_world1 * pt_local1;
488 
489  float sup0 = normal_world_from_cast.dot(pt_world0);
490  float sup1 = normal_world_from_cast.dot(pt_world1);
491 
492  // TODO: this section is potentially problematic. think hard about the math
493  if (sup0 - sup1 > BULLET_SUPPORT_FUNC_TOLERANCE)
494  {
495  col->percent_interpolation = 0;
496  }
497  else if (sup1 - sup0 > BULLET_SUPPORT_FUNC_TOLERANCE)
498  {
499  col->percent_interpolation = 1;
500  }
501  else
502  {
503  const btVector3& pt_on_cast = cast_shape_is_first ? cp.m_positionWorldOnA : cp.m_positionWorldOnB;
504  float l0c = (pt_on_cast - pt_world0).length();
505  float l1c = (pt_on_cast - pt_world1).length();
506 
507  if (l0c + l1c < BULLET_LENGTH_TOLERANCE)
508  {
509  col->percent_interpolation = .5;
510  }
511  else
512  {
513  col->percent_interpolation = static_cast<double>(l0c / (l0c + l1c));
514  }
515  }
516 
517  return 1;
518 }
519 
521 inline bool isOnlyKinematic(const CollisionObjectWrapper* cow0, const CollisionObjectWrapper* cow1)
522 {
523  return cow0->m_collisionFilterGroup == btBroadphaseProxy::KinematicFilter &&
524  cow1->m_collisionFilterGroup == btBroadphaseProxy::KinematicFilter;
525 }
526 
532 {
536 
538  bool self_;
539 
541  bool cast_{ false };
542 
543  BroadphaseContactResultCallback(ContactTestData& collisions, double contact_distance,
544  const collision_detection::AllowedCollisionMatrix* acm, bool self, bool cast = false)
545  : collisions_(collisions), contact_distance_(contact_distance), acm_(acm), self_(self), cast_(cast)
546  {
547  }
548 
550 
553  // TODO: Add check for two objects attached to the same link
554  bool needsCollision(const CollisionObjectWrapper* cow0, const CollisionObjectWrapper* cow1) const
555  {
556  if (cast_)
557  {
558  return !collisions_.done && !isOnlyKinematic(cow0, cow1) && !acmCheck(cow0->getName(), cow1->getName(), acm_);
559  }
560  else
561  {
562  return !collisions_.done && (self_ ? isOnlyKinematic(cow0, cow1) : !isOnlyKinematic(cow0, cow1)) &&
563  !acmCheck(cow0->getName(), cow1->getName(), acm_);
564  }
565  }
566 
568  btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap, int partId0, int index0,
569  const btCollisionObjectWrapper* colObj1Wrap, int partId1, int index1);
570 };
571 
572 struct TesseractBroadphaseBridgedManifoldResult : public btManifoldResult
573 {
575 
576  TesseractBroadphaseBridgedManifoldResult(const btCollisionObjectWrapper* obj0Wrap,
577  const btCollisionObjectWrapper* obj1Wrap,
578  BroadphaseContactResultCallback& result_callback)
579  : btManifoldResult(obj0Wrap, obj1Wrap), result_callback_(result_callback)
580  {
581  }
582 
583  void addContactPoint(const btVector3& normalOnBInWorld, const btVector3& pointInWorld, btScalar depth) override
584  {
586  depth > static_cast<btScalar>(result_callback_.contact_distance_))
587  {
588  return;
589  }
590 
591  bool is_swapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject();
592  btVector3 point_a = pointInWorld + normalOnBInWorld * depth;
593  btVector3 local_a;
594  btVector3 local_b;
595  if (is_swapped)
596  {
597  local_a = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(point_a);
598  local_b = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
599  }
600  else
601  {
602  local_a = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(point_a);
603  local_b = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
604  }
605 
606  btManifoldPoint new_pt(local_a, local_b, normalOnBInWorld, depth);
607  new_pt.m_positionWorldOnA = point_a;
608  new_pt.m_positionWorldOnB = pointInWorld;
609 
610  // BP mod, store contact triangles.
611  if (is_swapped)
612  {
613  new_pt.m_partId0 = m_partId1;
614  new_pt.m_partId1 = m_partId0;
615  new_pt.m_index0 = m_index1;
616  new_pt.m_index1 = m_index0;
617  }
618  else
619  {
620  new_pt.m_partId0 = m_partId0;
621  new_pt.m_partId1 = m_partId1;
622  new_pt.m_index0 = m_index0;
623  new_pt.m_index1 = m_index1;
624  }
625 
626  // experimental feature info, for per-triangle material etc.
627  const btCollisionObjectWrapper* obj0_wrap = is_swapped ? m_body1Wrap : m_body0Wrap;
628  const btCollisionObjectWrapper* obj1_wrap = is_swapped ? m_body0Wrap : m_body1Wrap;
629  result_callback_.addSingleResult(new_pt, obj0_wrap, new_pt.m_partId0, new_pt.m_index0, obj1_wrap, new_pt.m_partId1,
630  new_pt.m_index1);
631  }
632 };
633 
638 class TesseractCollisionPairCallback : public btOverlapCallback
639 {
640  const btDispatcherInfo& dispatch_info_;
641  btCollisionDispatcher* dispatcher_;
642 
644  BroadphaseContactResultCallback& results_callback_;
645 
646 public:
647  TesseractCollisionPairCallback(const btDispatcherInfo& dispatchInfo, btCollisionDispatcher* dispatcher,
648  BroadphaseContactResultCallback& results_callback)
649  : dispatch_info_(dispatchInfo), dispatcher_(dispatcher), results_callback_(results_callback)
650  {
651  }
652 
653  ~TesseractCollisionPairCallback() override = default;
654 
655  bool processOverlap(btBroadphasePair& pair) override;
656 };
657 
659 btCollisionShape* createShapePrimitive(const shapes::ShapeConstPtr& geom,
660  const CollisionObjectType& collision_object_type, CollisionObjectWrapper* cow);
661 
670 void updateCollisionObjectFilters(const std::vector<std::string>& active, CollisionObjectWrapper& cow);
671 
672 CollisionObjectWrapperPtr makeCastCollisionObject(const CollisionObjectWrapperPtr& cow);
673 
678 inline void updateBroadphaseAABB(const CollisionObjectWrapperPtr& cow,
679  const std::unique_ptr<btBroadphaseInterface>& broadphase,
680  const std::unique_ptr<btCollisionDispatcher>& dispatcher)
681 {
682  btVector3 aabb_min, aabb_max;
683  cow->getAABB(aabb_min, aabb_max);
684 
685  assert(cow->getBroadphaseHandle() != nullptr);
686  broadphase->setAabb(cow->getBroadphaseHandle(), aabb_min, aabb_max, dispatcher.get());
687 }
688 
693 inline void removeCollisionObjectFromBroadphase(const CollisionObjectWrapperPtr& cow,
694  const std::unique_ptr<btBroadphaseInterface>& broadphase,
695  const std::unique_ptr<btCollisionDispatcher>& dispatcher)
696 {
697  btBroadphaseProxy* bp = cow->getBroadphaseHandle();
698  if (bp)
699  {
700  // only clear the cached algorithms
701  broadphase->getOverlappingPairCache()->cleanProxyFromPairs(bp, dispatcher.get());
702  broadphase->destroyProxy(bp, dispatcher.get());
703  cow->setBroadphaseHandle(nullptr);
704  }
705 }
706 
711 void addCollisionObjectToBroadphase(const CollisionObjectWrapperPtr& cow,
712  const std::unique_ptr<btBroadphaseInterface>& broadphase,
713  const std::unique_ptr<btCollisionDispatcher>& dispatcher);
714 
715 struct BroadphaseFilterCallback : public btOverlapFilterCallback
716 {
717  bool needBroadphaseCollision(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) const override;
718 };
719 
720 } // namespace collision_detection_bullet
#define METERS
Definition: bullet_utils.h:49
ROS/KDL based interface for the inverse kinematics of the PR2 arm.
Definition of a structure for the allowed collision matrix. All elements in the collision world are r...
Tesseract bullet collision object.
Definition: bullet_utils.h:110
std::shared_ptr< CollisionObjectWrapper > clone()
Clones the collision objects but not the collision shape which is const.
Definition: bullet_utils.h:181
void manage(std::shared_ptr< T > t)
Manage memory of a shared pointer shape.
Definition: bullet_utils.h:205
short int m_collisionFilterGroup
Bitfield specifies to which group the object belongs.
Definition: bullet_utils.h:132
bool m_enabled
Indicates if the collision object is used for a collision check.
Definition: bullet_utils.h:138
void getAABB(btVector3 &aabb_min, btVector3 &aabb_max) const
Get the collision objects axis aligned bounding box.
Definition: bullet_utils.h:169
AlignedVector< Eigen::Isometry3d > m_shape_poses
The poses of the shapes, must be same length as m_shapes.
Definition: bullet_utils.h:227
std::vector< std::shared_ptr< void > > m_data
Manages the collision shape pointer so they get destroyed.
Definition: bullet_utils.h:233
void manage(T *t)
Manage memory of a raw pointer shape.
Definition: bullet_utils.h:198
const std::string & getName() const
Get the collision object name.
Definition: bullet_utils.h:144
std::string m_name
The name of the object, must be unique.
Definition: bullet_utils.h:219
std::set< std::string > m_touch_links
The robot links the collision objects is allowed to touch.
Definition: bullet_utils.h:141
EIGEN_MAKE_ALIGNED_OPERATOR_NEW CollisionObjectWrapper(const std::string &name, const collision_detection::BodyType &type_id, const std::vector< shapes::ShapeConstPtr > &shapes, const AlignedVector< Eigen::Isometry3d > &shape_poses, const std::vector< CollisionObjectType > &collision_object_types, bool active=true)
Standard constructor.
bool sameObject(const CollisionObjectWrapper &other) const
Check if two CollisionObjectWrapper objects point to the same source object.
Definition: bullet_utils.h:157
std::vector< shapes::ShapeConstPtr > m_shapes
The shapes that define the collision object.
Definition: bullet_utils.h:224
std::vector< CollisionObjectType > m_collision_object_types
The shape collision object type to be used.
Definition: bullet_utils.h:230
short int m_collisionFilterMask
Bitfield specifies against which other groups the object is collision checked.
Definition: bullet_utils.h:135
const collision_detection::BodyType & getTypeID() const
Get a user defined type.
Definition: bullet_utils.h:150
A callback function that is called as part of the broadphase collision checking.
Definition: bullet_utils.h:639
TesseractCollisionPairCallback(const btDispatcherInfo &dispatchInfo, btCollisionDispatcher *dispatcher, BroadphaseContactResultCallback &results_callback)
Definition: bullet_utils.h:647
bool processOverlap(btBroadphasePair &pair) override
Type
The types of bodies that are considered for collision.
btCollisionShape * createShapePrimitive(const shapes::ShapeConstPtr &geom, const CollisionObjectType &collision_object_type, CollisionObjectWrapper *cow)
Casts a geometric shape into a btCollisionShape.
btVector3 convertEigenToBt(const Eigen::Vector3d &v)
Converts eigen vector to bullet vector.
Definition: bullet_utils.h:65
const btScalar BULLET_MARGIN
Definition: bullet_utils.h:51
MOVEIT_CLASS_FORWARD(BulletBVHManager)
CollisionObjectWrapperPtr makeCastCollisionObject(const CollisionObjectWrapperPtr &cow)
collision_detection::Contact * processResult(ContactTestData &cdata, collision_detection::Contact &contact, const std::pair< std::string, std::string > &key, bool found)
Stores a single contact result in the requested way.
std::vector< T, Eigen::aligned_allocator< T > > AlignedVector
Definition: basic_types.h:37
void updateCollisionObjectFilters(const std::vector< std::string > &active, CollisionObjectWrapper &cow)
Update a collision objects filters.
std::pair< std::string, std::string > getObjectPairKey(const std::string &obj1, const std::string &obj2)
Get a key for two object to search the collision matrix.
bool acmCheck(const std::string &body_1, const std::string &body_2, const collision_detection::AllowedCollisionMatrix *acm)
Allowed = true.
const btScalar BULLET_EPSILON
Definition: bullet_utils.h:54
const bool BULLET_COMPOUND_USE_DYNAMIC_AABB
Definition: bullet_utils.h:56
const btScalar BULLET_LENGTH_TOLERANCE
Definition: bullet_utils.h:53
btScalar addCastSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int, const btCollisionObjectWrapper *colObj1Wrap, int, ContactTestData &collisions)
Definition: bullet_utils.h:420
void updateBroadphaseAABB(const CollisionObjectWrapperPtr &cow, const std::unique_ptr< btBroadphaseInterface > &broadphase, const std::unique_ptr< btCollisionDispatcher > &dispatcher)
Update the Broadphase AABB for the input collision object.
Definition: bullet_utils.h:678
Eigen::Vector3d convertBtToEigen(const btVector3 &v)
Converts bullet vector to eigen vector.
Definition: bullet_utils.h:71
void removeCollisionObjectFromBroadphase(const CollisionObjectWrapperPtr &cow, const std::unique_ptr< btBroadphaseInterface > &broadphase, const std::unique_ptr< btCollisionDispatcher > &dispatcher)
Remove the collision object from broadphase.
Definition: bullet_utils.h:693
void addCollisionObjectToBroadphase(const CollisionObjectWrapperPtr &cow, const std::unique_ptr< btBroadphaseInterface > &broadphase, const std::unique_ptr< btCollisionDispatcher > &dispatcher)
Add the collision object to broadphase.
bool isOnlyKinematic(const CollisionObjectWrapper *cow0, const CollisionObjectWrapper *cow1)
Checks if the collision pair is kinematic vs kinematic objects.
Definition: bullet_utils.h:521
const btScalar BULLET_SUPPORT_FUNC_TOLERANCE
Definition: bullet_utils.h:52
const btScalar BULLET_DEFAULT_CONTACT_DISTANCE
Definition: bullet_utils.h:55
btScalar addDiscreteSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, const btCollisionObjectWrapper *colObj1Wrap, ContactTestData &collisions)
Converts a bullet contact result to MoveIt format and adds it to the result data structure.
Definition: bullet_utils.h:387
void getAverageSupport(const btConvexShape *shape, const btVector3 &localNormal, float &outsupport, btVector3 &outpt)
Computes the local supporting vertex of a convex shape.
Definition: bullet_utils.h:345
Vec3fX< details::Vec3Data< double > > Vector3d
Definition: fcl_compat.h:89
r
Definition: plan.py:56
double distance(const urdf::Pose &transform)
Definition: pr2_arm_ik.h:55
name
Definition: setup.py:7
Definition: world.h:49
Definition of a contact point.
std::string body_name_2
The id of the second body involved in the contact.
double percent_interpolation
The distance percentage between casted poses until collision.
Eigen::Vector3d nearest_points[2]
The two nearest points connecting the two bodies.
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::Vector3d normal
normal unit vector at contact
double depth
depth (penetration between bodies)
EIGEN_MAKE_ALIGNED_OPERATOR_NEW Eigen::Vector3d pos
contact position
Callback structure for both discrete and continuous broadphase collision pair.
Definition: bullet_utils.h:532
btScalar addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1)
This callback is used after btManifoldResult processed a collision result.
bool needsCollision(const CollisionObjectWrapper *cow0, const CollisionObjectWrapper *cow1) const
This callback is used for each overlapping pair in a pair cache of the broadphase interface to check ...
Definition: bullet_utils.h:554
const collision_detection::AllowedCollisionMatrix * acm_
Definition: bullet_utils.h:535
bool cast_
Indicates if the callback is used for casted collisions.
Definition: bullet_utils.h:541
bool self_
Indicates if the callback is used for only self-collision checking.
Definition: bullet_utils.h:538
BroadphaseContactResultCallback(ContactTestData &collisions, double contact_distance, const collision_detection::AllowedCollisionMatrix *acm, bool self, bool cast=false)
Definition: bullet_utils.h:543
bool needBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const override
Casted collision shape used for checking if an object is collision free between two discrete poses.
Definition: bullet_utils.h:241
int getNumPreferredPenetrationDirections() const override
Definition: bullet_utils.h:311
btScalar getMargin() const override
Definition: bullet_utils.h:306
void getAabbSlow(const btTransform &, btVector3 &, btVector3 &) const override
Definition: bullet_utils.h:287
btVector3 localGetSupportingVertex(const btVector3 &vec) const override
From both shape poses computes the support vertex and returns the larger one.
Definition: bullet_utils.h:260
void updateCastTransform(const btTransform &cast_transform)
Definition: bullet_utils.h:254
void calculateLocalInertia(btScalar, btVector3 &) const override
Definition: bullet_utils.h:321
void getPreferredPenetrationDirection(int, btVector3 &) const override
Definition: bullet_utils.h:316
btTransform m_shape_transform
Transformation from the first pose to the second pose.
Definition: bullet_utils.h:247
void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3 *, btVector3 *, int) const override
Definition: bullet_utils.h:268
CastHullShape(btConvexShape *shape, const btTransform &t01)
Definition: bullet_utils.h:249
void getAabb(const btTransform &transform_world, btVector3 &aabbMin, btVector3 &aabbMax) const override
Shape specific fast recalculation of the AABB at a certain pose.
Definition: bullet_utils.h:278
const char * getName() const override
Definition: bullet_utils.h:326
btVector3 localGetSupportingVertexWithoutMargin(const btVector3 &v) const override
Definition: bullet_utils.h:331
btConvexShape * m_shape
The casted shape.
Definition: bullet_utils.h:244
const btVector3 & getLocalScaling() const override
Definition: bullet_utils.h:296
void setLocalScaling(const btVector3 &) override
Definition: bullet_utils.h:292
Bundles the data for a collision query.
Definition: basic_types.h:59
bool done
Indicates if search is finished.
Definition: basic_types.h:77
collision_detection::CollisionResult & res
Definition: basic_types.h:73
bool pair_done
Indicates if search between a single pair is finished.
Definition: basic_types.h:80
TesseractBroadphaseBridgedManifoldResult(const btCollisionObjectWrapper *obj0Wrap, const btCollisionObjectWrapper *obj1Wrap, BroadphaseContactResultCallback &result_callback)
Definition: bullet_utils.h:576
void addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorld, btScalar depth) override
Definition: bullet_utils.h:583