Skip to content

Commit f435c9a

Browse files
authored
Fix FCL mesh contact regression and add test (#2258)
1 parent 807988c commit f435c9a

File tree

4 files changed

+115
-3
lines changed

4 files changed

+115
-3
lines changed

dart/collision/fcl/FCLCollisionDetector.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,9 +1100,21 @@ bool collisionCallback(
11001100
::fcl::collide(o1, o2, fclRequest, fclResult);
11011101

11021102
if (result) {
1103+
const bool usingMeshContacts
1104+
= (collData->primitiveShapeType == FCLCollisionDetector::MESH);
1105+
const bool forcingMeshFallback = usingMeshContacts
1106+
&& collData->contactPointComputationMethod
1107+
== FCLCollisionDetector::FCL;
1108+
11031109
// Post processing -- converting fcl contact information to ours if needed
1104-
if (FCLCollisionDetector::DART == collData->contactPointComputationMethod
1105-
&& FCLCollisionDetector::MESH == collData->primitiveShapeType) {
1110+
if (usingMeshContacts) {
1111+
if (forcingMeshFallback) {
1112+
DART_WARN_ONCE(
1113+
"FCL mesh contact-point computation is known to be inaccurate "
1114+
"(see flexible-collision-library/fcl#106); falling back to DART's "
1115+
"mesh contact handler.");
1116+
}
1117+
11061118
postProcessDART(fclResult, o1, o2, option, *result);
11071119
} else {
11081120
postProcessFCL(fclResult, o1, o2, option, *result);

tests/integration/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@ if(TARGET dart-utils)
1010
target_link_libraries(INTEGRATION_collision_Collision dart-utils)
1111
endif()
1212

13+
if(DART_BUILD_COLLISION_FCL)
14+
dart_add_test(
15+
"integration"
16+
INTEGRATION_collision_MeshContactRegression
17+
collision/test_MeshContactRegression.cpp)
18+
endif()
19+
1320
# Additional collision tests
1421
if(TARGET dart-utils-urdf)
1522
dart_add_test("integration" INTEGRATION_collision_SelfCollisionFiltering collision/test_SelfCollisionFiltering.cpp)
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
* Copyright (c) 2011-2025, The DART development contributors
3+
* All rights reserved.
4+
*
5+
* The list of contributors can be found at:
6+
* https://github.com/dartsim/dart/blob/main/LICENSE
7+
*
8+
* This file is provided under the following "BSD-style" License:
9+
* Redistribution and use in source and binary forms, with or
10+
* without modification, are permitted provided that the following
11+
* conditions are met:
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+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19+
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20+
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21+
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26+
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27+
* 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+
#include <dart/collision/CollisionResult.hpp>
34+
#include <dart/collision/fcl/FCLCollisionDetector.hpp>
35+
36+
#include <dart/dynamics/BoxShape.hpp>
37+
#include <dart/dynamics/Frame.hpp>
38+
#include <dart/dynamics/SimpleFrame.hpp>
39+
40+
#include <Eigen/Core>
41+
#include <cmath>
42+
#include <gtest/gtest.h>
43+
44+
using dart::collision::FCLCollisionDetector;
45+
46+
// Reproduces the face-to-face mesh box contact from DART issue #860.
47+
// The detector is intentionally configured to use FCL's contact computation,
48+
// and the test asserts that DART still returns sensible contact points on the
49+
// touching face.
50+
TEST(CollisionRegression, MeshMeshContactPointsStayOnContactPlane)
51+
{
52+
auto detector = FCLCollisionDetector::create();
53+
detector->setPrimitiveShapeType(FCLCollisionDetector::MESH);
54+
detector->setContactPointComputationMethod(FCLCollisionDetector::FCL);
55+
56+
auto shape = std::make_shared<dart::dynamics::BoxShape>(
57+
Eigen::Vector3d::Ones());
58+
59+
auto bottom = dart::dynamics::SimpleFrame::createShared(
60+
dart::dynamics::Frame::World());
61+
auto top = dart::dynamics::SimpleFrame::createShared(
62+
dart::dynamics::Frame::World());
63+
64+
bottom->setShape(shape);
65+
top->setShape(shape);
66+
67+
bottom->setTranslation(Eigen::Vector3d::Zero());
68+
top->setTranslation(Eigen::Vector3d(0.0, 0.0, 1.0));
69+
70+
auto group = detector->createCollisionGroup(bottom.get(), top.get());
71+
72+
dart::collision::CollisionOption option;
73+
option.enableContact = true;
74+
option.maxNumContacts = 20u;
75+
76+
dart::collision::CollisionResult result;
77+
const bool collided = group->collide(option, &result);
78+
ASSERT_TRUE(collided);
79+
ASSERT_GT(result.getNumContacts(), 0u);
80+
81+
const double half = 0.5;
82+
const double tol = 1e-3;
83+
84+
for (std::size_t i = 0; i < result.getNumContacts(); ++i) {
85+
const auto& contact = result.getContact(i);
86+
87+
EXPECT_NEAR(contact.point[2], half, tol) << "Contact index: " << i;
88+
EXPECT_LE(contact.point.head<2>().cwiseAbs().maxCoeff(), half + tol);
89+
90+
EXPECT_NEAR(std::abs(contact.normal[2]), 1.0, 1e-6);
91+
EXPECT_LT(std::abs(contact.normal[0]) + std::abs(contact.normal[1]), 1e-3);
92+
}
93+
}

tests/integration/dynamics/test_DynamicsHybrid.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
#include "DynamicsTestFixture.hpp"
21
#include "helpers/dynamics_helpers.hpp"
32

3+
#include "DynamicsTestFixture.hpp"
44
#include "dart/dynamics/Inertia.hpp"
55
#include "dart/math/Random.hpp"
66
#include "dart/simulation/World.hpp"

0 commit comments

Comments
 (0)