From 6133f32ab06cad94123fdcb566b9931576fb0942 Mon Sep 17 00:00:00 2001 From: Florent Lamiraux <florent@laas.fr> Date: Wed, 1 Jul 2015 10:47:50 +0200 Subject: [PATCH] Express closest points in global frame - The frame in which closest points were expressed was neither clear, nor consistent. --- include/hpp/fcl/narrowphase/narrowphase.h | 8 +++--- src/distance.cpp | 9 +++++++ src/distance_capsule_capsule.cpp | 9 +++---- src/narrowphase/narrowphase.cpp | 32 +++++++++-------------- test/test_fcl_box_box_distance.cpp | 25 +++++++++--------- test/test_fcl_capsule_box_1.cpp | 16 ++++++------ test/test_fcl_capsule_box_2.cpp | 12 ++++----- 7 files changed, 57 insertions(+), 54 deletions(-) diff --git a/include/hpp/fcl/narrowphase/narrowphase.h b/include/hpp/fcl/narrowphase/narrowphase.h index a09c3ddc..0db42cdf 100644 --- a/include/hpp/fcl/narrowphase/narrowphase.h +++ b/include/hpp/fcl/narrowphase/narrowphase.h @@ -617,8 +617,8 @@ struct GJKSolver_indep if(distance) *distance = (w0 - w1).length(); - if(p1) *p1 = w0; - if(p2) *p2 = w1; + if(p1) *p1 = tf1.transform (w0); + if(p2) *p2 = tf1.transform (w1); return true; } @@ -718,8 +718,8 @@ struct GJKSolver_indep } if(distance) *distance = (w0 - w1).length(); - if(p1) *p1 = w0; - if(p2) *p2 = shape.toshape0.transform(w1); + if(p1) *p1 = tf1.transform(w0); + if(p2) *p2 = tf1.transform(w1); return true; } else diff --git a/src/distance.cpp b/src/distance.cpp index 30341788..c86cdd5e 100644 --- a/src/distance.cpp +++ b/src/distance.cpp @@ -87,6 +87,15 @@ FCL_REAL distance(const CollisionGeometry* o1, const Transform3f& tf1, else { res = looktable.distance_matrix[node_type2][node_type1](o2, tf2, o1, tf1, nsolver, request, result); + // If closest points are requested, switch object 1 and 2 + if (request.enable_nearest_points) { + const CollisionGeometry *tmpo = result.o1; + result.o1 = result.o2; + result.o2 = tmpo; + Vec3f tmpn (result.nearest_points [0]); + result.nearest_points [0] = result.nearest_points [1]; + result.nearest_points [1] = tmpn; + } } } else diff --git a/src/distance_capsule_capsule.cpp b/src/distance_capsule_capsule.cpp index 26380b79..7239066a 100644 --- a/src/distance_capsule_capsule.cpp +++ b/src/distance_capsule_capsule.cpp @@ -35,12 +35,11 @@ namespace fcl { const Capsule* c2 = static_cast <const Capsule*> (o2); // We assume that capsules are centered at the origin. - fcl::Vec3f center1 = Vec3f (0, 0, 0); - fcl::Vec3f center2 = inverse (tf1).transform (tf2.getTranslation ()); + fcl::Vec3f center1 = tf1.getTranslation (); + fcl::Vec3f center2 = tf2.getTranslation (); // We assume that capsules are oriented along z-axis. - fcl::Vec3f direction1 = Vec3f (0, 0, 1.); - fcl::Vec3f direction2 = tf1.getRotation ().transposeTimes - (tf2.getRotation ().getColumn (2)); + fcl::Vec3f direction1 = tf1.getRotation ().getColumn (2); + fcl::Vec3f direction2 = tf2.getRotation ().getColumn (2); FCL_REAL halfLength1 = 0.5*c1->lz; FCL_REAL halfLength2 = 0.5*c2->lz; diff --git a/src/narrowphase/narrowphase.cpp b/src/narrowphase/narrowphase.cpp index 56c7014f..5aee9c7b 100644 --- a/src/narrowphase/narrowphase.cpp +++ b/src/narrowphase/narrowphase.cpp @@ -111,9 +111,9 @@ bool sphereCapsuleDistance(const Sphere& s1, const Transform3f& tf1, Transform3f tf2_inv(tf2); tf2_inv.inverse(); - Vec3f pos1(0., 0., 0.5 * s2.lz); - Vec3f pos2(0., 0., -0.5 * s2.lz); - Vec3f s_c = tf2_inv.transform(tf1.transform(Vec3f())); + Vec3f pos1 (tf2.transform (Vec3f (0., 0., 0.5 * s2.lz))); + Vec3f pos2 (tf2.transform (Vec3f (0., 0., -0.5 * s2.lz))); + Vec3f s_c = tf1.getTranslation (); Vec3f segment_point; @@ -122,20 +122,19 @@ bool sphereCapsuleDistance(const Sphere& s1, const Transform3f& tf1, FCL_REAL distance = diff.length() - s1.radius - s2.radius; - if(distance <= 0) - return false; - if(dist) *dist = distance; if(p1 || p2) diff.normalize(); if(p1) { *p1 = s_c - diff * s1.radius; - *p1 = inverse(tf1).transform(tf2.transform(*p1)); } if(p2) *p2 = segment_point + diff * s1.radius; + if(distance <= 0) + return false; + return true; } @@ -176,16 +175,13 @@ bool sphereSphereDistance(const Sphere& s1, const Transform3f& tf1, Vec3f o2 = tf2.getTranslation(); Vec3f diff = o1 - o2; FCL_REAL len = diff.length(); - if(len > s1.radius + s2.radius) - { - if(dist) *dist = len - (s1.radius + s2.radius); - if(p1) *p1 = inverse(tf1).transform(o1 - diff * (s1.radius / len)); - if(p2) *p2 = inverse(tf2).transform(o2 + diff * (s2.radius / len)); - return true; - } + FCL_REAL d (len > s1.radius + s2.radius); - if(dist) *dist = -1; - return false; + if(dist) *dist = len - (s1.radius + s2.radius); + if(p1) *p1 = o1 - diff * (s1.radius / len); + if(p2) *p2 = o2 + diff * (s2.radius / len); + + return (d >=0); } /** \brief the minimum distance from a point to a line */ @@ -584,7 +580,7 @@ bool sphereTriangleDistance(const Sphere& sp, const Transform3f& tf, Vec3f project_p = P1 * result.parameterization[0] + P2 * result.parameterization[1] + P3 * result.parameterization[2]; Vec3f dir = o - project_p; dir.normalize(); - if(p1) { *p1 = o - dir * sp.radius; *p1 = inverse(tf).transform(*p1); } + if(p1) { *p1 = o - dir * sp.radius; } if(p2) *p2 = project_p; return true; } @@ -603,8 +599,6 @@ bool sphereTriangleDistance(const Sphere& sp, const Transform3f& tf1, FCL_REAL* dist, Vec3f* p1, Vec3f* p2) { bool res = details::sphereTriangleDistance(sp, tf1, tf2.transform(P1), tf2.transform(P2), tf2.transform(P3), dist, p1, p2); - if(p2) *p2 = inverse(tf2).transform(*p2); - return res; } diff --git a/test/test_fcl_box_box_distance.cpp b/test/test_fcl_box_box_distance.cpp index fdae2a49..5fd1bea4 100644 --- a/test/test_fcl_box_box_distance.cpp +++ b/test/test_fcl_box_box_distance.cpp @@ -87,7 +87,7 @@ BOOST_AUTO_TEST_CASE(distance_box_box_1) const Vec3f& p1 = distanceResult.nearest_points [0]; const Vec3f& p2 = distanceResult.nearest_points [1]; - BOOST_CHECK_CLOSE(distanceResult.min_distance, + BOOST_CHECK_CLOSE(distanceResult.min_distance, sqrt (dx*dx + dy*dy + dz*dz), 1e-4); BOOST_CHECK_CLOSE (p1 [0], 3, 1e-6); @@ -133,7 +133,7 @@ BOOST_AUTO_TEST_CASE(distance_box_box_2) BOOST_CHECK_CLOSE (p1 [0], 0.60947571, 1e-4); BOOST_CHECK_CLOSE (p1 [1], 0.01175873, 1e-4); - BOOST_CHECK_CLOSE (p1 [2], 1., 1e-6); + BOOST_CHECK_CLOSE (p1 [2], 1, 1e-6); BOOST_CHECK_CLOSE (p2 [0], 0.60947571, 1e-4); BOOST_CHECK_CLOSE (p2 [1], 0.01175873, 1e-4); BOOST_CHECK_CLOSE (p2 [2], -1.62123444 + 10, 1e-4); @@ -172,9 +172,8 @@ BOOST_AUTO_TEST_CASE(distance_box_box_3) double distance = 4 - sqrt (2); BOOST_CHECK_CLOSE(distanceResult.min_distance, distance, 1e-4); - const Vec3f p1Ref (.5, -.5, 0); - const Vec3f p2Ref (2.3284271247461898, -2.3284271247461898, 0); - + const Vec3f p1Ref (sqrt(2)/2 - 2, 1, .5); + const Vec3f p2Ref (2 - sqrt(2)/2, 1, .5); BOOST_CHECK_CLOSE (p1 [0], p1Ref [0], 1e-4); BOOST_CHECK_CLOSE (p1 [1], p1Ref [1], 1e-4); BOOST_CHECK_CLOSE (p1 [2], p1Ref [2], 1e-4); @@ -205,11 +204,13 @@ BOOST_AUTO_TEST_CASE(distance_box_box_3) BOOST_CHECK_CLOSE(distanceResult.min_distance, distance, 1e-4); - BOOST_CHECK_CLOSE (p1 [0], p1Ref [0], 1e-4); - BOOST_CHECK_CLOSE (p1 [1], p1Ref [1], 1e-4); - CHECK_CLOSE_TO_0 (p1 [2], 1e-6); - BOOST_CHECK_CLOSE (p2 [0], p2Ref [0], 1e-4); - BOOST_CHECK_CLOSE (p2 [1], p2Ref [1], 1e-4); - CHECK_CLOSE_TO_0 (p2 [2], 1e-6); - + const Vec3f p1Moved = tf3.transform (p1Ref); + const Vec3f p2Moved = tf3.transform (p2Ref); + BOOST_CHECK_CLOSE (p1 [0], p1Moved [0], 1e-4); + BOOST_CHECK_CLOSE (p1 [1], p1Moved [1], 1e-4); + BOOST_CHECK_CLOSE (p1 [2], p1Moved [2], 1e-4); + BOOST_CHECK_CLOSE (p2 [0], p2Moved [0], 1e-4); + BOOST_CHECK_CLOSE (p2 [1], p2Moved [1], 1e-4); + BOOST_CHECK_CLOSE (p2 [2], p2Moved [2], 1e-4); + } diff --git a/test/test_fcl_capsule_box_1.cpp b/test/test_fcl_capsule_box_1.cpp index 938d2047..16159ed1 100644 --- a/test/test_fcl_capsule_box_1.cpp +++ b/test/test_fcl_capsule_box_1.cpp @@ -70,9 +70,9 @@ BOOST_AUTO_TEST_CASE(distance_capsule_box) // Nearest point on box fcl::Vec3f o2 (distanceResult.nearest_points [1]); BOOST_CHECK_CLOSE (distanceResult.min_distance, 0.5, 1e-1); - BOOST_CHECK_CLOSE (o1 [0], -2.0, 1e-4); + BOOST_CHECK_CLOSE (o1 [0], 1.0, 1e-1); CHECK_CLOSE_TO_0 (o1 [1], 1e-1); - BOOST_CHECK_CLOSE (o2 [0], -2.5, 1e-4); + BOOST_CHECK_CLOSE (o2 [0], 0.5, 1e-1); CHECK_CLOSE_TO_0 (o1 [1], 1e-1); // Move capsule above box @@ -88,11 +88,11 @@ BOOST_AUTO_TEST_CASE(distance_capsule_box) BOOST_CHECK_CLOSE (distanceResult.min_distance, 2.0, 1e-1); CHECK_CLOSE_TO_0 (o1 [0], 1e-1); CHECK_CLOSE_TO_0 (o1 [1], 1e-1); - BOOST_CHECK_CLOSE (o1 [2], -4.0, 1e-4); + BOOST_CHECK_CLOSE (o1 [2], 4.0, 1e-1); CHECK_CLOSE_TO_0 (o2 [0], 1e-1); CHECK_CLOSE_TO_0 (o2 [1], 1e-1); - BOOST_CHECK_CLOSE (o2 [2], -6.0, 1e-4); + BOOST_CHECK_CLOSE (o2 [2], 2.0, 1e-1); // Rotate capsule around y axis by pi/2 and move it behind box tf1.setTranslation (fcl::Vec3f (-10., 0., 0.)); @@ -106,10 +106,10 @@ BOOST_AUTO_TEST_CASE(distance_capsule_box) o2 = distanceResult.nearest_points [1]; BOOST_CHECK_CLOSE (distanceResult.min_distance, 5.5, 1e-1); - CHECK_CLOSE_TO_0 (o1 [0], 1e-1); + BOOST_CHECK_CLOSE (o1 [0], -6, 1e-2); CHECK_CLOSE_TO_0 (o1 [1], 1e-1); - BOOST_CHECK_CLOSE (o1 [2], 4.0, 1e-1); - CHECK_CLOSE_TO_0 (o2 [0], 1e-1); + CHECK_CLOSE_TO_0 (o1 [2], 1e-1); + BOOST_CHECK_CLOSE (o2 [0], -0.5, 1e-2); CHECK_CLOSE_TO_0 (o2 [1], 1e-1); - BOOST_CHECK_CLOSE (o2 [2], 9.5, 1e-1); + CHECK_CLOSE_TO_0 (o2 [2], 1e-1); } diff --git a/test/test_fcl_capsule_box_2.cpp b/test/test_fcl_capsule_box_2.cpp index a612cefb..81e355bc 100644 --- a/test/test_fcl_capsule_box_2.cpp +++ b/test/test_fcl_capsule_box_2.cpp @@ -72,10 +72,10 @@ BOOST_AUTO_TEST_CASE(distance_capsule_box) fcl::Vec3f o2 = distanceResult.nearest_points [1]; BOOST_CHECK_CLOSE (distanceResult.min_distance, 5.5, 1e-2); - CHECK_CLOSE_TO_0 (o1 [0], 1e-2); - CHECK_CLOSE_TO_0 (o1 [1], 1e-1); - BOOST_CHECK_CLOSE (o1 [2], 4., 1e-2); - CHECK_CLOSE_TO_0 (o2 [0], 1e-2); - CHECK_CLOSE_TO_0 (o2 [1], 1e-1); - BOOST_CHECK_CLOSE (o2 [2], 9.5, 1e-2); + BOOST_CHECK_CLOSE (o1 [0], -6, 1e-2); + BOOST_CHECK_CLOSE (o1 [1], 0.8, 1e-1); + BOOST_CHECK_CLOSE (o1 [2], 1.5, 1e-2); + BOOST_CHECK_CLOSE (o2 [0], -0.5, 1e-2); + BOOST_CHECK_CLOSE (o2 [1], 0.8, 1e-1); + BOOST_CHECK_CLOSE (o2 [2], 1.5, 1e-2); } -- GitLab