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
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
38
39#ifndef COAL_GJK_H
40#define COAL_GJK_H
41
42#include <vector>
43
45
46namespace coal {
47
48namespace details {
49
53struct COAL_DLLAPI GJK {
54 struct COAL_DLLAPI SimplexV {
60 };
61
62 typedef unsigned char vertex_id_t;
63
71 struct COAL_DLLAPI Simplex {
76
77 Simplex() {}
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 CoalScalar 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_, CoalScalar 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_, CoalScalar tolerance_);
154
157 const MinkowskiDiff& shape, const Vec3s& guess,
158 const support_func_guess_t& supportHint = support_func_guess_t::Zero());
159
162 inline void getSupport(const Vec3s& d, SimplexV& sv,
163 support_func_guess_t& hint) const {
164 shape->support(d, sv.w0, sv.w1, hint);
165 sv.w = sv.w0 - sv.w1;
166 }
167
170
173 inline Simplex* getSimplex() const { return simplex; }
174
177
185 Vec3s& w1, Vec3s& normal) const;
186
189
196 }
197
200 bool checkConvergence(const Vec3s& w, const CoalScalar& rl, CoalScalar& alpha,
201 const CoalScalar& omega) const;
202
204 size_t getNumMaxIterations() const { return max_iterations; }
205
207 CoalScalar getTolerance() const { return tolerance; }
208
210 size_t getNumIterations() const { return iterations; }
211
215 return iterations_momentum_stop;
216 }
217
218 private:
222 void initialize();
223
225 inline void removeVertex(Simplex& simplex);
226
228 inline void appendVertex(Simplex& simplex, const Vec3s& v,
230
246 bool projectLineOrigin(const Simplex& current, Simplex& next);
247
250 bool projectTriangleOrigin(const Simplex& current, Simplex& next);
251
254 bool projectTetrahedraOrigin(const Simplex& current, Simplex& next);
255};
256
258struct COAL_DLLAPI EPA {
260 struct COAL_DLLAPI SimplexFace {
263 bool ignore; // If the origin does not project inside the face, we
264 // ignore this face.
265 size_t vertex_id[3]; // Index of vertex in sv_store.
266 SimplexFace* adjacent_faces[3]; // A face has three adjacent faces.
267 SimplexFace* prev_face; // The previous face in the list.
268 SimplexFace* next_face; // The next face in the list.
269 size_t adjacent_edge[3]; // Each face has 3 edges: `0`, `1` and `2`.
270 // The i-th adjacent face is bound (to this face)
271 // along its `adjacent_edge[i]`-th edge
272 // (with 0 <= i <= 2).
273 size_t pass;
274
275 SimplexFace() : n(Vec3s::Zero()), ignore(false) {};
276 };
277
281 struct COAL_DLLAPI SimplexFaceList {
283 size_t count;
284 SimplexFaceList() : root(nullptr), count(0) {}
285
286 void reset() {
287 root = nullptr;
288 count = 0;
289 }
290
291 void append(SimplexFace* face) {
292 face->prev_face = nullptr;
293 face->next_face = root;
294 if (root != nullptr) root->prev_face = face;
295 root = face;
296 ++count;
297 }
298
299 void remove(SimplexFace* face) {
300 if (face->next_face != nullptr)
301 face->next_face->prev_face = face->prev_face;
302 if (face->prev_face != nullptr)
303 face->prev_face->next_face = face->next_face;
304 if (face == root) root = face->next_face;
305 --count;
306 }
307 };
308
311 static inline void bind(SimplexFace* fa, size_t ea, SimplexFace* fb,
312 size_t eb) {
313 assert(ea == 0 || ea == 1 || ea == 2);
314 assert(eb == 0 || eb == 1 || eb == 2);
315 fa->adjacent_edge[ea] = eb;
316 fa->adjacent_faces[ea] = fb;
317 fb->adjacent_edge[eb] = ea;
318 fb->adjacent_faces[eb] = fa;
319 }
320
321 struct COAL_DLLAPI SimplexHorizon {
322 SimplexFace* current_face; // current face in the horizon
323 SimplexFace* first_face; // first face in the horizon
324 size_t num_faces; // number of faces in the horizon
326 : current_face(nullptr), first_face(nullptr), num_faces(0) {}
327 };
328
329 enum Status {
331 Failed = 0,
332 Valid = 1,
334 Degenerated = 1 << 1 | Failed,
335 NonConvex = 2 << 1 | Failed,
336 InvalidHull = 3 << 1 | Failed,
337 OutOfFaces = 4 << 1 | Failed,
339 FallBack = 6 << 1 | Failed
340 };
341
342 public:
349
350 private:
351 // max_iteration and tolerance are made private
352 // because they are meant to be set by the `reset` function.
353 size_t max_iterations;
354 CoalScalar tolerance;
355
356 std::vector<SimplexVertex> sv_store;
357 std::vector<SimplexFace> fc_store;
358 SimplexFaceList hull, stock;
359 size_t num_vertices; // number of vertices in polytpoe constructed by EPA
360 size_t iterations;
361
362 public:
363 EPA(size_t max_iterations_, CoalScalar tolerance_)
364 : max_iterations(max_iterations_), tolerance(tolerance_) {
365 initialize();
366 }
367
370 EPA(const EPA& other)
371 : max_iterations(other.max_iterations),
372 tolerance(other.tolerance),
373 sv_store(other.sv_store),
374 fc_store(other.fc_store) {
375 initialize();
376 }
377
379 size_t getNumMaxIterations() const { return max_iterations; }
380
382 size_t getNumMaxVertices() const { return sv_store.size(); }
383
385 size_t getNumMaxFaces() const { return fc_store.size(); }
386
388 CoalScalar getTolerance() const { return tolerance; }
389
391 size_t getNumIterations() const { return iterations; }
392
394 size_t getNumVertices() const { return num_vertices; }
395
397 size_t getNumFaces() const { return hull.count; }
398
407 void reset(size_t max_iterations, CoalScalar tolerance);
408
412 Status evaluate(GJK& gjk, const Vec3s& guess);
413
422 Vec3s& w1, Vec3s& normal) const;
423
424 private:
428 void initialize();
429
430 bool getEdgeDist(SimplexFace* face, const SimplexVertex& a,
431 const SimplexVertex& b, CoalScalar& dist);
432
436 SimplexFace* newFace(size_t id_a, size_t id_b, size_t id_vertex,
437 bool force = false);
438
440 SimplexFace* findClosestFace();
441
443 bool expand(size_t pass, const SimplexVertex& w, SimplexFace* f, size_t e,
444 SimplexHorizon& horizon);
445
446 // @brief Use this function to debug expand if needed.
447 // void PrintExpandLooping(const SimplexFace* f, const SimplexVertex& w);
448};
449
450} // namespace details
451
452} // namespace coal
453
454#endif
#define COAL_ASSERT(check, message, exception)
Definition fwd.hh:82
Definition hfield.h:170
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
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
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
The simplex list of EPA is a linked list of faces. Note: EPA's linked list does not own any memory....
Definition gjk.h:281
SimplexFace * root
Definition gjk.h:282
void reset()
Definition gjk.h:286
size_t count
Definition gjk.h:283
void append(SimplexFace *face)
Definition gjk.h:291
SimplexFaceList()
Definition gjk.h:284
void remove(SimplexFace *face)
Definition gjk.h:299
size_t adjacent_edge[3]
Definition gjk.h:269
Vec3s n
Definition gjk.h:261
CoalScalar d
Definition gjk.h:262
SimplexFace * adjacent_faces[3]
Definition gjk.h:266
size_t vertex_id[3]
Definition gjk.h:265
bool ignore
Definition gjk.h:263
SimplexFace * next_face
Definition gjk.h:268
size_t pass
Definition gjk.h:273
SimplexFace()
Definition gjk.h:275
SimplexFace * prev_face
Definition gjk.h:267
SimplexHorizon()
Definition gjk.h:325
SimplexFace * first_face
Definition gjk.h:323
size_t num_faces
Definition gjk.h:324
SimplexFace * current_face
Definition gjk.h:322
size_t getNumMaxIterations() const
Get the max number of iterations of EPA.
Definition gjk.h:379
void reset(size_t max_iterations, CoalScalar tolerance)
resets the EPA algorithm, preparing it for a new run. It potentially reallocates memory for the verti...
support_func_guess_t support_hint
Definition gjk.h:346
Vec3s normal
Definition gjk.h:345
GJK::SimplexV SimplexVertex
Definition gjk.h:259
Status status
Definition gjk.h:343
Status
Definition gjk.h:329
@ 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
CoalScalar depth
Definition gjk.h:347
EPA(const EPA &other)
Copy constructor of EPA. Mostly needed for the copy constructor of GJKSolver.
Definition gjk.h:370
size_t getNumVertices() const
Get the number of vertices in the polytope of the last run of EPA.
Definition gjk.h:394
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:311
CoalScalar getTolerance() const
Get the tolerance of EPA.
Definition gjk.h:388
size_t getNumMaxFaces() const
Get the max number of faces of EPA.
Definition gjk.h:385
size_t getNumIterations() const
Get the number of iterations of the last run of EPA.
Definition gjk.h:391
GJK::Simplex result
Definition gjk.h:344
Status evaluate(GJK &gjk, const Vec3s &guess)
size_t getNumFaces() const
Get the number of faces in the polytope of the last run of EPA.
Definition gjk.h:397
size_t getNumMaxVertices() const
Get the max number of vertices of EPA.
Definition gjk.h:382
EPA(size_t max_iterations_, CoalScalar tolerance_)
Definition gjk.h:363
void getWitnessPointsAndNormal(const MinkowskiDiff &shape, Vec3s &w0, Vec3s &w1, Vec3s &normal) const
SimplexFace * closest_face
Definition gjk.h:348
Definition gjk.h:54
Vec3s w0
support vector for shape 0 and 1.
Definition gjk.h:56
Vec3s w
support vector (i.e., the furthest point on the shape along the support direction)
Definition gjk.h:59
Vec3s w1
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
SimplexV * vertex[4]
simplex vertex
Definition gjk.h:73
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_, 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
Vec3s getGuessFromSimplex() const
get the guess from current simplex
void getSupport(const Vec3s &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
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
MinkowskiDiff const * shape
Definition gjk.h:110
CoalScalar distance
The distance between the two shapes, computed by GJK. If the distance is below GJK's threshold,...
Definition gjk.h:118
GJK(size_t max_iterations_, CoalScalar tolerance_)
Definition gjk.h:143
size_t getNumIterationsMomentumStopped() const
Get GJK number of iterations before momentum stops. Only usefull if the Nesterov or Polyak accelerati...
Definition gjk.h:214
CoalScalar distance_upper_bound
Definition gjk.h:104
Simplex * simplex
Definition gjk.h:119
size_t getNumIterations() const
Get the number of iterations of the last run of GJK.
Definition gjk.h:210
Vec3s ray
Definition gjk.h:111
unsigned char vertex_id_t
Definition gjk.h:62
size_t getNumMaxIterations() const
Get the max number of iterations of GJK.
Definition gjk.h:204
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
@ 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
bool hasClosestPoints() const
Tells whether the closest points are available.
Definition gjk.h:176
Status status
Definition gjk.h:105
bool checkConvergence(const Vec3s &w, const CoalScalar &rl, CoalScalar &alpha, const CoalScalar &omega) const
Convergence check used to stop GJK when shapes are not in collision.
bool encloseOrigin()
whether the simplex enclose the origin
Simplex * getSimplex() const
get the underlying simplex using in GJK, can be used for cache in next iteration
Definition gjk.h:173
Minkowski difference class of two shapes.
Definition minkowski_difference.h:53