coal/narrowphase/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 
40 #ifndef COAL_NARROWPHASE_H
41 #define COAL_NARROWPHASE_H
42 
43 #include <limits>
44 
45 #include "coal/narrowphase/gjk.h"
46 #include "coal/collision_data.h"
48 #include "coal/logging.h"
49 
50 namespace coal {
51 
57 struct COAL_DLLAPI GJKSolver {
58  public:
59  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
60 
62  mutable details::GJK gjk;
63 
66 
69 
72 
75  COAL_DEPRECATED_MESSAGE(Use gjk_initial_guess instead)
76  bool enable_cached_guess;
77 
79  mutable Vec3s cached_guess;
80 
82  mutable support_func_guess_t support_func_cached_guess;
83 
86  CoalScalar distance_upper_bound;
87 
89  GJKVariant gjk_variant;
90 
92  GJKConvergenceCriterion gjk_convergence_criterion;
93 
95  GJKConvergenceCriterionType gjk_convergence_criterion_type;
96 
98  mutable details::EPA epa;
99 
101  size_t epa_max_iterations;
102 
104  CoalScalar epa_tolerance;
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:
125  gjk_max_iterations(GJK_DEFAULT_MAX_ITERATIONS),
126  gjk_tolerance(GJK_DEFAULT_TOLERANCE),
127  gjk_initial_guess(GJKInitialGuess::DefaultGuess),
128  enable_cached_guess(false), // Use gjk_initial_guess instead
129  cached_guess(Vec3s(1, 0, 0)),
130  support_func_cached_guess(support_func_guess_t::Zero()),
131  distance_upper_bound((std::numeric_limits<CoalScalar>::max)()),
132  gjk_variant(GJKVariant::DefaultGJK),
133  gjk_convergence_criterion(GJKConvergenceCriterion::Default),
134  gjk_convergence_criterion_type(GJKConvergenceCriterionType::Absolute),
135  epa(0, EPA_DEFAULT_TOLERANCE),
136  epa_max_iterations(EPA_DEFAULT_MAX_ITERATIONS),
137  epa_tolerance(EPA_DEFAULT_TOLERANCE) {}
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;
165  this->enable_cached_guess = request.enable_cached_gjk_guess;
166  if (this->gjk_initial_guess == GJKInitialGuess::CachedGuess ||
167  this->enable_cached_guess) {
168  this->cached_guess = request.cached_gjk_guess;
169  this->support_func_cached_guess = request.cached_support_func_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;
176  this->gjk_convergence_criterion = request.gjk_convergence_criterion;
177  this->gjk_convergence_criterion_type =
179 
180  // ---------------------
181  // EPA settings
182  this->epa_max_iterations = request.epa_max_iterations;
183  this->epa_tolerance = request.epa_tolerance;
184 
185  // ---------------------
186  // Reset GJK and EPA status
187  this->epa.status = details::EPA::Status::DidNotRun;
188  this->gjk.status = details::GJK::Status::DidNotRun;
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;
217  this->enable_cached_guess = request.enable_cached_gjk_guess;
218  if (this->gjk_initial_guess == GJKInitialGuess::CachedGuess ||
219  this->enable_cached_guess) {
220  this->cached_guess = request.cached_gjk_guess;
221  this->support_func_cached_guess = request.cached_support_func_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;
230  this->gjk_convergence_criterion = request.gjk_convergence_criterion;
231  this->gjk_convergence_criterion_type =
233 
234  // ---------------------
235  // EPA settings
236  this->epa_max_iterations = request.epa_max_iterations;
237  this->epa_tolerance = request.epa_tolerance;
238 
239  // ---------------------
240  // Reset GJK and EPA status
241  this->gjk.status = details::GJK::Status::DidNotRun;
242  this->epa.status = details::EPA::Status::DidNotRun;
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 &&
254  this->support_func_cached_guess == other.support_func_cached_guess &&
255  this->gjk_max_iterations == other.gjk_max_iterations &&
256  this->gjk_tolerance == other.gjk_tolerance &&
257  this->distance_upper_bound == other.distance_upper_bound &&
258  this->gjk_variant == other.gjk_variant &&
259  this->gjk_convergence_criterion == other.gjk_convergence_criterion &&
260  this->gjk_convergence_criterion_type ==
262  this->gjk_initial_guess == other.gjk_initial_guess &&
263  this->epa_max_iterations == other.epa_max_iterations &&
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 {
344  CoalScalar distance = this->shapeDistance<S2>(
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);
433  this->gjk.setDistanceEarlyBreak(this->distance_upper_bound);
434  this->gjk.gjk_variant = this->gjk_variant;
435  this->gjk.convergence_criterion = this->gjk_convergence_criterion;
436  this->gjk.convergence_criterion_type = this->gjk_convergence_criterion_type;
437  this->epa.status = details::EPA::Status::DidNotRun;
438 
439  // Get initial guess for GJK: default, cached or bounding volume guess
440  Vec3s guess;
441  support_func_guess_t support_hint;
442  getGJKInitialGuess(*(this->minkowski_difference.shapes[0]),
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.
469  GJKEarlyStopExtractWitnessPointsAndNormal(tf1, distance, p1, p2,
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);
494  COAL_ASSERT(
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.
503  GJKCollisionExtractWitnessPointsAndNormal(tf1, distance, p1, p2,
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;
544  case details::EPA::Valid:
546  COAL_ASSERT(
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.");
571  EPAFailedExtractWitnessPointsAndNormal(tf1, distance, p1, p2,
572  normal);
573  break;
575  COAL_ASSERT(
576  false,
577  "EPA went into fallback mode. It should never do that.",
578  std::logic_error);
579  COAL_LOG_ERROR("EPA error: FallBack.");
580  EPAFailedExtractWitnessPointsAndNormal(tf1, distance, p1, p2,
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;
596  this->support_func_cached_guess = this->gjk.support_hint;
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;
625  this->support_func_cached_guess = this->gjk.support_hint;
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;
650  this->support_func_cached_guess = this->gjk.support_hint;
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
coal::GJKConvergenceCriterion
GJKConvergenceCriterion
Which convergence criterion is used to stop the algorithm (when the shapes are not in collision)....
Definition: coal/data_types.h:104
coal::GJKSolver::EPAFailedExtractWitnessPointsAndNormal
void EPAFailedExtractWitnessPointsAndNormal(const Transform3s &tf1, CoalScalar &distance, Vec3s &p1, Vec3s &p2, Vec3s &normal) const
Definition: coal/narrowphase/narrowphase.h:712
coal::QueryRequest::gjk_convergence_criterion
GJKConvergenceCriterion gjk_convergence_criterion
convergence criterion used to stop GJK
Definition: coal/collision_data.h:198
coal::TriangleP::b
Vec3s b
Definition: coal/shape/geometric_shapes.h:149
coal::GJKSolver::gjk
EIGEN_MAKE_ALIGNED_OPERATOR_NEW details::GJK gjk
GJK algorithm.
Definition: coal/narrowphase/narrowphase.h:62
coal::details::EPA::NonConvex
@ NonConvex
Definition: coal/narrowphase/gjk.h:335
coal::QueryRequest::gjk_tolerance
CoalScalar gjk_tolerance
tolerance for the GJK algorithm. Note: This tolerance determines the precision on the estimated dista...
Definition: coal/collision_data.h:192
coal::Vec3s
Eigen::Matrix< CoalScalar, 3, 1 > Vec3s
Definition: coal/data_types.h:77
coal::details::GJK::Failed
@ Failed
Definition: coal/narrowphase/gjk.h:96
coal::QueryRequest::gjk_initial_guess
GJKInitialGuess gjk_initial_guess
Definition: coal/collision_data.h:172
coal::QueryRequest::epa_tolerance
CoalScalar epa_tolerance
tolerance for EPA. Note: This tolerance determines the precision on the estimated distance between tw...
Definition: coal/collision_data.h:211
coal::details::EPA::Failed
@ Failed
Definition: coal/narrowphase/gjk.h:331
coal::details::GJK::ray
Vec3s ray
Definition: coal/narrowphase/gjk.h:111
coal::GJKSolver::gjk_max_iterations
size_t gjk_max_iterations
maximum number of iterations of GJK
Definition: coal/narrowphase/narrowphase.h:65
coal::QueryRequest::cached_support_func_guess
support_func_guess_t cached_support_func_guess
the support function initial guess set by user
Definition: coal/collision_data.h:183
COAL_COMPILER_DIAGNOSTIC_PUSH
#define COAL_COMPILER_DIAGNOSTIC_PUSH
Definition: include/coal/fwd.hh:120
coal::GJK_DEFAULT_TOLERANCE
constexpr CoalScalar GJK_DEFAULT_TOLERANCE
Definition: coal/narrowphase/narrowphase_defaults.h:47
coal::GJKSolver::shapeDistance
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: coal/narrowphase/narrowphase.h:323
COAL_ASSERT
#define COAL_ASSERT(check, message, exception)
Definition: include/coal/fwd.hh:82
coal::GJKConvergenceCriterionType
GJKConvergenceCriterionType
Wether the convergence criterion is scaled on the norm of the solution or not.
Definition: coal/data_types.h:108
coal::DefaultGuess
@ DefaultGuess
Definition: coal/data_types.h:95
coal::details::GJK::gjk_variant
GJKVariant gjk_variant
Definition: coal/narrowphase/gjk.h:106
coal::details::GJK::NoCollisionEarlyStopped
@ NoCollisionEarlyStopped
Definition: coal/narrowphase/gjk.h:97
coal::GJKSolver::GJKCollisionExtractWitnessPointsAndNormal
void GJKCollisionExtractWitnessPointsAndNormal(const Transform3s &tf1, CoalScalar &distance, Vec3s &p1, Vec3s &p2, Vec3s &normal) const
Definition: coal/narrowphase/narrowphase.h:637
coal::Transform3s::transform
Vec3s transform(const Eigen::MatrixBase< Derived > &v) const
transform a given vector by the transform
Definition: coal/math/transform.h:152
coal::details::EPA::OutOfVertices
@ OutOfVertices
Definition: coal/narrowphase/gjk.h:338
gjk.tf1
tuple tf1
Definition: test/scripts/gjk.py:27
coal::CollisionRequest::security_margin
CoalScalar security_margin
Distance below which objects are considered in collision. See Collision.
Definition: coal/collision_data.h:328
collision_data.h
coal
Main namespace.
Definition: coal/broadphase/broadphase_bruteforce.h:44
coal::details::GJK::setDistanceEarlyBreak
void setDistanceEarlyBreak(const CoalScalar &dup)
Distance threshold for early break. GJK stops when it proved the distance is more than this threshold...
Definition: coal/narrowphase/gjk.h:194
coal::GJKSolver::set
void set(const CollisionRequest &request)
setter from a CollisionRequest
Definition: coal/narrowphase/narrowphase.h:213
coal::details::NoSweptSphere
@ NoSweptSphere
Definition: coal/narrowphase/support_functions.h:59
coal::CachedGuess
@ CachedGuess
Definition: coal/data_types.h:95
coal::GJKSolver::operator==
COAL_COMPILER_DIAGNOSTIC_PUSH COAL_COMPILER_DIAGNOSTIC_IGNORED_DEPRECECATED_DECLARATIONS bool operator==(const GJKSolver &other) const
Definition: coal/narrowphase/narrowphase.h:250
coal::GJKSolver::GJKEarlyStopExtractWitnessPointsAndNormal
void GJKEarlyStopExtractWitnessPointsAndNormal(const Transform3s &tf1, CoalScalar &distance, Vec3s &p1, Vec3s &p2, Vec3s &normal) const
Definition: coal/narrowphase/narrowphase.h:589
coal::details::GJK::convergence_criterion
GJKConvergenceCriterion convergence_criterion
Definition: coal/narrowphase/gjk.h:107
coal::Default
@ Default
Definition: coal/data_types.h:104
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::GJK::distance_upper_bound
CoalScalar distance_upper_bound
Definition: coal/narrowphase/gjk.h:104
coal::distance
COAL_DLLAPI 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.
Definition: kIOS.cpp:180
coal::GJKSolver::gjk_convergence_criterion
GJKConvergenceCriterion gjk_convergence_criterion
Convergence criterion for GJK.
Definition: coal/narrowphase/narrowphase.h:92
coal::DefaultGJK
@ DefaultGJK
Definition: coal/data_types.h:98
coal::details::EPA::OutOfFaces
@ OutOfFaces
Definition: coal/narrowphase/gjk.h:337
coal::GJKSolver::enable_cached_guess
bool enable_cached_guess
Whether smart guess can be provided @Deprecated Use gjk_initial_guess instead.
Definition: coal/narrowphase/narrowphase.h:76
coal::GJKVariant
GJKVariant
Variant to use for the GJK algorithm.
Definition: coal/data_types.h:98
coal::GJKSolver::getDistancePrecision
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: coal/narrowphase/narrowphase.h:272
coal::QueryRequest::cached_gjk_guess
Vec3s cached_gjk_guess
the gjk initial guess set by user
Definition: coal/collision_data.h:180
coal::details::GJK::reset
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...
Definition: src/narrowphase/gjk.cpp:58
narrowphase_defaults.h
coal::QueryRequest::gjk_convergence_criterion_type
GJKConvergenceCriterionType gjk_convergence_criterion_type
convergence criterion used to stop GJK
Definition: coal/collision_data.h:201
coal::Transform3s
Simple transform class used locally by InterpMotion.
Definition: coal/math/transform.h:55
coal::QueryRequest::gjk_max_iterations
size_t gjk_max_iterations
maximum iteration for the GJK algorithm
Definition: coal/collision_data.h:186
coal::details::EPA::AccuracyReached
@ AccuracyReached
Definition: coal/narrowphase/gjk.h:333
COAL_UNUSED_VARIABLE
#define COAL_UNUSED_VARIABLE(var)
Definition: include/coal/fwd.hh:56
coal::support_func_guess_t
Eigen::Vector2i support_func_guess_t
Definition: coal/data_types.h:87
coal::TriangleP::a
Vec3s a
Definition: coal/shape/geometric_shapes.h:149
coal::DistanceRequest
request to the distance computation
Definition: coal/collision_data.h:985
coal::EPA_DEFAULT_MAX_ITERATIONS
constexpr size_t EPA_DEFAULT_MAX_ITERATIONS
Definition: coal/narrowphase/narrowphase_defaults.h:59
coal::details::EPA::InvalidHull
@ InvalidHull
Definition: coal/narrowphase/gjk.h:336
coal::details::EPA::DidNotRun
@ DidNotRun
Definition: coal/narrowphase/gjk.h:330
coal::GJKSolver::support_func_cached_guess
support_func_guess_t support_func_cached_guess
smart guess for the support function
Definition: coal/narrowphase/narrowphase.h:82
coal::details::GJK::distance
CoalScalar distance
The distance between the two shapes, computed by GJK. If the distance is below GJK's threshold,...
Definition: coal/narrowphase/gjk.h:118
coal::GJKSolver::set
void set(const DistanceRequest &request)
setter from a DistanceRequest
Definition: coal/narrowphase/narrowphase.h:161
COAL_THROW_PRETTY
#define COAL_THROW_PRETTY(message, exception)
Definition: include/coal/fwd.hh:64
instead
overload_base_get_item_for_map< Container > instead
coal::GJKSolver::epa_tolerance
CoalScalar epa_tolerance
tolerance of EPA
Definition: coal/narrowphase/narrowphase.h:104
coal::details::GJK::convergence_criterion_type
GJKConvergenceCriterionType convergence_criterion_type
Definition: coal/narrowphase/gjk.h:108
coal::CollisionRequest
request to the collision algorithm
Definition: coal/collision_data.h:311
coal::QueryRequest::epa_max_iterations
size_t epa_max_iterations
max number of iterations for EPA
Definition: coal/collision_data.h:204
coal::GJKSolver::gjk_variant
GJKVariant gjk_variant
Variant of the GJK algorithm (Default, Nesterov or Polyak).
Definition: coal/narrowphase/narrowphase.h:89
coal::GJKSolver::GJKSolver
GJKSolver(const CollisionRequest &request)
Constructor from a CollisionRequest.
Definition: coal/narrowphase/narrowphase.h:200
gjk.tf2
tuple tf2
Definition: test/scripts/gjk.py:36
coal::GJKSolver::distance_upper_bound
CoalScalar distance_upper_bound
If GJK can guarantee that the distance between the shapes is greater than this value,...
Definition: coal/narrowphase/narrowphase.h:86
coal::details::GJK::CollisionWithPenetrationInformation
@ CollisionWithPenetrationInformation
Definition: coal/narrowphase/gjk.h:99
coal::details::EPA::Degenerated
@ Degenerated
Definition: coal/narrowphase/gjk.h:334
coal::GJK_DEFAULT_MAX_ITERATIONS
constexpr size_t GJK_DEFAULT_MAX_ITERATIONS
GJK.
Definition: coal/narrowphase/narrowphase_defaults.h:46
coal::GJKSolver::getGJKInitialGuess
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: coal/narrowphase/narrowphase.h:354
coal::BoundingVolumeGuess
@ BoundingVolumeGuess
Definition: coal/data_types.h:95
octree.p1
tuple p1
Definition: octree.py:54
coal::TriangleP
Triangle stores the points instead of only indices of points.
Definition: coal/shape/geometric_shapes.h:110
coal::details::GJK::status
Status status
Definition: coal/narrowphase/gjk.h:105
coal::GJKSolver::shapeDistance
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: coal/narrowphase/narrowphase.h:308
coal::details::GJK::NoCollision
@ NoCollision
Definition: coal/narrowphase/gjk.h:98
coal::GJKSolver::cached_guess
Vec3s cached_guess
smart guess
Definition: coal/narrowphase/narrowphase.h:79
coal::QueryRequest::gjk_variant
GJKVariant gjk_variant
whether to enable the Nesterov accleration of GJK
Definition: coal/collision_data.h:195
coal::details::GJK::DidNotRun
@ DidNotRun
Definition: coal/narrowphase/gjk.h:95
coal::EPA_DEFAULT_TOLERANCE
constexpr CoalScalar EPA_DEFAULT_TOLERANCE
Definition: coal/narrowphase/narrowphase_defaults.h:60
coal::GJKInitialGuess
GJKInitialGuess
Initial guess to use for the GJK algorithm DefaultGuess: Vec3s(1, 0, 0) CachedGuess: previous vector ...
Definition: coal/data_types.h:95
coal::GJKSolver::shapeDistance
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: coal/narrowphase/narrowphase.h:340
coal::GJKSolver::operator!=
COAL_COMPILER_DIAGNOSTIC_POP bool operator!=(const GJKSolver &other) const
Definition: coal/narrowphase/narrowphase.h:268
coal::GJKSolver::GJKExtractWitnessPointsAndNormal
void GJKExtractWitnessPointsAndNormal(const Transform3s &tf1, CoalScalar &distance, Vec3s &p1, Vec3s &p2, Vec3s &normal) const
Definition: coal/narrowphase/narrowphase.h:610
coal::details::GJK::getTolerance
CoalScalar getTolerance() const
Get the tolerance of GJK.
Definition: coal/narrowphase/gjk.h:207
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
COAL_COMPILER_DIAGNOSTIC_POP
#define COAL_COMPILER_DIAGNOSTIC_POP
Definition: include/coal/fwd.hh:121
coal::details::EPA::Valid
@ Valid
Definition: coal/narrowphase/gjk.h:332
coal::GJKSolver::gjk_convergence_criterion_type
GJKConvergenceCriterionType gjk_convergence_criterion_type
Absolute or relative convergence criterion for GJK.
Definition: coal/narrowphase/narrowphase.h:95
COAL_COMPILER_DIAGNOSTIC_IGNORED_DEPRECECATED_DECLARATIONS
#define COAL_COMPILER_DIAGNOSTIC_IGNORED_DEPRECECATED_DECLARATIONS
Definition: include/coal/fwd.hh:122
coal::GJKSolver::EPAExtractWitnessPointsAndNormal
void EPAExtractWitnessPointsAndNormal(const Transform3s &tf1, CoalScalar &distance, Vec3s &p1, Vec3s &p2, Vec3s &normal) const
Definition: coal/narrowphase/narrowphase.h:657
coal::TriangleP::c
Vec3s c
Definition: coal/shape/geometric_shapes.h:149
coal::details::EPA::FallBack
@ FallBack
Definition: coal/narrowphase/gjk.h:339
coal::details::GJK
class for GJK algorithm
Definition: coal/narrowphase/gjk.h:53
coal::QueryRequest::enable_cached_gjk_guess
bool enable_cached_gjk_guess
whether enable gjk initial guess @Deprecated Use gjk_initial_guess instead
Definition: coal/collision_data.h:177
coal::GJKSolver::runGJKAndEPA
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: coal/narrowphase/narrowphase.h:422
COAL_LOG_ERROR
#define COAL_LOG_ERROR(message)
Definition: coal/logging.h:51
gjk.h
coal::details::GJK::Collision
@ Collision
Definition: coal/narrowphase/gjk.h:100
coal::GJKSolver::epa_max_iterations
size_t epa_max_iterations
maximum number of iterations of EPA
Definition: coal/narrowphase/narrowphase.h:101
logging.h
coal::CoalScalar
double CoalScalar
Definition: coal/data_types.h:76
coal::details::GJK::support_hint
support_func_guess_t support_hint
Definition: coal/narrowphase/gjk.h:112
coal::GJKSolver::GJKSolver
GJKSolver(const DistanceRequest &request)
Constructor from a DistanceRequest.
Definition: coal/narrowphase/narrowphase.h:148
COAL_LOG_WARNING
#define COAL_LOG_WARNING(message)
Definition: coal/logging.h:50
coal::CollisionRequest::distance_upper_bound
CoalScalar distance_upper_bound
Distance above which GJK solver makes an early stopping. GJK stops searching for the closest points w...
Definition: coal/collision_data.h:340
coal::GJKSolver::gjk_tolerance
CoalScalar gjk_tolerance
tolerance of GJK
Definition: coal/narrowphase/narrowphase.h:68
coal::GJKSolver::gjk_initial_guess
GJKInitialGuess gjk_initial_guess
which warm start to use for GJK
Definition: coal/narrowphase/narrowphase.h:71
gjk
Definition: doc/gjk.py:1
coal::Absolute
@ Absolute
Definition: coal/data_types.h:108


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