coal 3.0.1
Coal, The Collision Detection Library. Previously known as HPP-FCL, fork of FCL -- The Flexible Collision Library
Loading...
Searching...
No Matches
gjk.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) 2021-2024, INRIA
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * * Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * * Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer in the documentation and/or other materials provided
18 * with the distribution.
19 * * Neither the name of Open Source Robotics Foundation nor the names of its
20 * contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
39#ifndef COAL_GJK_H
40#define COAL_GJK_H
41
42#include <vector>
43
45
46namespace coal {
47
48namespace details {
49
61
62 typedef unsigned char vertex_id_t;
63
73 SimplexV* vertex[4];
76
78
79 void reset() {
80 rank = 0;
81 for (size_t i = 0; i < 4; ++i) vertex[i] = nullptr;
82 }
83 };
84
102
103 public:
109
119 Simplex* simplex; // Pointer to the result of the last run of GJK.
120
121 private:
122 // max_iteration and tolerance are made private
123 // because they are meant to be set by the `reset` function.
124 size_t max_iterations;
125 SolverScalar tolerance;
126
127 SimplexV store_v[4];
128 SimplexV* free_v[4];
129 vertex_id_t nfree;
130 vertex_id_t current;
131 Simplex simplices[2];
132 size_t iterations;
133 size_t iterations_momentum_stop;
134
135 public:
143 GJK(size_t max_iterations_, SolverScalar tolerance_)
144 : max_iterations(max_iterations_), tolerance(tolerance_) {
145 COAL_ASSERT(tolerance_ > 0, "Tolerance must be positive.",
146 std::invalid_argument);
147 initialize();
148 }
149
153 void reset(size_t max_iterations_, SolverScalar tolerance_);
154
157 const MinkowskiDiff& shape, const Vec3ps& guess,
158 const support_func_guess_t& supportHint = support_func_guess_t::Zero());
159
162 inline void getSupport(const Vec3ps& d, SimplexV& sv,
163 support_func_guess_t& hint) const {
164 Vec3s w0, w1;
165 shape->support(d.cast<Scalar>(), w0, w1, hint);
166 sv.w0 = w0.cast<SolverScalar>();
167 sv.w1 = w1.cast<SolverScalar>();
168 sv.w = sv.w0 - sv.w1;
169 }
170
173
176 inline Simplex* getSimplex() const { return simplex; }
177
179 bool hasClosestPoints() const { return distance < distance_upper_bound; }
180
188 Vec3ps& w1, Vec3ps& normal) const;
189
192
198 distance_upper_bound = dup;
199 }
200
203 bool checkConvergence(const Vec3ps& w, const SolverScalar& rl,
204 SolverScalar& alpha, const SolverScalar& omega) const;
205
207 size_t getNumMaxIterations() const { return max_iterations; }
208
210 SolverScalar getTolerance() const { return tolerance; }
211
213 size_t getNumIterations() const { return iterations; }
214
218 return iterations_momentum_stop;
219 }
220
221 private:
225 void initialize();
226
228 inline void removeVertex(Simplex& simplex);
229
231 inline void appendVertex(Simplex& simplex, const Vec3ps& v,
233
249 bool projectLineOrigin(const Simplex& current, Simplex& next);
250
253 bool projectTriangleOrigin(const Simplex& current, Simplex& next);
254
257 bool projectTetrahedraOrigin(const Simplex& current, Simplex& next);
258};
259
266 bool ignore; // If the origin does not project inside the face, we
267 // ignore this face.
268 size_t vertex_id[3]; // Index of vertex in sv_store.
269 SimplexFace* adjacent_faces[3]; // A face has three adjacent faces.
270 SimplexFace* prev_face; // The previous face in the list.
271 SimplexFace* next_face; // The next face in the list.
272 size_t adjacent_edge[3]; // Each face has 3 edges: `0`, `1` and `2`.
273 // The i-th adjacent face is bound (to this face)
274 // along its `adjacent_edge[i]`-th edge
275 // (with 0 <= i <= 2).
276 size_t pass;
277
278 SimplexFace() : n(Vec3ps::Zero()), ignore(false) {};
279 };
280
286 size_t count;
287 SimplexFaceList() : root(nullptr), count(0) {}
288
289 void reset() {
290 root = nullptr;
291 count = 0;
292 }
293
294 void append(SimplexFace* face) {
295 face->prev_face = nullptr;
296 face->next_face = root;
297 if (root != nullptr) root->prev_face = face;
298 root = face;
299 ++count;
300 }
301
302 void remove(SimplexFace* face) {
303 if (face->next_face != nullptr)
304 face->next_face->prev_face = face->prev_face;
305 if (face->prev_face != nullptr)
306 face->prev_face->next_face = face->next_face;
307 if (face == root) root = face->next_face;
308 --count;
309 }
310 };
311
314 static inline void bind(SimplexFace* fa, size_t ea, SimplexFace* fb,
315 size_t eb) {
316 assert(ea == 0 || ea == 1 || ea == 2);
317 assert(eb == 0 || eb == 1 || eb == 2);
318 fa->adjacent_edge[ea] = eb;
319 fa->adjacent_faces[ea] = fb;
320 fb->adjacent_edge[eb] = ea;
321 fb->adjacent_faces[eb] = fa;
322 }
323
325 SimplexFace* current_face; // current face in the horizon
326 SimplexFace* first_face; // first face in the horizon
327 size_t num_faces; // number of faces in the horizon
329 : current_face(nullptr), first_face(nullptr), num_faces(0) {}
330 };
331
332 enum Status {
333 DidNotRun = -1,
334 Failed = 0,
335 Valid = 1,
336 AccuracyReached = 1 << 1 | Valid,
337 Degenerated = 1 << 1 | Failed,
338 NonConvex = 2 << 1 | Failed,
339 InvalidHull = 3 << 1 | Failed,
340 OutOfFaces = 4 << 1 | Failed,
341 OutOfVertices = 5 << 1 | Failed,
342 FallBack = 6 << 1 | Failed
343 };
344
345 public:
352
353 private:
354 // max_iteration and tolerance are made private
355 // because they are meant to be set by the `reset` function.
356 size_t max_iterations;
357 SolverScalar tolerance;
358
359 std::vector<SimplexVertex> sv_store;
360 std::vector<SimplexFace> fc_store;
361 SimplexFaceList hull, stock;
362 size_t num_vertices; // number of vertices in polytpoe constructed by EPA
363 size_t iterations;
364
365 public:
366 EPA(size_t max_iterations_, SolverScalar tolerance_)
367 : max_iterations(max_iterations_), tolerance(tolerance_) {
368 initialize();
369 }
370
373 EPA(const EPA& other)
374 : max_iterations(other.max_iterations),
375 tolerance(other.tolerance),
376 sv_store(other.sv_store),
377 fc_store(other.fc_store) {
378 initialize();
379 }
380
382 size_t getNumMaxIterations() const { return max_iterations; }
383
385 size_t getNumMaxVertices() const { return sv_store.size(); }
386
388 size_t getNumMaxFaces() const { return fc_store.size(); }
389
391 SolverScalar getTolerance() const { return tolerance; }
392
394 size_t getNumIterations() const { return iterations; }
395
397 size_t getNumVertices() const { return num_vertices; }
398
400 size_t getNumFaces() const { return hull.count; }
401
410 void reset(size_t max_iterations, SolverScalar tolerance);
411
415 Status evaluate(GJK& gjk, const Vec3ps& guess);
416
425 Vec3ps& w1, Vec3ps& normal) const;
426
427 private:
431 void initialize();
432
433 bool getEdgeDist(SimplexFace* face, const SimplexVertex& a,
434 const SimplexVertex& b, SolverScalar& dist);
435
439 SimplexFace* newFace(size_t id_a, size_t id_b, size_t id_vertex,
440 bool force = false);
441
443 SimplexFace* findClosestFace();
444
446 bool expand(size_t pass, const SimplexVertex& w, SimplexFace* f, size_t e,
447 SimplexHorizon& horizon);
448
449 // @brief Use this function to debug expand if needed.
450 // void PrintExpandLooping(const SimplexFace* f, const SimplexVertex& w);
451};
452
453} // namespace details
454
455} // namespace coal
456
457#endif
#define COAL_DLLAPI
Definition config.hh:88
#define COAL_ASSERT(check, message, exception)
Definition fwd.hh:82
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:118
Eigen::Matrix< SolverScalar, 3, 1 > Vec3ps
Definition data_types.h:83
Scalar 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.
double SolverScalar
Definition data_types.h:82
Eigen::Matrix< Scalar, 3, 1 > Vec3s
Definition data_types.h:70
double Scalar
Definition data_types.h:68
Eigen::Vector2i support_func_guess_t
Definition data_types.h:80
GJKConvergenceCriterion
Which convergence criterion is used to stop the algorithm (when the shapes are not in collision)....
Definition data_types.h:114
GJKVariant
Variant to use for the GJK algorithm.
Definition data_types.h:108
The simplex list of EPA is a linked list of faces. Note: EPA's linked list does not own any memory....
Definition gjk.h:284
SimplexFace * root
Definition gjk.h:285
void reset()
Definition gjk.h:289
size_t count
Definition gjk.h:286
void append(SimplexFace *face)
Definition gjk.h:294
SimplexFaceList()
Definition gjk.h:287
void remove(SimplexFace *face)
Definition gjk.h:302
size_t adjacent_edge[3]
Definition gjk.h:272
SimplexFace * adjacent_faces[3]
Definition gjk.h:269
SolverScalar d
Definition gjk.h:265
bool ignore
Definition gjk.h:266
SimplexFace * next_face
Definition gjk.h:271
size_t pass
Definition gjk.h:276
Vec3ps n
Definition gjk.h:264
SimplexFace()
Definition gjk.h:278
SimplexFace * prev_face
Definition gjk.h:270
SimplexHorizon()
Definition gjk.h:328
SimplexFace * first_face
Definition gjk.h:326
size_t num_faces
Definition gjk.h:327
SimplexFace * current_face
Definition gjk.h:325
class for EPA algorithm
Definition gjk.h:261
size_t getNumMaxIterations() const
Get the max number of iterations of EPA.
Definition gjk.h:382
support_func_guess_t support_hint
Definition gjk.h:349
GJK::SimplexV SimplexVertex
Definition gjk.h:262
Status status
Definition gjk.h:346
Status
Definition gjk.h:332
EPA(const EPA &other)
Copy constructor of EPA. Mostly needed for the copy constructor of GJKSolver.
Definition gjk.h:373
size_t getNumVertices() const
Get the number of vertices in the polytope of the last run of EPA.
Definition gjk.h:397
static void bind(SimplexFace *fa, size_t ea, SimplexFace *fb, size_t eb)
We bind the face fa along its edge ea to the face fb along its edge fb.
Definition gjk.h:314
size_t getNumMaxFaces() const
Get the max number of faces of EPA.
Definition gjk.h:388
SolverScalar depth
Definition gjk.h:350
size_t getNumIterations() const
Get the number of iterations of the last run of EPA.
Definition gjk.h:394
GJK::Simplex result
Definition gjk.h:347
void getWitnessPointsAndNormal(const MinkowskiDiff &shape, Vec3ps &w0, Vec3ps &w1, Vec3ps &normal) const
EPA(size_t max_iterations_, SolverScalar tolerance_)
Definition gjk.h:366
void reset(size_t max_iterations, SolverScalar tolerance)
resets the EPA algorithm, preparing it for a new run. It potentially reallocates memory for the verti...
Status evaluate(GJK &gjk, const Vec3ps &guess)
SolverScalar getTolerance() const
Get the tolerance of EPA.
Definition gjk.h:391
Vec3ps normal
Definition gjk.h:348
size_t getNumFaces() const
Get the number of faces in the polytope of the last run of EPA.
Definition gjk.h:400
size_t getNumMaxVertices() const
Get the max number of vertices of EPA.
Definition gjk.h:385
SimplexFace * closest_face
Definition gjk.h:351
Definition gjk.h:54
Vec3ps w1
Definition gjk.h:56
Vec3ps w
support vector (i.e., the furthest point on the shape along the support direction)
Definition gjk.h:59
Vec3ps w0
support vector for shape 0 and 1.
Definition gjk.h:56
A simplex is a set of up to 4 vertices. Its rank is the number of vertices it contains.
Definition gjk.h:71
vertex_id_t rank
size of simplex (number of vertices)
Definition gjk.h:75
void reset()
Definition gjk.h:79
Simplex()
Definition gjk.h:77
class for GJK algorithm
Definition gjk.h:53
void reset(size_t max_iterations_, SolverScalar tolerance_)
resets the GJK algorithm, preparing it for a new run. Other than the maximum number of iterations and...
GJK(size_t max_iterations_, SolverScalar tolerance_)
Definition gjk.h:143
SolverScalar getTolerance() const
Get the tolerance of GJK.
Definition gjk.h:210
void setDistanceEarlyBreak(const SolverScalar &dup)
Distance threshold for early break. GJK stops when it proved the distance is more than this threshold...
Definition gjk.h:197
GJKConvergenceCriterionType convergence_criterion_type
Definition gjk.h:108
support_func_guess_t support_hint
Definition gjk.h:112
SolverScalar distance_upper_bound
Definition gjk.h:104
GJKVariant gjk_variant
Definition gjk.h:106
MinkowskiDiff const * shape
Definition gjk.h:110
Vec3ps ray
Definition gjk.h:111
SolverScalar distance
The distance between the two shapes, computed by GJK. If the distance is below GJK's threshold,...
Definition gjk.h:118
bool checkConvergence(const Vec3ps &w, const SolverScalar &rl, SolverScalar &alpha, const SolverScalar &omega) const
Convergence check used to stop GJK when shapes are not in collision.
size_t getNumIterationsMomentumStopped() const
Get GJK number of iterations before momentum stops. Only usefull if the Nesterov or Polyak accelerati...
Definition gjk.h:217
Status evaluate(const MinkowskiDiff &shape, const Vec3ps &guess, const support_func_guess_t &supportHint=support_func_guess_t::Zero())
GJK algorithm, given the initial value guess.
Vec3ps getGuessFromSimplex() const
get the guess from current simplex
Simplex * simplex
Definition gjk.h:119
size_t getNumIterations() const
Get the number of iterations of the last run of GJK.
Definition gjk.h:213
unsigned char vertex_id_t
Definition gjk.h:62
size_t getNumMaxIterations() const
Get the max number of iterations of GJK.
Definition gjk.h:207
GJKConvergenceCriterion convergence_criterion
Definition gjk.h:107
Status
Status of the GJK algorithm: DidNotRun: GJK has not been run. Failed: GJK did not converge (it exceed...
Definition gjk.h:94
@ 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
bool hasClosestPoints() const
Tells whether the closest points are available.
Definition gjk.h:179
Status status
Definition gjk.h:105
bool encloseOrigin()
whether the simplex enclose the origin
void getSupport(const Vec3ps &d, SimplexV &sv, support_func_guess_t &hint) const
apply the support function along a direction, the result is return in sv
Definition gjk.h:162
Simplex * getSimplex() const
get the underlying simplex using in GJK, can be used for cache in next iteration
Definition gjk.h:176
void getWitnessPointsAndNormal(const MinkowskiDiff &shape, Vec3ps &w0, Vec3ps &w1, Vec3ps &normal) const
Minkowski difference class of two shapes.
Definition minkowski_difference.h:53
void support(const Vec3s &dir, Vec3s &supp0, Vec3s &supp1, support_func_guess_t &hint) const
Support function for the pair of shapes. This method assumes set has already been called.
Definition minkowski_difference.h:174