Skip to content

Commit 838f23d

Browse files
Check pair margin AABB before narrow phase check
1 parent bf3ad4c commit 838f23d

File tree

7 files changed

+102
-36
lines changed

7 files changed

+102
-36
lines changed

tesseract_collision/bullet/include/tesseract_collision/bullet/bullet_utils.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,15 @@ class CollisionObjectWrapper : public btCollisionObject
126126
*/
127127
void getAABB(btVector3& aabb_min, btVector3& aabb_max) const;
128128

129+
/**
130+
* @brief Get the collision object's axis aligned bounding box
131+
* This AABB is extended by the provided margin
132+
* @param aabb_min The minimum point
133+
* @param aabb_max The maximum point
134+
* @margin margin The value to extend the aabb
135+
*/
136+
void getAABB(btVector3& aabb_min, btVector3& aabb_max, btScalar margin) const;
137+
129138
/**
130139
* @brief This clones the collision objects but not the collision shape wich is const.
131140
* @return Shared Pointer to the cloned collision object

tesseract_collision/bullet/src/bullet_cast_simple_manager.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ void BulletCastSimpleManager::contactTest(ContactResultMap& collisions, const Co
404404
continue;
405405

406406
btVector3 min_aabb[2], max_aabb[2]; // NOLINT
407-
cow1->getAABB(min_aabb[0], max_aabb[0]);
407+
cow1->getAABB(min_aabb[0], max_aabb[0], 0.0);
408408

409409
btCollisionObjectWrapper obA(nullptr, cow1->getCollisionShape(), cow1.get(), cow1->getWorldTransform(), -1, -1);
410410

@@ -414,7 +414,10 @@ void BulletCastSimpleManager::contactTest(ContactResultMap& collisions, const Co
414414
assert(!contact_test_data_.done);
415415

416416
const COW::Ptr& cow2 = *cow2_iter;
417-
cow2->getAABB(min_aabb[1], max_aabb[1]);
417+
418+
const double contact_threshold =
419+
contact_test_data_.collision_margin_data.getCollisionMargin(cow1->getName(), cow2->getName());
420+
cow2->getAABB(min_aabb[1], max_aabb[1], contact_threshold);
418421

419422
bool aabb_check = (min_aabb[0][0] <= max_aabb[1][0] && max_aabb[0][0] >= min_aabb[1][0]) &&
420423
(min_aabb[0][1] <= max_aabb[1][1] && max_aabb[0][1] >= min_aabb[1][1]) &&
@@ -435,8 +438,7 @@ void BulletCastSimpleManager::contactTest(ContactResultMap& collisions, const Co
435438
if (algorithm != nullptr)
436439
{
437440
// Update the contact threshold to be pair specific
438-
cc.m_closestDistanceThreshold =
439-
contact_test_data_.collision_margin_data.getCollisionMargin(cow1->getName(), cow2->getName());
441+
cc.m_closestDistanceThreshold = contact_threshold;
440442
TesseractBridgedManifoldResult contactPointResult(&obA, &obB, cc);
441443

442444
// discrete collision detection query

tesseract_collision/bullet/src/bullet_discrete_simple_manager.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ void BulletDiscreteSimpleManager::contactTest(ContactResultMap& collisions, cons
290290
continue;
291291

292292
btVector3 min_aabb[2], max_aabb[2]; // NOLINT
293-
cow1->getAABB(min_aabb[0], max_aabb[0]);
293+
cow1->getAABB(min_aabb[0], max_aabb[0], 0.0);
294294

295295
btCollisionObjectWrapper obA(nullptr, cow1->getCollisionShape(), cow1.get(), cow1->getWorldTransform(), -1, -1);
296296

@@ -300,7 +300,9 @@ void BulletDiscreteSimpleManager::contactTest(ContactResultMap& collisions, cons
300300
assert(!contact_test_data_.done);
301301

302302
const COW::Ptr& cow2 = *cow2_iter;
303-
cow2->getAABB(min_aabb[1], max_aabb[1]);
303+
const double contact_threshold =
304+
contact_test_data_.collision_margin_data.getCollisionMargin(cow1->getName(), cow2->getName());
305+
cow2->getAABB(min_aabb[1], max_aabb[1], contact_threshold);
304306

305307
bool aabb_check = (min_aabb[0][0] <= max_aabb[1][0] && max_aabb[0][0] >= min_aabb[1][0]) &&
306308
(min_aabb[0][1] <= max_aabb[1][1] && max_aabb[0][1] >= min_aabb[1][1]) &&
@@ -321,8 +323,7 @@ void BulletDiscreteSimpleManager::contactTest(ContactResultMap& collisions, cons
321323
if (algorithm != nullptr)
322324
{
323325
// Update the contact threshold to be pair specific
324-
cc.m_closestDistanceThreshold =
325-
contact_test_data_.collision_margin_data.getCollisionMargin(cow1->getName(), cow2->getName());
326+
cc.m_closestDistanceThreshold = contact_threshold;
326327
TesseractBridgedManifoldResult contactPointResult(&obA, &obB, cc);
327328

328329
// discrete collision detection query

tesseract_collision/bullet/src/bullet_utils.cpp

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -528,12 +528,17 @@ const tesseract_common::VectorIsometry3d& CollisionObjectWrapper::getCollisionGe
528528
}
529529

530530
void CollisionObjectWrapper::getAABB(btVector3& aabb_min, btVector3& aabb_max) const
531+
{
532+
const btScalar d = getContactProcessingThreshold() / 2.0;
533+
getAABB(aabb_min, aabb_max, d);
534+
}
535+
536+
void CollisionObjectWrapper::getAABB(btVector3& aabb_min, btVector3& aabb_max, btScalar margin) const
531537
{
532538
getCollisionShape()->getAabb(getWorldTransform(), aabb_min, aabb_max);
533-
const btScalar& d = getContactProcessingThreshold() / 2.0;
534-
btVector3 contactThreshold(d, d, d);
535-
aabb_min -= contactThreshold;
536-
aabb_max += contactThreshold;
539+
btVector3 contact_threshold(margin, margin, margin);
540+
aabb_min -= contact_threshold;
541+
aabb_max += contact_threshold;
537542
}
538543

539544
std::shared_ptr<CollisionObjectWrapper> CollisionObjectWrapper::clone()
@@ -1131,27 +1136,42 @@ bool TesseractCollisionPairCallback::processOverlap(btBroadphasePair& pair)
11311136
const auto* cow0 = static_cast<const CollisionObjectWrapper*>(pair.m_pProxy0->m_clientObject);
11321137
const auto* cow1 = static_cast<const CollisionObjectWrapper*>(pair.m_pProxy1->m_clientObject);
11331138

1134-
if (results_callback_.needsCollision(cow0, cow1))
1135-
{
1136-
btCollisionObjectWrapper obj0Wrap(nullptr, cow0->getCollisionShape(), cow0, cow0->getWorldTransform(), -1, -1);
1137-
btCollisionObjectWrapper obj1Wrap(nullptr, cow1->getCollisionShape(), cow1, cow1->getWorldTransform(), -1, -1);
1139+
if (!results_callback_.needsCollision(cow0, cow1))
1140+
return false;
11381141

1139-
// dispatcher will keep algorithms persistent in the collision pair
1140-
if (pair.m_algorithm == nullptr)
1141-
{
1142-
pair.m_algorithm = dispatcher_->findAlgorithm(&obj0Wrap, &obj1Wrap, nullptr, BT_CLOSEST_POINT_ALGORITHMS);
1143-
}
1142+
const double contact_threshold =
1143+
results_callback_.collisions_.collision_margin_data.getCollisionMargin(cow0->getName(), cow1->getName());
1144+
btVector3 min_aabb[2], max_aabb[2]; // NOLINT
1145+
cow0->getAABB(min_aabb[0], max_aabb[0], contact_threshold / 2.0);
1146+
cow1->getAABB(min_aabb[1], max_aabb[1], contact_threshold / 2.0);
11441147

1145-
if (pair.m_algorithm != nullptr)
1146-
{
1147-
TesseractBroadphaseBridgedManifoldResult contactPointResult(&obj0Wrap, &obj1Wrap, results_callback_);
1148-
contactPointResult.m_closestPointDistanceThreshold =
1149-
results_callback_.collisions_.collision_margin_data.getCollisionMargin(cow0->getName(), cow1->getName());
1148+
const bool aabb_check = (min_aabb[0][0] <= max_aabb[1][0] && max_aabb[0][0] >= min_aabb[1][0]) &&
1149+
(min_aabb[0][1] <= max_aabb[1][1] && max_aabb[0][1] >= min_aabb[1][1]) &&
1150+
(min_aabb[0][2] <= max_aabb[1][2] && max_aabb[0][2] >= min_aabb[1][2]);
11501151

1151-
// discrete collision detection query
1152-
pair.m_algorithm->processCollision(&obj0Wrap, &obj1Wrap, dispatch_info_, &contactPointResult);
1153-
}
1152+
// Check if ABB are overlapping
1153+
if (!aabb_check)
1154+
return false;
1155+
1156+
btCollisionObjectWrapper obj0Wrap(nullptr, cow0->getCollisionShape(), cow0, cow0->getWorldTransform(), -1, -1);
1157+
btCollisionObjectWrapper obj1Wrap(nullptr, cow1->getCollisionShape(), cow1, cow1->getWorldTransform(), -1, -1);
1158+
1159+
// dispatcher will keep algorithms persistent in the collision pair
1160+
if (pair.m_algorithm == nullptr)
1161+
{
1162+
pair.m_algorithm = dispatcher_->findAlgorithm(&obj0Wrap, &obj1Wrap, nullptr, BT_CLOSEST_POINT_ALGORITHMS);
11541163
}
1164+
1165+
if (pair.m_algorithm != nullptr)
1166+
{
1167+
TesseractBroadphaseBridgedManifoldResult contactPointResult(&obj0Wrap, &obj1Wrap, results_callback_);
1168+
contactPointResult.m_closestPointDistanceThreshold = contact_threshold;
1169+
1170+
// discrete collision detection query
1171+
pair.m_algorithm->processCollision(&obj0Wrap, &obj1Wrap, dispatch_info_, &contactPointResult);
1172+
}
1173+
1174+
// Should this return true?
11551175
return false;
11561176
}
11571177

tesseract_collision/fcl/include/tesseract_collision/fcl/fcl_collision_object_wrapper.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ class FCLCollisionObjectWrapper : public fcl::CollisionObject<double>
5757
*/
5858
double getContactDistanceThreshold() const;
5959

