test/gjk.cpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2018, CNRS-LAAS.
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 Willow Garage, Inc. 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 
37 #define BOOST_TEST_MODULE COAL_GJK
38 #include <time.h>
39 #include <boost/test/included/unit_test.hpp>
40 
41 #include <Eigen/Geometry>
44 #include "coal/internal/tools.h"
46 
47 #include "utility.h"
48 
49 using coal::CoalScalar;
50 using coal::GJKSolver;
51 using coal::GJKVariant;
52 using coal::Matrix3s;
53 using coal::Quatf;
54 using coal::Transform3s;
55 using coal::TriangleP;
56 using coal::Vec3s;
57 
58 typedef Eigen::Matrix<CoalScalar, Eigen::Dynamic, 1> vector_t;
59 typedef Eigen::Matrix<CoalScalar, 6, 1> vector6_t;
60 typedef Eigen::Matrix<CoalScalar, 4, 1> vector4_t;
61 typedef Eigen::Matrix<CoalScalar, Eigen::Dynamic, Eigen::Dynamic> matrix_t;
62 
63 struct Result {
64  bool collision;
65  clock_t timeGjk;
66  clock_t timeGte;
67 }; // struct benchmark
68 
69 typedef std::vector<Result> Results_t;
70 
72  bool enable_gjk_nesterov_acceleration) {
73  Eigen::IOFormat numpy(Eigen::FullPrecision, Eigen::DontAlignCols, ", ", ", ",
74  "np.array ((", "))", "", "");
75  Eigen::IOFormat tuple(Eigen::FullPrecision, Eigen::DontAlignCols, "", ", ",
76  "", "", "(", ")");
77  std::size_t N = 10000;
78  GJKSolver solver;
79  if (enable_gjk_nesterov_acceleration)
82  Vec3s p1, p2, a1, a2;
83  Matrix3s M;
84  CoalScalar distance(sqrt(-1));
85  clock_t start, end;
86 
87  std::size_t nCol = 0, nDiff = 0;
88  CoalScalar eps = 1e-7;
89  Results_t results(N);
90  for (std::size_t i = 0; i < N; ++i) {
91  Vec3s P1_loc(Vec3s::Random()), P2_loc(Vec3s::Random()),
92  P3_loc(Vec3s::Random());
93  Vec3s Q1_loc(Vec3s::Random()), Q2_loc(Vec3s::Random()),
94  Q3_loc(Vec3s::Random());
95  if (i == 0) {
96  P1_loc = Vec3s(0.063996093749999997, -0.15320971679687501,
97  -0.42799999999999999);
98  P2_loc =
99  Vec3s(0.069105957031249998, -0.150722900390625, -0.42999999999999999);
100  P3_loc = Vec3s(0.063996093749999997, -0.15320971679687501,
101  -0.42999999999999999);
102  Q1_loc =
103  Vec3s(-25.655000000000001, -1.2858199462890625, 3.7249809570312502);
104  Q2_loc = Vec3s(-10.926, -1.284259033203125, 3.7281499023437501);
105  Q3_loc = Vec3s(-10.926, -1.2866180419921875, 3.72335400390625);
106  Transform3s tf(
107  Quatf(-0.42437287410898855, -0.26862477561450587,
108  -0.46249645019513175, 0.73064726592483387),
109  Vec3s(-12.824601270753471, -1.6840516940066426, 3.8914453043793844));
110  tf1 = tf;
111  } else if (i == 1) {
112  P1_loc =
113  Vec3s(-0.8027043342590332, -0.30276307463645935, -0.4372950792312622);
114  P2_loc =
115  Vec3s(-0.8027043342590332, 0.30276307463645935, -0.4372950792312622);
116  P3_loc =
117  Vec3s(0.8027043342590332, 0.30276307463645935, -0.4372950792312622);
118  Q1_loc =
119  Vec3s(-0.224713996052742, -0.7417119741439819, 0.19999997317790985);
120  Q2_loc =
121  Vec3s(-0.5247139930725098, -0.7417119741439819, 0.19999997317790985);
122  Q3_loc =
123  Vec3s(-0.224713996052742, -0.7417119741439819, 0.09999997168779373);
124  Matrix3s R;
125  Vec3s T;
126  R << 0.9657787025454787, 0.09400415350535746, 0.24173273843919627,
127  -0.06713698817647556, 0.9908494114820345, -0.11709000206805695,
128  -0.25052768814676646, 0.09685382227587608, 0.9632524147814993;
129 
130  T << -0.13491177905469953, -1, 0.6000449621843792;
131  tf1.setRotation(R);
132  tf1.setTranslation(T);
133  } else {
134  tf1 = Transform3s();
135  }
136 
137  TriangleP tri1(P1_loc, P2_loc, P3_loc);
138  TriangleP tri2(Q1_loc, Q2_loc, Q3_loc);
139  Vec3s normal;
140  const bool compute_penetration = true;
141  coal::DistanceRequest request(compute_penetration, compute_penetration);
142  coal::DistanceResult result;
143 
144  start = clock();
145  // The specialized function TriangleP-TriangleP calls GJK to check for
146  // collision and compute the witness points but it does not use EPA to
147  // compute the penetration depth.
149  &tri1, tf1, &tri2, tf2, &solver, request, result);
150  end = clock();
151  p1 = result.nearest_points[0];
152  p2 = result.nearest_points[1];
153  normal = result.normal;
154  bool res = (distance <= 0);
155  results[i].timeGjk = end - start;
156  results[i].collision = res;
157  if (res) {
158  Vec3s c1, c2, normal2;
159  ++nCol;
160  // check that moving triangle 2 by the penetration depth in the
161  // direction of the normal makes the triangles collision free.
162  CoalScalar penetration_depth(-distance);
163  assert(penetration_depth >= 0);
164  tf2.setTranslation((penetration_depth + 10 - 4) * normal);
165  result.clear();
167  &tri1, tf1, &tri2, tf2, &solver, request, result);
168  c1 = result.nearest_points[0];
169  c2 = result.nearest_points[1];
170  normal2 = result.normal;
171  res = (distance <= 0);
172  if (res) {
173  std::cerr << "P1 = " << P1_loc.format(tuple) << std::endl;
174  std::cerr << "P2 = " << P2_loc.format(tuple) << std::endl;
175  std::cerr << "P3 = " << P3_loc.format(tuple) << std::endl;
176  std::cerr << "Q1 = " << Q1_loc.format(tuple) << std::endl;
177  std::cerr << "Q2 = " << Q2_loc.format(tuple) << std::endl;
178  std::cerr << "Q3 = " << Q3_loc.format(tuple) << std::endl;
179  std::cerr << "p1 = " << c1.format(tuple) << std::endl;
180  std::cerr << "p2 = " << c2.format(tuple) << std::endl;
181  std::cerr << "tf1 = " << tf1.getTranslation().format(tuple) << " + "
182  << tf1.getQuatRotation().coeffs().format(tuple) << std::endl;
183  std::cerr << "tf2 = " << tf2.getTranslation().format(tuple) << " + "
184  << tf2.getQuatRotation().coeffs().format(tuple) << std::endl;
185  std::cerr << "normal = " << normal.format(tuple) << std::endl;
186  abort();
187  }
188  distance = 0;
189  tf2.setIdentity();
190  }
191  // Compute vectors between vertices
192  Vec3s P1(tf1.transform(P1_loc)), P2(tf1.transform(P2_loc)),
193  P3(tf1.transform(P3_loc)), Q1(tf2.transform(Q1_loc)),
194  Q2(tf2.transform(Q2_loc)), Q3(tf2.transform(Q3_loc));
195  Vec3s u1(P2 - P1);
196  Vec3s v1(P3 - P1);
197  Vec3s w1(u1.cross(v1));
198  Vec3s u2(Q2 - Q1);
199  Vec3s v2(Q3 - Q1);
200  Vec3s w2(u2.cross(v2));
201  BOOST_CHECK(w1.squaredNorm() > eps * eps);
202  M.col(0) = u1;
203  M.col(1) = v1;
204  M.col(2) = w1;
205  // Compute a1 such that p1 = P1 + a11 u1 + a12 v1 + a13 u1 x v1
206  a1 = M.inverse() * (p1 - P1);
207  EIGEN_VECTOR_IS_APPROX(p1, P1 + a1[0] * u1 + a1[1] * v1, eps);
208  BOOST_CHECK(w2.squaredNorm() > eps * eps);
209  // Compute a2 such that p2 = Q1 + a21 u2 + a22 v2 + a23 u2 x v2
210  M.col(0) = u2;
211  M.col(1) = v2;
212  M.col(2) = w2;
213  a2 = M.inverse() * (p2 - Q1);
214  EIGEN_VECTOR_IS_APPROX(p2, Q1 + a2[0] * u2 + a2[1] * v2, eps);
215 
216  // minimal distance and closest points can be considered as a constrained
217  // optimisation problem:
218  //
219  // min f (a1[0],a1[1], a2[0],a2[1])
220  // g1 (a1[0],a1[1], a2[0],a2[1]) <=0
221  // ...
222  // g6 (a1[0],a1[1], a2[0],a2[1]) <=0
223  // with
224  // f (a1[0],a1[1], a2[0],a2[1]) =
225  // 1 2
226  // --- dist (P1 + a1[0] u1 + a1[1] v1, Q1 + a2[0] u2 + a2[1] v2),
227  // 2
228  // g1 (a1[0],a1[1], a2[0],a2[1]) = -a1[0]
229  // g2 (a1[0],a1[1], a2[0],a2[1]) = -a1[1]
230  // g3 (a1[0],a1[1], a2[0],a2[1]) = a1[0] + a1[1] - 1
231  // g4 (a1[0],a1[1], a2[0],a2[1]) = -a2[0]
232  // g5 (a1[0],a1[1], a2[0],a2[1]) = -a2[1]
233  // g6 (a1[0],a1[1], a2[0],a2[1]) = a2[0] + a2[1] - 1
234 
235  // Compute gradient of f
236  vector4_t grad_f;
237  grad_f[0] = -(p2 - p1).dot(u1);
238  grad_f[1] = -(p2 - p1).dot(v1);
239  grad_f[2] = (p2 - p1).dot(u2);
240  grad_f[3] = (p2 - p1).dot(v2);
241  vector6_t g;
242  g[0] = -a1[0];
243  g[1] = -a1[1];
244  g[2] = a1[0] + a1[1] - 1;
245  g[3] = -a2[0];
246  g[4] = -a2[1];
247  g[5] = a2[0] + a2[1] - 1;
248  matrix_t grad_g(4, 6);
249  grad_g.setZero();
250  grad_g(0, 0) = -1.;
251  grad_g(1, 1) = -1;
252  grad_g(0, 2) = 1;
253  grad_g(1, 2) = 1;
254  grad_g(2, 3) = -1;
255  grad_g(3, 4) = -1;
256  grad_g(2, 5) = 1;
257  grad_g(3, 5) = 1;
258  // Check that closest points are on triangles planes
259  // Projection of [P1p1] on line normal to triangle 1 plane is equal to 0
260  BOOST_CHECK_SMALL(a1[2], eps);
261  // Projection of [Q1p2] on line normal to triangle 2 plane is equal to 0
262  BOOST_CHECK_SMALL(a2[2], eps);
263 
264  /* Check Karush–Kuhn–Tucker conditions
265  6
266  __
267  \
268  -grad f = /_ c grad g
269  i=1 i i
270 
271  where c >= 0, and
272  i
273  c g = 0 for i between 1 and 6
274  i i
275  */
276 
277  matrix_t Mkkt(4, 6);
278  matrix_t::Index col = 0;
279  // Check that constraints are satisfied
280  for (vector6_t::Index j = 0; j < 6; ++j) {
281  BOOST_CHECK(g[j] <= eps);
282  // if constraint is saturated, add gradient in matrix
283  if (fabs(g[j]) <= eps) {
284  Mkkt.col(col) = grad_g.col(j);
285  ++col;
286  }
287  }
288  if (col > 0) {
289  Mkkt.conservativeResize(4, col);
290  // Compute KKT coefficients ci by inverting
291  // Mkkt.c = -grad_f
292  Eigen::JacobiSVD<matrix_t> svd(Mkkt,
293  Eigen::ComputeThinU | Eigen::ComputeThinV);
294  vector_t c(svd.solve(-grad_f));
295  for (vector_t::Index j = 0; j < c.size(); ++j) {
296  BOOST_CHECK_MESSAGE(c[j] >= -eps,
297  "c[" << j << "]{" << c[j] << "} is below " << -eps);
298  }
299  }
300  }
301  std::cerr << "nCol / nTotal = " << nCol << " / " << N << std::endl;
302  std::cerr << "nDiff = " << nDiff << std::endl;
303  // statistics
304  clock_t totalTimeGjkColl = 0;
305  clock_t totalTimeGjkNoColl = 0;
306  for (std::size_t i = 0; i < N; ++i) {
307  if (results[i].collision) {
308  totalTimeGjkColl += results[i].timeGjk;
309  } else {
310  totalTimeGjkNoColl += results[i].timeGjk;
311  }
312  }
313  std::cerr << "Total / average time gjk: "
314  << totalTimeGjkNoColl + totalTimeGjkColl << ", "
315  << CoalScalar(totalTimeGjkNoColl + totalTimeGjkColl) /
316  CoalScalar(CLOCKS_PER_SEC * N)
317  << "s" << std::endl;
318  std::cerr << "-- Collisions -------------------------" << std::endl;
319  std::cerr << "Total / average time gjk: " << totalTimeGjkColl << ", "
320  << CoalScalar(totalTimeGjkColl) / CoalScalar(CLOCKS_PER_SEC * nCol)
321  << "s" << std::endl;
322  std::cerr << "-- No collisions -------------------------" << std::endl;
323  std::cerr << "Total / average time gjk: " << totalTimeGjkNoColl << ", "
324  << CoalScalar(totalTimeGjkNoColl) /
325  CoalScalar(CLOCKS_PER_SEC * (N - nCol))
326  << "s" << std::endl;
327 }
328 
329 BOOST_AUTO_TEST_CASE(distance_triangle_triangle) {
331 }
332 
333 BOOST_AUTO_TEST_CASE(distance_triangle_triangle_nesterov) {
335 }
336 
337 void test_gjk_unit_sphere(CoalScalar center_distance, Vec3s ray,
338  double swept_sphere_radius,
339  bool use_gjk_nesterov_acceleration) {
340  using namespace coal;
341  const CoalScalar r = 1.0;
342  Sphere sphere(r);
343  sphere.setSweptSphereRadius(swept_sphere_radius);
344 
345  typedef Eigen::Matrix<CoalScalar, 4, 1> Vec4f;
346  Transform3s tf0(Quatf(Vec4f::Random().normalized()), Vec3s::Zero());
347  Transform3s tf1(Quatf(Vec4f::Random().normalized()), center_distance * ray);
348 
349  bool expect_collision = center_distance <= 2 * (r + swept_sphere_radius);
350 
353 
354  BOOST_CHECK_EQUAL(shape.swept_sphere_radius[0],
355  sphere.radius + sphere.getSweptSphereRadius());
356  BOOST_CHECK_EQUAL(shape.swept_sphere_radius[1],
357  sphere.radius + sphere.getSweptSphereRadius());
358 
359  details::GJK gjk(2, 1e-6);
360  if (use_gjk_nesterov_acceleration)
362  details::GJK::Status status = gjk.evaluate(shape, Vec3s(1, 0, 0));
363 
364  if (expect_collision) {
365  BOOST_CHECK((status == details::GJK::Collision) ||
367  // For sphere-sphere, if the distance between the centers is above GJK's
368  // tolerance, the `Collision` status should never be returned.
370  center_distance > gjk.getTolerance());
371  } else {
372  BOOST_CHECK_EQUAL(status, details::GJK::NoCollision);
373  }
374 
375  Vec3s w0, w1, normal;
376  gjk.getWitnessPointsAndNormal(shape, w0, w1, normal);
377 
378  Vec3s w0_expected(tf0.inverse().transform(tf0.getTranslation() + ray) +
379  swept_sphere_radius * normal);
380  Vec3s w1_expected(tf0.inverse().transform(tf1.getTranslation() - ray) -
381  swept_sphere_radius * normal);
382 
383  EIGEN_VECTOR_IS_APPROX(w0, w0_expected, 1e-10);
384  EIGEN_VECTOR_IS_APPROX(w1, w1_expected, 1e-10);
385 }
386 
387 BOOST_AUTO_TEST_CASE(sphere_sphere) {
388  std::array<bool, 2> use_nesterov_acceleration = {false, true};
389  std::array<double, 5> swept_sphere_radius = {0., 0.1, 1., 10., 100.};
390  for (bool nesterov_acceleration : use_nesterov_acceleration) {
391  for (double ssr : swept_sphere_radius) {
392  test_gjk_unit_sphere(3, Vec3s(1, 0, 0), ssr, nesterov_acceleration);
393 
394  test_gjk_unit_sphere(2.01, Vec3s(1, 0, 0), ssr, nesterov_acceleration);
395 
396  test_gjk_unit_sphere(2.0, Vec3s(1, 0, 0), ssr, nesterov_acceleration);
397 
398  test_gjk_unit_sphere(1.0, Vec3s(1, 0, 0), ssr, nesterov_acceleration);
399 
400  // Random rotation
401  test_gjk_unit_sphere(3, Vec3s::Random().normalized(), ssr,
402  nesterov_acceleration);
403 
404  test_gjk_unit_sphere(2.01, Vec3s::Random().normalized(), ssr,
405  nesterov_acceleration);
406 
407  test_gjk_unit_sphere(2.0, Vec3s::Random().normalized(), ssr,
408  nesterov_acceleration);
409 
410  test_gjk_unit_sphere(1.0, Vec3s::Random().normalized(), ssr,
411  nesterov_acceleration);
412  }
413  }
414 }
415 
416 void test_gjk_triangle_capsule(Vec3s T, bool expect_collision,
417  bool use_gjk_nesterov_acceleration,
418  Vec3s w0_expected, Vec3s w1_expected) {
419  using namespace coal;
420  Capsule capsule(1., 2.); // Radius 1 and length 2
421  TriangleP triangle(Vec3s(0., 0., 0.), Vec3s(1., 0., 0.), Vec3s(1., 1., 0.));
422 
423  Transform3s tf0, tf1;
424  tf1.setTranslation(T);
425 
427  // No need to take into account swept-sphere radius in supports computation
428  // when using GJK/EPA; after they have converged, these algos will correctly
429  // handle the swept-sphere radius of the shapes.
430  shape.set<details::SupportOptions::NoSweptSphere>(&capsule, &triangle, tf0,
431  tf1);
432 
433  BOOST_CHECK_EQUAL(shape.swept_sphere_radius[0], capsule.radius);
434  BOOST_CHECK_EQUAL(shape.swept_sphere_radius[1], 0.);
435 
436  details::GJK gjk(10, 1e-6);
437  if (use_gjk_nesterov_acceleration)
439  details::GJK::Status status = gjk.evaluate(shape, Vec3s(1, 0, 0));
440 
441  if (expect_collision) {
442  BOOST_CHECK((status == details::GJK::Collision) ||
444  } else {
445  BOOST_CHECK_EQUAL(status, details::GJK::NoCollision);
446 
447  // Check that guess works as expected
448  Vec3s guess = gjk.getGuessFromSimplex();
449  details::GJK gjk2(3, 1e-6);
450  details::GJK::Status status2 = gjk2.evaluate(shape, guess);
451  BOOST_CHECK_EQUAL(status2, details::GJK::NoCollision);
452  }
453 
454  Vec3s w0, w1, normal;
455  if (status == details::GJK::NoCollision ||
457  gjk.getWitnessPointsAndNormal(shape, w0, w1, normal);
458  } else {
459  details::EPA epa(64, 1e-6);
460  details::EPA::Status epa_status = epa.evaluate(gjk, Vec3s(1, 0, 0));
461  BOOST_CHECK_EQUAL(epa_status, details::EPA::AccuracyReached);
462  epa.getWitnessPointsAndNormal(shape, w0, w1, normal);
463  }
464 
465  EIGEN_VECTOR_IS_APPROX(w0, w0_expected, 1e-10);
466  EIGEN_VECTOR_IS_APPROX(w1 - T, w1_expected, 1e-10);
467 }
468 
469 BOOST_AUTO_TEST_CASE(triangle_capsule) {
470  // GJK -> no collision
471  test_gjk_triangle_capsule(Vec3s(1.01, 0, 0), false, false, Vec3s(1., 0, 0),
472  Vec3s(0., 0, 0));
473  // GJK + Nesterov acceleration -> no collision
474  test_gjk_triangle_capsule(Vec3s(1.01, 0, 0), false, true, Vec3s(1., 0, 0),
475  Vec3s(0., 0, 0));
476 
477  // GJK -> collision
478  test_gjk_triangle_capsule(Vec3s(0.5, 0, 0), true, false, Vec3s(1., 0, 0),
479  Vec3s(0., 0, 0));
480  // GJK + Nesterov acceleration -> collision
481  test_gjk_triangle_capsule(Vec3s(0.5, 0, 0), true, true, Vec3s(1., 0, 0),
482  Vec3s(0., 0, 0));
483 
484  // GJK + EPA -> collision
485  test_gjk_triangle_capsule(Vec3s(-0.5, -0.01, 0), true, false, Vec3s(0, 1, 0),
486  Vec3s(0.5, 0, 0));
487  // GJK + Nesterov accleration + EPA -> collision
488  test_gjk_triangle_capsule(Vec3s(-0.5, -0.01, 0), true, true, Vec3s(0, 1, 0),
489  Vec3s(0.5, 0, 0));
490 }
coal::details::EPA::Status
Status
Definition: coal/narrowphase/gjk.h:329
vector4_t
Eigen::Matrix< CoalScalar, 4, 1 > vector4_t
Definition: test/gjk.cpp:60
coal::GJKSolver::gjk
EIGEN_MAKE_ALIGNED_OPERATOR_NEW details::GJK gjk
GJK algorithm.
Definition: coal/narrowphase/narrowphase.h:62
coal::Vec3s
Eigen::Matrix< CoalScalar, 3, 1 > Vec3s
Definition: coal/data_types.h:77
matrix_t
Eigen::Matrix< CoalScalar, Eigen::Dynamic, Eigen::Dynamic > matrix_t
Definition: test/gjk.cpp:61
vector6_t
Eigen::Matrix< CoalScalar, 6, 1 > vector6_t
Definition: test/gjk.cpp:59
coal::details::MinkowskiDiff
Minkowski difference class of two shapes.
Definition: coal/narrowphase/minkowski_difference.h:53
coal::details::GJK::Status
Status
Status of the GJK algorithm: DidNotRun: GJK has not been run. Failed: GJK did not converge (it exceed...
Definition: coal/narrowphase/gjk.h:94
coal::details::GJK::gjk_variant
GJKVariant gjk_variant
Definition: coal/narrowphase/gjk.h:106
collision_manager.sphere
sphere
Definition: collision_manager.py:4
coal::details::EPA
class for EPA algorithm
Definition: coal/narrowphase/gjk.h:258
gjk.tf1
tuple tf1
Definition: test/scripts/gjk.py:27
coal::Capsule
Capsule It is where is the distance between the point x and the capsule segment AB,...
Definition: coal/shape/geometric_shapes.h:383
gjk.P2
tuple P2
Definition: test/scripts/gjk.py:22
distance
double distance(const std::vector< Transform3s > &tf, const BVHModel< BV > &m1, const BVHModel< BV > &m2, bool verbose)
Definition: benchmark.cpp:93
coal
Main namespace.
Definition: coal/broadphase/broadphase_bruteforce.h:44
narrowphase.h
coal::DistanceResult::normal
Vec3s normal
normal.
Definition: coal/collision_data.h:1061
coal::Quatf
Eigen::Quaternion< CoalScalar > Quatf
Definition: coal/math/transform.h:47
utility.h
coal::details::NoSweptSphere
@ NoSweptSphere
Definition: coal/narrowphase/support_functions.h:59
octree.r
r
Definition: octree.py:9
R
R
coal::GJKSolver
collision and distance solver based on the GJK and EPA algorithms. Originally, GJK and EPA were imple...
Definition: coal/narrowphase/narrowphase.h:57
coal::details::EPA::evaluate
Status evaluate(GJK &gjk, const Vec3s &guess)
Definition: src/narrowphase/gjk.cpp:1157
coal::GJKVariant
GJKVariant
Variant to use for the GJK algorithm.
Definition: coal/data_types.h:98
eps
const CoalScalar eps
Definition: obb.cpp:93
coal::Sphere
Center at zero point sphere.
Definition: coal/shape/geometric_shapes.h:240
EIGEN_VECTOR_IS_APPROX
#define EIGEN_VECTOR_IS_APPROX(Va, Vb, precision)
Definition: utility.h:59
coal::Transform3s
Simple transform class used locally by InterpMotion.
Definition: coal/math/transform.h:55
res
res
coal::NesterovAcceleration
@ NesterovAcceleration
Definition: coal/data_types.h:98
coal::details::MinkowskiDiff::swept_sphere_radius
Array2d swept_sphere_radius
The radii of the sphere swepted around each shape of the Minkowski difference. The 2 values correspon...
Definition: coal/narrowphase/minkowski_difference.h:74
coal::details::EPA::AccuracyReached
@ AccuracyReached
Definition: coal/narrowphase/gjk.h:333
shape_shape_func.h
Result::collision
bool collision
Definition: test/gjk.cpp:64
coal::DistanceRequest
request to the distance computation
Definition: coal/collision_data.h:985
gjk.Q1
tuple Q1
Definition: test/scripts/gjk.py:24
gjk.P1
tuple P1
Definition: test/scripts/gjk.py:21
c
c
test_gjk_triangle_capsule
void test_gjk_triangle_capsule(Vec3s T, bool expect_collision, bool use_gjk_nesterov_acceleration, Vec3s w0_expected, Vec3s w1_expected)
Definition: test/gjk.cpp:416
coal::DistanceResult
distance result
Definition: coal/collision_data.h:1051
gjk.tf2
tuple tf2
Definition: test/scripts/gjk.py:36
M
M
coal::details::GJK::CollisionWithPenetrationInformation
@ CollisionWithPenetrationInformation
Definition: coal/narrowphase/gjk.h:99
vector_t
Eigen::Matrix< CoalScalar, Eigen::Dynamic, 1 > vector_t
Definition: test/gjk.cpp:58
Result::timeGjk
clock_t timeGjk
Definition: test/gjk.cpp:65
tools.h
octree.p1
tuple p1
Definition: octree.py:54
Result
Definition: test/gjk.cpp:63
collision
Definition: python_unit/collision.py:1
coal::TriangleP
Triangle stores the points instead of only indices of points.
Definition: coal/shape/geometric_shapes.h:110
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(distance_triangle_triangle)
Definition: test/gjk.cpp:329
coal::internal::ShapeShapeDistance< TriangleP, TriangleP >
CoalScalar ShapeShapeDistance< TriangleP, TriangleP >(const CollisionGeometry *o1, const Transform3s &tf1, const CollisionGeometry *o2, const Transform3s &tf2, const GJKSolver *solver, const bool, Vec3s &p1, Vec3s &p2, Vec3s &normal)
Definition: triangle_triangle.cpp:46
coal::details::GJK::NoCollision
@ NoCollision
Definition: coal/narrowphase/gjk.h:98
coal::details::MinkowskiDiff::set
void set(const ShapeBase *shape0, const ShapeBase *shape1)
Set the two shapes, assuming the relative transformation between them is identity....
Definition: minkowski_difference.cpp:293
gjk.Q3
tuple Q3
Definition: test/scripts/gjk.py:26
coal::Matrix3s
Eigen::Matrix< CoalScalar, 3, 3 > Matrix3s
Definition: coal/data_types.h:81
Results_t
std::vector< Result > Results_t
Definition: test/gjk.cpp:69
coal::details::GJK::evaluate
Status evaluate(const MinkowskiDiff &shape, const Vec3s &guess, const support_func_guess_t &supportHint=support_func_guess_t::Zero())
GJK algorithm, given the initial value guess.
Definition: src/narrowphase/gjk.cpp:187
geometric_shapes.h
coal::details::GJK
class for GJK algorithm
Definition: coal/narrowphase/gjk.h:53
coal::details::GJK::Collision
@ Collision
Definition: coal/narrowphase/gjk.h:100
coal::details::EPA::getWitnessPointsAndNormal
void getWitnessPointsAndNormal(const MinkowskiDiff &shape, Vec3s &w0, Vec3s &w1, Vec3s &normal) const
Definition: src/narrowphase/gjk.cpp:1452
gjk.P3
tuple P3
Definition: test/scripts/gjk.py:23
c2
c2
test_gjk_unit_sphere
void test_gjk_unit_sphere(CoalScalar center_distance, Vec3s ray, double swept_sphere_radius, bool use_gjk_nesterov_acceleration)
Definition: test/gjk.cpp:337
test_gjk_distance_triangle_triangle
void test_gjk_distance_triangle_triangle(bool enable_gjk_nesterov_acceleration)
Definition: test/gjk.cpp:71
coal::CoalScalar
double CoalScalar
Definition: coal/data_types.h:76
coal::DistanceResult::clear
void clear()
clear the result
Definition: coal/collision_data.h:1139
coal::DistanceResult::nearest_points
std::array< Vec3s, 2 > nearest_points
nearest points. See CollisionResult::nearest_points.
Definition: coal/collision_data.h:1065
gjk.Q2
tuple Q2
Definition: test/scripts/gjk.py:25
Result::timeGte
clock_t timeGte
Definition: test/gjk.cpp:66
gjk
Definition: doc/gjk.py:1


hpp-fcl
Author(s):
autogenerated on Sat Nov 23 2024 03:44:58