40 #ifndef COAL_NARROWPHASE_H
41 #define COAL_NARROWPHASE_H
59 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
76 bool enable_cached_guess;
98 mutable details::EPA epa;
101 size_t epa_max_iterations;
107 mutable details::MinkowskiDiff minkowski_difference;
111 static constexpr
CoalScalar m_dummy_precision = 1e-6;
128 enable_cached_guess(false),
129 cached_guess(
Vec3s(1, 0, 0)),
131 distance_upper_bound((std::numeric_limits<
CoalScalar>::max)()),
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();
167 this->enable_cached_guess) {
174 this->distance_upper_bound = (std::numeric_limits<CoalScalar>::max)();
177 this->gjk_convergence_criterion_type =
187 this->epa.status = details::EPA::Status::DidNotRun;
188 this->gjk.
status = details::GJK::Status::DidNotRun;
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();
219 this->enable_cached_guess) {
227 this->distance_upper_bound = (std::max)(
231 this->gjk_convergence_criterion_type =
241 this->gjk.
status = details::GJK::Status::DidNotRun;
242 this->epa.status = details::EPA::Status::DidNotRun;
251 return this->enable_cached_guess ==
260 this->gjk_convergence_criterion_type ==
273 return compute_penetration
274 ? (std::max)(this->gjk_tolerance, this->epa_tolerance)
275 : this->gjk_tolerance;
307 template <
typename S1,
typename S2>
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);
322 template <
typename S1>
325 const bool compute_penetration,
Vec3s& p1,
Vec3s& p2,
326 Vec3s& normal)
const {
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);
339 template <
typename S2>
342 const bool compute_penetration,
Vec3s& p1,
Vec3s& p2,
343 Vec3s& normal)
const {
345 s2, tf2, s1, tf1, compute_penetration, p2, p1, normal);
353 template <
typename S1,
typename S2>
356 const Vec3s& default_guess =
Vec3s(1, 0, 0))
const {
359 support_hint = this->support_func_cached_guess;
361 switch (gjk_initial_guess) {
363 guess = default_guess;
366 guess = this->cached_guess;
369 if (s1.aabb_local.volume() < 0 || s2.aabb_local.volume() < 0) {
371 "computeLocalAABB must have been called on the shapes before "
373 "GJKInitialGuess::BoundingVolumeGuess.",
377 s1.aabb_local.center() -
378 (this->minkowski_difference.oR1 * s2.aabb_local.center() +
379 this->minkowski_difference.ot1);
387 if (this->enable_cached_guess) {
388 guess = this->cached_guess;
420 template <
typename S1,
typename S2,
423 const S1& s1,
const Transform3s& tf1,
const S2& s2,
424 const Transform3s& tf2,
const bool compute_penetration,
426 const bool relative_transformation_already_computed =
false)
const {
428 if (relative_transformation_already_computed)
429 this->minkowski_difference.set<_SupportOptions>(&s1, &s2);
431 this->minkowski_difference.set<_SupportOptions>(&s1, &s2, tf1, tf2);
432 this->gjk.
reset(this->gjk_max_iterations, this->gjk_tolerance);
437 this->epa.status = details::EPA::Status::DidNotRun;
442 getGJKInitialGuess(*(this->minkowski_difference.shapes[0]),
443 *(this->minkowski_difference.shapes[1]), guess,
446 this->gjk.
evaluate(this->minkowski_difference, guess, support_hint);
448 switch (this->gjk.
status) {
450 COAL_ASSERT(
false,
"GJK did not run. It should have!",
452 this->cached_guess =
Vec3s(1, 0, 0);
453 this->support_func_cached_guess.setZero();
454 distance = -(std::numeric_limits<CoalScalar>::max)();
456 Vec3s::Constant(std::numeric_limits<CoalScalar>::quiet_NaN());
462 GJKExtractWitnessPointsAndNormal(tf1,
distance, p1, p2, normal);
469 GJKEarlyStopExtractWitnessPointsAndNormal(tf1,
distance, p1, p2,
472 this->m_dummy_precision,
473 "The distance should be bigger than GJK's "
474 "`distance_upper_bound`.",
482 GJKExtractWitnessPointsAndNormal(tf1,
distance, p1, p2, normal);
485 "The distance found by GJK should coincide with the "
486 "distance between the closest points.",
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.",
501 if (!compute_penetration) {
503 GJKCollisionExtractWitnessPointsAndNormal(tf1,
distance, p1, p2,
514 this->epa.reset(this->epa_max_iterations, this->epa_tolerance);
518 this->epa.evaluate(this->gjk, -guess);
520 switch (epa.status) {
534 EPAExtractWitnessPointsAndNormal(tf1,
distance, p1, p2, normal);
538 EPAExtractWitnessPointsAndNormal(tf1,
distance, p1, p2, normal);
542 EPAExtractWitnessPointsAndNormal(tf1,
distance, p1, p2, normal);
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).",
551 EPAExtractWitnessPointsAndNormal(tf1,
distance, p1, p2, normal);
555 "EPA warning: created a polytope with a degenerated face.");
556 EPAExtractWitnessPointsAndNormal(tf1,
distance, p1, p2, normal);
560 "EPA warning: EPA got called onto non-convex shapes.");
561 EPAExtractWitnessPointsAndNormal(tf1,
distance, p1, p2, normal);
565 EPAExtractWitnessPointsAndNormal(tf1,
distance, p1, p2, normal);
568 COAL_ASSERT(
false,
"EPA did not run. It should have!",
571 EPAFailedExtractWitnessPointsAndNormal(tf1,
distance, p1, p2,
577 "EPA went into fallback mode. It should never do that.",
580 EPAFailedExtractWitnessPointsAndNormal(tf1,
distance, p1, p2,
592 Vec3s& normal)
const {
595 this->cached_guess = this->gjk.
ray;
596 this->support_func_cached_guess = this->gjk.
support_hint;
600 Vec3s::Constant(std::numeric_limits<CoalScalar>::quiet_NaN());
620 this->gjk.getTolerance() - this->m_dummy_precision,
621 "The norm of GJK's ray should be bigger than GJK's tolerance.",
624 this->cached_guess = this->gjk.
ray;
625 this->support_func_cached_guess = this->gjk.
support_hint;
633 p1.noalias() = p - 0.5 *
distance * normal;
634 p2.noalias() = p + 0.5 *
distance * normal;
640 Vec3s& normal)
const {
643 this->gjk.getTolerance() + this->m_dummy_precision,
644 "The distance should be lower than GJK's tolerance.",
650 this->support_func_cached_guess = this->gjk.
support_hint;
654 Vec3s::Constant(std::numeric_limits<CoalScalar>::quiet_NaN());
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,
708 p1.noalias() = p - 0.5 *
distance * normal;
709 p2.noalias() = p + 0.5 *
distance * normal;
715 this->cached_guess =
Vec3s(1, 0, 0);
716 this->support_func_cached_guess.setZero();
719 distance = -(std::numeric_limits<CoalScalar>::max)();
721 Vec3s::Constant(std::numeric_limits<CoalScalar>::quiet_NaN());
Triangle stores the points instead of only indices of points.
Definition: geometric_shapes.h:110
#define COAL_DLLAPI
Definition: config.hh:88
#define COAL_DEPRECATED_MESSAGE(message)
Definition: deprecated.hh:38
#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
@ 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
collision and distance solver based on the GJK and EPA algorithms. Originally, GJK and EPA were imple...
Definition: narrowphase.h:57
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
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
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
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...
void getWitnessPointsAndNormal(const MinkowskiDiff &shape, Vec3s &w0, Vec3s &w1, Vec3s &normal) const
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