60+
/**
61+
* @brief Get AABB with provided margin
62+
* @param margin The margin to apply to AABB
63+
* @return The AABB
64+
*/
65+
fcl::AABB<double> getAABB(double margin) const;
66+
6067
/**
6168
* @brief Update the internal AABB. This must be called instead of the base class computeAABB().
6269
*
@@ -81,6 +88,9 @@ class FCLCollisionObjectWrapper : public fcl::CollisionObject<double>
8188

8289
/** @brief The shape index, which is the geometries index in the urdf. */
8390
int shape_index_{ -1 };
91+
92+
/** @brief AABB which does not include margin */
93+
fcl::AABB<double> aabb_without_margin_;
8494
};
8595

8696
} // namespace tesseract_collision::tesseract_collision_fcl

tesseract_collision/fcl/src/fcl_collision_object_wrapper.cpp

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,22 +36,33 @@ void FCLCollisionObjectWrapper::setContactDistanceThreshold(double contact_dista
3636

3737
double FCLCollisionObjectWrapper::getContactDistanceThreshold() const { return contact_distance_; }
3838

39+
fcl::AABB<double> FCLCollisionObjectWrapper::getAABB(double margin) const
40+
{
41+
fcl::AABB<double> aabb_with_margin{ aabb_without_margin_ };
42+
fcl::Vector3<double> delta = fcl::Vector3<double>::Constant(margin);
43+
aabb_with_margin.min_ -= delta;
44+
aabb_with_margin.max_ += delta;
45+
return aabb_with_margin;
46+
}
47+
3948
void FCLCollisionObjectWrapper::updateAABB()
4049
{
4150
if (t.linear().isIdentity())
4251
{
43-
aabb = translate(cgeom->aabb_local, t.translation());
44-
fcl::Vector3<double> delta = fcl::Vector3<double>::Constant(contact_distance_ / 2.0);
45-
aabb.min_ -= delta;
46-
aabb.max_ += delta;
52+
aabb_without_margin_ = translate(cgeom->aabb_local, t.translation());
4753
}
4854
else
4955
{
5056
fcl::Vector3<double> center = t * cgeom->aabb_center;
51-
fcl::Vector3<double> delta = fcl::Vector3<double>::Constant(cgeom->aabb_radius + (contact_distance_ / 2.0));
52-
aabb.min_ = center - delta;
53-
aabb.max_ = center + delta;
57+
fcl::Vector3<double> aabb_radius = fcl::Vector3<double>::Constant(cgeom->aabb_radius);
58+
aabb_without_margin_.min_ = center - aabb_radius;
59+
aabb_without_margin_.max_ = center + aabb_radius;
5460
}
61+
62+
aabb = aabb_without_margin_;
63+
fcl::Vector3<double> delta = fcl::Vector3<double>::Constant(contact_distance_ / 2.0);
64+
aabb.min_ -= delta;
65+
aabb.max_ += delta;
5566
}
5667

5768
void FCLCollisionObjectWrapper::setShapeIndex(int index) { shape_index_ = index; }

tesseract_collision/fcl/src/fcl_utils.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,19 @@ bool collisionCallback(fcl::CollisionObjectd* o1, fcl::CollisionObjectd* o2, voi
237237
if (!needs_collision)
238238
return false;
239239

240+
const double margin = cdata->collision_margin_data.getCollisionMargin(cd1->getName(), cd2->getName()) / 2.0;
241+
242+
fcl::AABB<double> aabb1 = static_cast<const FCLCollisionObjectWrapper*>(o1)->getAABB(margin);
243+
fcl::AABB<double> aabb2 = static_cast<const FCLCollisionObjectWrapper*>(o2)->getAABB(margin);
244+
245+
const bool aabb_check = (aabb1.min_[0] <= aabb2.max_[0] && aabb1.max_[0] >= aabb2.min_[0]) &&
246+
(aabb1.min_[1] <= aabb2.max_[1] && aabb1.max_[1] >= aabb2.min_[1]) &&
247+
(aabb1.min_[2] <= aabb2.max_[2] && aabb1.max_[2] >= aabb2.min_[2]);
248+
249+
// Check if ABB are overlapping
250+
if (!aabb_check)
251+
return false;
252+
240253
std::size_t num_contacts = (cdata->req.contact_limit > 0) ? static_cast<std::size_t>(cdata->req.contact_limit) :
241254
std::numeric_limits<std::size_t>::max();
242255
if (cdata->req.type == ContactTestType::FIRST)

0 commit comments

Comments
 (0)