coal 3.0.2
Coal, The Collision Detection Library. Previously known as HPP-FCL, fork of FCL -- The Flexible Collision Library
Loading...
Searching...
No Matches
narrowphase.h
Go to the documentation of this file.
1/*
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2011-2014, Willow Garage, Inc.
5 * Copyright (c) 2014-2015, Open Source Robotics Foundation
6 * Copyright (c) 2018-2019, Centre National de la Recherche Scientifique
7 * All rights reserved.
8 * Copyright (c) 2021-2024, INRIA
9 * All rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 *
14 * * Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * * Redistributions in binary form must reproduce the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer in the documentation and/or other materials provided
19 * with the distribution.
20 * * Neither the name of Open Source Robotics Foundation nor the names of its
21 * contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
39
40#ifndef COAL_NARROWPHASE_H
41#define COAL_NARROWPHASE_H
42
43#include <limits>
44
48#include "coal/logging.h"
49
50namespace coal {
51
57struct COAL_DLLAPI GJKSolver {
58 public:
59 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
60
63
66
69
72
75 COAL_DEPRECATED_MESSAGE(Use gjk_initial_guess instead)
77
80
83
87
90
93
96
98 mutable details::EPA epa;
99
102
105
107 mutable details::MinkowskiDiff minkowski_difference;
108
109 private:
110 // Used internally for assertion checks.
111 static constexpr CoalScalar m_dummy_precision = 1e-6;
112
113 public:
138
148 explicit GJKSolver(const DistanceRequest& request)
149 : gjk(request.gjk_max_iterations, request.gjk_tolerance),
150 epa(0, request.epa_tolerance) {
151 this->cached_guess = Vec3s(1, 0, 0);
152 this->support_func_cached_guess = support_func_guess_t::Zero();
153
154 set(request);
155 }
156
161 void set(const DistanceRequest& request) {
162 // ---------------------
163 // GJK settings
164 this->gjk_initial_guess = request.gjk_initial_guess;
166 if (this->gjk_initial_guess == GJKInitialGuess::CachedGuess ||
167 this->enable_cached_guess) {
168 this->cached_guess = request.cached_gjk_guess;
170 }
171 this->gjk_max_iterations = request.gjk_max_iterations;
172 this->gjk_tolerance = request.gjk_tolerance;
173 // For distance computation, we don't want GJK to early stop
174 this->distance_upper_bound = (std::numeric_limits<CoalScalar>::max)();
175 this->gjk_variant = request.gjk_variant;
179
180 // ---------------------
181 // EPA settings
183 this->epa_tolerance = request.epa_tolerance;
184
185 // ---------------------
186 // Reset GJK and EPA status
189 }
190
200 explicit GJKSolver(const CollisionRequest& request)
201 : gjk(request.gjk_max_iterations, request.gjk_tolerance),
202 epa(0, request.epa_tolerance) {
203 this->cached_guess = Vec3s(1, 0, 0);
204 this->support_func_cached_guess = support_func_guess_t::Zero();
205
206 set(request);
207 }
208
213 void set(const CollisionRequest& request) {
214 // ---------------------
215 // GJK settings
216 this->gjk_initial_guess = request.gjk_initial_guess;
218 if (this->gjk_initial_guess == GJKInitialGuess::CachedGuess ||
219 this->enable_cached_guess) {
220 this->cached_guess = request.cached_gjk_guess;
222 }
223 this->gjk_tolerance = request.gjk_tolerance;
224 this->gjk_max_iterations = request.gjk_max_iterations;
225 // The distance upper bound should be at least greater to the requested
226 // security margin. Otherwise, we will likely miss some collisions.
227 this->distance_upper_bound = (std::max)(
228 0., (std::max)(request.distance_upper_bound, request.security_margin));
229 this->gjk_variant = request.gjk_variant;
233
234 // ---------------------
235 // EPA settings
237 this->epa_tolerance = request.epa_tolerance;
238
239 // ---------------------
240 // Reset GJK and EPA status
243 }
244
246 GJKSolver(const GJKSolver& other) = default;
247
250 bool operator==(const GJKSolver& other) const {
251 return this->enable_cached_guess ==
252 other.enable_cached_guess && // use gjk_initial_guess instead
253 this->cached_guess == other.cached_guess &&
255 this->gjk_max_iterations == other.gjk_max_iterations &&
256 this->gjk_tolerance == other.gjk_tolerance &&
258 this->gjk_variant == other.gjk_variant &&
262 this->gjk_initial_guess == other.gjk_initial_guess &&
264 this->epa_tolerance == other.epa_tolerance;
265 }
267
268 bool operator!=(const GJKSolver& other) const { return !(*this == other); }
269
272 CoalScalar getDistancePrecision(const bool compute_penetration) const {
273 return compute_penetration
274 ? (std::max)(this->gjk_tolerance, this->epa_tolerance)
275 : this->gjk_tolerance;
276 }
277
307 template <typename S1, typename S2>
308 CoalScalar shapeDistance(const S1& s1, const Transform3s& tf1, const S2& s2,
309 const Transform3s& tf2,
310 const bool compute_penetration, Vec3s& p1, Vec3s& p2,
311 Vec3s& normal) const {
312 constexpr bool relative_transformation_already_computed = false;
314 this->runGJKAndEPA(s1, tf1, s2, tf2, compute_penetration, distance, p1, p2,
315 normal, relative_transformation_already_computed);
316 return distance;
317 }
318
322 template <typename S1>
323 CoalScalar shapeDistance(const S1& s1, const Transform3s& tf1,
324 const TriangleP& s2, const Transform3s& tf2,
325 const bool compute_penetration, Vec3s& p1, Vec3s& p2,
326 Vec3s& normal) const {
327 const Transform3s tf_1M2(tf1.inverseTimes(tf2));
328 TriangleP tri(tf_1M2.transform(s2.a), tf_1M2.transform(s2.b),
329 tf_1M2.transform(s2.c));
330
331 constexpr bool relative_transformation_already_computed = true;
333 this->runGJKAndEPA(s1, tf1, tri, tf_1M2, compute_penetration, distance, p1,
334 p2, normal, relative_transformation_already_computed);
335 return distance;
336 }
337
339 template <typename S2>
341 const S2& s2, const Transform3s& tf2,
342 const bool compute_penetration, Vec3s& p1, Vec3s& p2,
343 Vec3s& normal) const {
345 s2, tf2, s1, tf1, compute_penetration, p2, p1, normal);
346 normal = -normal;
347 return distance;
348 }
349
350 protected:
353 template <typename S1, typename S2>
354 void getGJKInitialGuess(const S1& s1, const S2& s2, Vec3s& guess,
355 support_func_guess_t& support_hint,
356 const Vec3s& default_guess = Vec3s(1, 0, 0)) const {
357 // There is no reason not to warm-start the support function, so we always
358 // do it.
359 support_hint = this->support_func_cached_guess;
360 // The following switch takes care of the GJK warm-start.
361 switch (gjk_initial_guess) {
363 guess = default_guess;
364 break;
366 guess = this->cached_guess;
367 break;
369 if (s1.aabb_local.volume() < 0 || s2.aabb_local.volume() < 0) {
371 "computeLocalAABB must have been called on the shapes before "
372 "using "
373 "GJKInitialGuess::BoundingVolumeGuess.",
374 std::logic_error);
375 }
376 guess.noalias() =
377 s1.aabb_local.center() -
378 (this->minkowski_difference.oR1 * s2.aabb_local.center() +
379 this->minkowski_difference.ot1);
380 break;
381 default:
382 COAL_THROW_PRETTY("Wrong initial guess for GJK.", std::logic_error);
383 }
384 // TODO: use gjk_initial_guess instead
387 if (this->enable_cached_guess) {
388 guess = this->cached_guess;
389 }
391 }
392
420 template <typename S1, typename S2,
421 int _SupportOptions = details::SupportOptions::NoSweptSphere>
423 const S1& s1, const Transform3s& tf1, const S2& s2,
424 const Transform3s& tf2, const bool compute_penetration,
425 CoalScalar& distance, Vec3s& p1, Vec3s& p2, Vec3s& normal,
426 const bool relative_transformation_already_computed = false) const {
427 // Reset internal state of GJK algorithm
428 if (relative_transformation_already_computed)
429 this->minkowski_difference.set<_SupportOptions>(&s1, &s2);
430 else
431 this->minkowski_difference.set<_SupportOptions>(&s1, &s2, tf1, tf2);
432 this->gjk.reset(this->gjk_max_iterations, this->gjk_tolerance);
434 this->gjk.gjk_variant = this->gjk_variant;
438
439 // Get initial guess for GJK: default, cached or bounding volume guess
440 Vec3s guess;
441 support_func_guess_t support_hint;
443 *(this->minkowski_difference.shapes[1]), guess,
444 support_hint);
445
446 this->gjk.evaluate(this->minkowski_difference, guess, support_hint);
447
448 switch (this->gjk.status) {
450 COAL_ASSERT(false, "GJK did not run. It should have!",
451 std::logic_error);
452 this->cached_guess = Vec3s(1, 0, 0);
453 this->support_func_cached_guess.setZero();
454 distance = -(std::numeric_limits<CoalScalar>::max)();
455 p1 = p2 = normal =
456 Vec3s::Constant(std::numeric_limits<CoalScalar>::quiet_NaN());
457 break;
459 //
460 // GJK ran out of iterations.
461 COAL_LOG_WARNING("GJK ran out of iterations.");
462 GJKExtractWitnessPointsAndNormal(tf1, distance, p1, p2, normal);
463 break;
465 //
466 // Case where GJK early stopped because the distance was found to be
467 // above the `distance_upper_bound`.
468 // The two witness points have no meaning.
470 normal);
472 this->m_dummy_precision,
473 "The distance should be bigger than GJK's "
474 "`distance_upper_bound`.",
475 std::logic_error);
476 break;
478 //
479 // Case where GJK converged and proved that the shapes are not in
480 // collision, i.e their distance is above GJK's tolerance (default
481 // 1e-6).
482 GJKExtractWitnessPointsAndNormal(tf1, distance, p1, p2, normal);
483 COAL_ASSERT(std::abs((p1 - p2).norm() - distance) <=
484 this->gjk.getTolerance() + this->m_dummy_precision,
485 "The distance found by GJK should coincide with the "
486 "distance between the closest points.",
487 std::logic_error);
488 break;
489 //
490 // Next are the cases where GJK found the shapes to be in collision, i.e.
491 // their distance is below GJK's tolerance (default 1e-6).
493 GJKExtractWitnessPointsAndNormal(tf1, distance, p1, p2, normal);
495 distance <= this->gjk.getTolerance() + this->m_dummy_precision,
496 "The distance found by GJK should be negative or at "
497 "least below GJK's tolerance.",
498 std::logic_error);
499 break;
501 if (!compute_penetration) {
502 // Skip EPA and set the witness points and the normal to nans.
504 normal);
505 } else {
506 //
507 // GJK was not enough to recover the penetration information.
508 // We need to run the EPA algorithm to find the witness points,
509 // penetration depth and the normal.
510
511 // Reset EPA algorithm. Potentially allocate memory if
512 // `epa_max_face_num` or `epa_max_vertex_num` are bigger than EPA's
513 // current storage.
514 this->epa.reset(this->epa_max_iterations, this->epa_tolerance);
515
516 // TODO: understand why EPA's performance is so bad on cylinders and
517 // cones.
518 this->epa.evaluate(this->gjk, -guess);
519
520 switch (epa.status) {
521 //
522 // In the following switch cases, until the "Valid" case,
523 // EPA either ran out of iterations, of faces or of vertices.
524 // The depth, witness points and the normal are still valid,
525 // simply not at the precision of EPA's tolerance.
526 // The flag `COAL_ENABLE_LOGGING` enables feebdack on these
527 // cases.
528 //
529 // TODO: Remove OutOfFaces and OutOfVertices statuses and simply
530 // compute the upper bound on max faces and max vertices as a
531 // function of the number of iterations.
533 COAL_LOG_WARNING("EPA ran out of faces.");
534 EPAExtractWitnessPointsAndNormal(tf1, distance, p1, p2, normal);
535 break;
537 COAL_LOG_WARNING("EPA ran out of vertices.");
538 EPAExtractWitnessPointsAndNormal(tf1, distance, p1, p2, normal);
539 break;
541 COAL_LOG_WARNING("EPA ran out of iterations.");
542 EPAExtractWitnessPointsAndNormal(tf1, distance, p1, p2, normal);
543 break;
547 -epa.depth <= epa.getTolerance() + this->m_dummy_precision,
548 "EPA's penetration distance should be negative (or "
549 "at least below EPA's tolerance).",
550 std::logic_error);
551 EPAExtractWitnessPointsAndNormal(tf1, distance, p1, p2, normal);
552 break;
555 "EPA warning: created a polytope with a degenerated face.");
556 EPAExtractWitnessPointsAndNormal(tf1, distance, p1, p2, normal);
557 break;
560 "EPA warning: EPA got called onto non-convex shapes.");
561 EPAExtractWitnessPointsAndNormal(tf1, distance, p1, p2, normal);
562 break;
564 COAL_LOG_WARNING("EPA warning: created an invalid polytope.");
565 EPAExtractWitnessPointsAndNormal(tf1, distance, p1, p2, normal);
566 break;
568 COAL_ASSERT(false, "EPA did not run. It should have!",
569 std::logic_error);
570 COAL_LOG_ERROR("EPA error: did not run. It should have.");
572 normal);
573 break;
576 false,
577 "EPA went into fallback mode. It should never do that.",
578 std::logic_error);
579 COAL_LOG_ERROR("EPA error: FallBack.");
581 normal);
582 break;
583 }
584 }
585 break; // End of case details::GJK::Collision
586 }
587 }
588
591 Vec3s& p1, Vec3s& p2,
592 Vec3s& normal) const {
594 // Cache gjk result for potential future call to this GJKSolver.
595 this->cached_guess = this->gjk.ray;
597
598 distance = this->gjk.distance;
599 p1 = p2 = normal =
600 Vec3s::Constant(std::numeric_limits<CoalScalar>::quiet_NaN());
601 // If we absolutely want to return some witness points, we could use
602 // the following code (or simply merge the early stopped case with the
603 // valid case below):
604 // gjk.getWitnessPointsAndNormal(minkowski_difference, p1, p2, normal);
605 // p1 = tf1.transform(p1);
606 // p2 = tf1.transform(p2);
607 // normal = tf1.getRotation() * normal;
608 }
609
612 Vec3s& p2, Vec3s& normal) const {
613 // Apart from early stopping, there are two cases where GJK says there is no
614 // collision:
615 // 1. GJK proved the distance is above its tolerance (default 1e-6).
616 // 2. GJK ran out of iterations.
617 // In any case, `gjk.ray`'s norm is bigger than GJK's tolerance and thus
618 // it can safely be normalized.
619 COAL_ASSERT(this->gjk.ray.norm() >
620 this->gjk.getTolerance() - this->m_dummy_precision,
621 "The norm of GJK's ray should be bigger than GJK's tolerance.",
622 std::logic_error);
623 // Cache gjk result for potential future call to this GJKSolver.
624 this->cached_guess = this->gjk.ray;
626
627 distance = this->gjk.distance;
628 // TODO: On degenerated case, the closest points may be non-unique.
629 // (i.e. an object face normal is colinear to `gjk.ray`)
630 gjk.getWitnessPointsAndNormal(this->minkowski_difference, p1, p2, normal);
631 Vec3s p = tf1.transform(0.5 * (p1 + p2));
632 normal = tf1.getRotation() * normal;
633 p1.noalias() = p - 0.5 * distance * normal;
634 p2.noalias() = p + 0.5 * distance * normal;
635 }
636
639 Vec3s& p1, Vec3s& p2,
640 Vec3s& normal) const {
642 COAL_ASSERT(this->gjk.distance <=
643 this->gjk.getTolerance() + this->m_dummy_precision,
644 "The distance should be lower than GJK's tolerance.",
645 std::logic_error);
646 // Because GJK has returned the `Collision` status and EPA has not run,
647 // we purposefully do not cache the result of GJK, because ray is zero.
648 // However, we can cache the support function hint.
649 // this->cached_guess = this->gjk.ray;
651
652 distance = this->gjk.distance;
653 p1 = p2 = normal =
654 Vec3s::Constant(std::numeric_limits<CoalScalar>::quiet_NaN());
655 }
656
659 Vec3s& p2, Vec3s& normal) const {
660 // Cache EPA result for potential future call to this GJKSolver.
661 // This caching allows to warm-start the next GJK call.
662 this->cached_guess = -(this->epa.depth * this->epa.normal);
663 this->support_func_cached_guess = this->epa.support_hint;
664 distance = (std::min)(0., -this->epa.depth);
665 this->epa.getWitnessPointsAndNormal(this->minkowski_difference, p1, p2,
666 normal);
667 // The following is very important to understand why EPA can sometimes
668 // return a normal that is not colinear to the vector $p_1 - p_2$ when
669 // working with tolerances like $\epsilon = 10^{-3}$.
670 // It can be resumed with a simple idea:
671 // EPA is an algorithm meant to find the penetration depth and the
672 // normal. It is not meant to find the closest points.
673 // Again, the issue here is **not** the normal, it's $p_1$ and $p_2$.
674 //
675 // More details:
676 // We'll denote $S_1$ and $S_2$ the two shapes, $n$ the normal and $p_1$ and
677 // $p_2$ the witness points. In theory, when EPA converges to $\epsilon =
678 // 0$, the normal and witness points verify the following property (P):
679 // - $p_1 \in \partial \sigma_{S_1}(n)$,
680 // - $p_2 \in \partial \sigma_{S_2}(-n),
681 // where $\sigma_{S_1}$ and $\sigma_{S_2}$ are the support functions of
682 // $S_1$ and $S_2$. The $\partial \sigma(n)$ simply denotes the support set
683 // of the support function in the direction $n$. (Note: I am leaving out the
684 // details of frame choice for the support function, to avoid making the
685 // mathematical notation too heavy.)
686 // --> In practice, EPA converges to $\epsilon > 0$.
687 // On polytopes and the likes, this does not change much and the property
688 // given above is still valid.
689 // --> However, this is very different on curved surfaces, such as
690 // ellipsoids, cylinders, cones, capsules etc. For these shapes, converging
691 // at $\epsilon = 10^{-6}$ or to $\epsilon = 10^{-3}$ does not change the
692 // normal much, but the property (P) given above is no longer valid, which
693 // means that the points $p_1$ and $p_2$ do not necessarily belong to the
694 // support sets in the direction of $n$ and thus $n$ and $p_1 - p_2$ are not
695 // colinear.
696 //
697 // Do not panic! This is fine.
698 // Although the property above is not verified, it's almost verified,
699 // meaning that $p_1$ and $p_2$ belong to support sets in directions that
700 // are very close to $n$.
701 //
702 // Solution to compute better $p_1$ and $p_2$:
703 // We compute the middle points of the current $p_1$ and $p_2$ and we use
704 // the normal and the distance given by EPA to compute the new $p_1$ and
705 // $p_2$.
706 Vec3s p = tf1.transform(0.5 * (p1 + p2));
707 normal = tf1.getRotation() * normal;
708 p1.noalias() = p - 0.5 * distance * normal;
709 p2.noalias() = p + 0.5 * distance * normal;
710 }
711
714 Vec3s& p2, Vec3s& normal) const {
715 this->cached_guess = Vec3s(1, 0, 0);
716 this->support_func_cached_guess.setZero();
717
719 distance = -(std::numeric_limits<CoalScalar>::max)();
720 p1 = p2 = normal =
721 Vec3s::Constant(std::numeric_limits<CoalScalar>::quiet_NaN());
722 }
723};
724
725} // namespace coal
726
727#endif
Simple transform class used locally by InterpMotion.
Definition transform.h:55
Vec3s transform(const Eigen::MatrixBase< Derived > &v) const
transform a given vector by the transform
Definition transform.h:152
const Matrix3s & getRotation() const
get rotation
Definition transform.h:110
Transform3s inverseTimes(const Transform3s &other) const
inverse the transform and multiply with another
Definition transform.h:175
Triangle stores the points instead of only indices of points.
Definition geometric_shapes.h:110
#define COAL_COMPILER_DIAGNOSTIC_IGNORED_DEPRECECATED_DECLARATIONS
Definition fwd.hh:122
#define COAL_ASSERT(check, message, exception)
Definition fwd.hh:82
#define COAL_UNUSED_VARIABLE(var)
Definition fwd.hh:56
#define COAL_COMPILER_DIAGNOSTIC_PUSH
Definition fwd.hh:120
#define COAL_COMPILER_DIAGNOSTIC_POP
Definition fwd.hh:121
#define COAL_THROW_PRETTY(message, exception)
Definition fwd.hh:64
CoalScalar distance(const Matrix3s &R0, const Vec3s &T0, const kIOS &b1, const kIOS &b2, Vec3s *P=NULL, Vec3s *Q=NULL)
Approximate distance between two kIOS bounding volumes.
Vec3s a
Definition geometric_shapes.h:149
Vec3s b
Definition geometric_shapes.h:149
Vec3s c
Definition geometric_shapes.h:149
#define COAL_LOG_ERROR(message)
Definition logging.h:51
#define COAL_LOG_WARNING(message)
Definition logging.h:50
Definition hfield.h:170
@ NoSweptSphere
Definition support_functions.h:59
Main namespace.
Definition broadphase_bruteforce.h:44
GJKConvergenceCriterionType
Wether the convergence criterion is scaled on the norm of the solution or not.
Definition data_types.h:108
@ Absolute
Definition data_types.h:108
constexpr size_t GJK_DEFAULT_MAX_ITERATIONS
GJK.
Definition narrowphase_defaults.h:46
constexpr size_t EPA_DEFAULT_MAX_ITERATIONS
Definition narrowphase_defaults.h:59
constexpr CoalScalar EPA_DEFAULT_TOLERANCE
Definition narrowphase_defaults.h:60
constexpr CoalScalar GJK_DEFAULT_TOLERANCE
Definition narrowphase_defaults.h:47
Eigen::Vector2i support_func_guess_t
Definition data_types.h:87
GJKConvergenceCriterion
Which convergence criterion is used to stop the algorithm (when the shapes are not in collision)....
Definition data_types.h:104
@ Default
Definition data_types.h:104
GJKInitialGuess
Initial guess to use for the GJK algorithm DefaultGuess: Vec3s(1, 0, 0) CachedGuess: previous vector ...
Definition data_types.h:95
@ DefaultGuess
Definition data_types.h:95
@ BoundingVolumeGuess
Definition data_types.h:95
@ CachedGuess
Definition data_types.h:95
Eigen::Matrix< CoalScalar, 3, 1 > Vec3s
Definition data_types.h:77
double CoalScalar
Definition data_types.h:76
GJKVariant
Variant to use for the GJK algorithm.
Definition data_types.h:98
@ DefaultGJK
Definition data_types.h:98
request to the collision algorithm
Definition collision_data.h:311
CoalScalar security_margin
Distance below which objects are considered in collision. See Collision.
Definition collision_data.h:328
CoalScalar distance_upper_bound
Distance above which GJK solver makes an early stopping. GJK stops searching for the closest points w...
Definition collision_data.h:340
request to the distance computation
Definition collision_data.h:985
bool operator!=(const GJKSolver &other) const
Definition narrowphase.h:268
void set(const CollisionRequest &request)
setter from a CollisionRequest
Definition narrowphase.h:213
GJKSolver(const GJKSolver &other)=default
Copy constructor.
CoalScalar shapeDistance(const TriangleP &s1, const Transform3s &tf1, const S2 &s2, const Transform3s &tf2, const bool compute_penetration, Vec3s &p1, Vec3s &p2, Vec3s &normal) const
See other partial template specialization of shapeDistance above.
Definition narrowphase.h:340
void GJKExtractWitnessPointsAndNormal(const Transform3s &tf1, CoalScalar &distance, Vec3s &p1, Vec3s &p2, Vec3s &normal) const
Definition narrowphase.h:610
CoalScalar gjk_tolerance
tolerance of GJK
Definition narrowphase.h:68
size_t gjk_max_iterations
maximum number of iterations of GJK
Definition narrowphase.h:65
CoalScalar epa_tolerance
tolerance of EPA
Definition narrowphase.h:104
size_t epa_max_iterations
maximum number of iterations of EPA
Definition narrowphase.h:101
GJKSolver(const CollisionRequest &request)
Constructor from a CollisionRequest.
Definition narrowphase.h:200
CoalScalar shapeDistance(const S1 &s1, const Transform3s &tf1, const TriangleP &s2, const Transform3s &tf2, const bool compute_penetration, Vec3s &p1, Vec3s &p2, Vec3s &normal) const
Partial specialization of shapeDistance for the case where the second shape is a triangle....
Definition narrowphase.h:323
GJKInitialGuess gjk_initial_guess
which warm start to use for GJK
Definition narrowphase.h:71
EIGEN_MAKE_ALIGNED_OPERATOR_NEW details::GJK gjk
GJK algorithm.
Definition narrowphase.h:62
GJKConvergenceCriterion gjk_convergence_criterion
Convergence criterion for GJK.
Definition narrowphase.h:92
void EPAFailedExtractWitnessPointsAndNormal(const Transform3s &tf1, CoalScalar &distance, Vec3s &p1, Vec3s &p2, Vec3s &normal) const
Definition narrowphase.h:712
void EPAExtractWitnessPointsAndNormal(const Transform3s &tf1, CoalScalar &distance, Vec3s &p1, Vec3s &p2, Vec3s &normal) const
Definition narrowphase.h:657
GJKConvergenceCriterionType gjk_convergence_criterion_type
Absolute or relative convergence criterion for GJK.
Definition narrowphase.h:95
void GJKCollisionExtractWitnessPointsAndNormal(const Transform3s &tf1, CoalScalar &distance, Vec3s &p1, Vec3s &p2, Vec3s &normal) const
Definition narrowphase.h:637
bool enable_cached_guess
Whether smart guess can be provided @Deprecated Use gjk_initial_guess instead.
Definition narrowphase.h:76
void runGJKAndEPA(const S1 &s1, const Transform3s &tf1, const S2 &s2, const Transform3s &tf2, const bool compute_penetration, CoalScalar &distance, Vec3s &p1, Vec3s &p2, Vec3s &normal, const bool relative_transformation_already_computed=false) const
Runs the GJK algorithm.
Definition narrowphase.h:422
void getGJKInitialGuess(const S1 &s1, const S2 &s2, Vec3s &guess, support_func_guess_t &support_hint, const Vec3s &default_guess=Vec3s(1, 0, 0)) const
initialize GJK. This method assumes minkowski_difference has been set.
Definition narrowphase.h:354
GJKSolver(const DistanceRequest &request)
Constructor from a DistanceRequest.
Definition narrowphase.h:148
GJKSolver()
Default constructor for GJK algorithm By default, we don't want EPA to allocate memory because certai...
Definition narrowphase.h:123
CoalScalar distance_upper_bound
If GJK can guarantee that the distance between the shapes is greater than this value,...
Definition narrowphase.h:86
Vec3s cached_guess
smart guess
Definition narrowphase.h:79
void set(const DistanceRequest &request)
setter from a DistanceRequest
Definition narrowphase.h:161
CoalScalar getDistancePrecision(const bool compute_penetration) const
Helper to return the precision of the solver on the distance estimate, depending on whether or not co...
Definition narrowphase.h:272
support_func_guess_t support_func_cached_guess
smart guess for the support function
Definition narrowphase.h:82
void GJKEarlyStopExtractWitnessPointsAndNormal(const Transform3s &tf1, CoalScalar &distance, Vec3s &p1, Vec3s &p2, Vec3s &normal) const
Definition narrowphase.h:589
GJKVariant gjk_variant
Variant of the GJK algorithm (Default, Nesterov or Polyak).
Definition narrowphase.h:89
details::EPA epa
EPA algorithm.
Definition narrowphase.h:98
CoalScalar shapeDistance(const S1 &s1, const Transform3s &tf1, const S2 &s2, const Transform3s &tf2, const bool compute_penetration, Vec3s &p1, Vec3s &p2, Vec3s &normal) const
Uses GJK and EPA to compute the distance between two shapes.
Definition narrowphase.h:308
details::MinkowskiDiff minkowski_difference
Minkowski difference used by GJK and EPA algorithms.
Definition narrowphase.h:107
bool operator==(const GJKSolver &other) const
Definition narrowphase.h:250
CoalScalar epa_tolerance
tolerance for EPA. Note: This tolerance determines the precision on the estimated distance between tw...
Definition collision_data.h:211
Vec3s cached_gjk_guess
the gjk initial guess set by user
Definition collision_data.h:180
size_t epa_max_iterations
max number of iterations for EPA
Definition collision_data.h:204
GJKConvergenceCriterion gjk_convergence_criterion
convergence criterion used to stop GJK
Definition collision_data.h:198
support_func_guess_t cached_support_func_guess
the support function initial guess set by user
Definition collision_data.h:183
CoalScalar gjk_tolerance
tolerance for the GJK algorithm. Note: This tolerance determines the precision on the estimated dista...
Definition collision_data.h:192
bool enable_cached_gjk_guess
whether enable gjk initial guess @Deprecated Use gjk_initial_guess instead
Definition collision_data.h:177
GJKVariant gjk_variant
whether to enable the Nesterov accleration of GJK
Definition collision_data.h:195
GJKConvergenceCriterionType gjk_convergence_criterion_type
convergence criterion used to stop GJK
Definition collision_data.h:201
GJKInitialGuess gjk_initial_guess
Definition collision_data.h:172
size_t gjk_max_iterations
maximum iteration for the GJK algorithm
Definition collision_data.h:186
@ AccuracyReached
Definition gjk.h:333
@ DidNotRun
Definition gjk.h:330
@ InvalidHull
Definition gjk.h:336
@ OutOfFaces
Definition gjk.h:337
@ Failed
Definition gjk.h:331
@ Valid
Definition gjk.h:332
@ Degenerated
Definition gjk.h:334
@ OutOfVertices
Definition gjk.h:338
@ NonConvex
Definition gjk.h:335
@ FallBack
Definition gjk.h:339
class for GJK algorithm
Definition gjk.h:53
void reset(size_t max_iterations_, CoalScalar tolerance_)
resets the GJK algorithm, preparing it for a new run. Other than the maximum number of iterations and...
GJKConvergenceCriterionType convergence_criterion_type
Definition gjk.h:108
void setDistanceEarlyBreak(const CoalScalar &dup)
Distance threshold for early break. GJK stops when it proved the distance is more than this threshold...
Definition gjk.h:194
support_func_guess_t support_hint
Definition gjk.h:112
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.
GJKVariant gjk_variant
Definition gjk.h:106
CoalScalar distance
The distance between the two shapes, computed by GJK. If the distance is below GJK's threshold,...
Definition gjk.h:118
CoalScalar distance_upper_bound
Definition gjk.h:104
Vec3s ray
Definition gjk.h:111
GJKConvergenceCriterion convergence_criterion
Definition gjk.h:107
@ Collision
Definition gjk.h:100
@ DidNotRun
Definition gjk.h:95
@ Failed
Definition gjk.h:96
@ NoCollisionEarlyStopped
Definition gjk.h:97
@ CollisionWithPenetrationInformation
Definition gjk.h:99
@ NoCollision
Definition gjk.h:98
CoalScalar getTolerance() const
Get the tolerance of GJK.
Definition gjk.h:207
Status status
Definition gjk.h:105