Program Listing for File gjk.h
↰ Return to documentation for file (/tmp/ws/src/hpp-fcl/include/hpp/fcl/narrowphase/gjk.h
)
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2011-2014, Willow Garage, Inc.
* Copyright (c) 2014-2015, Open Source Robotics Foundation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Open Source Robotics Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef HPP_FCL_GJK_H
#define HPP_FCL_GJK_H
#include <vector>
#include <hpp/fcl/shape/geometric_shapes.h>
#include <hpp/fcl/math/transform.h>
namespace hpp {
namespace fcl {
namespace details {
Vec3f getSupport(const ShapeBase* shape, const Vec3f& dir, bool dirIsNormalized,
int& hint);
struct HPP_FCL_DLLAPI MinkowskiDiff {
typedef Eigen::Array<FCL_REAL, 1, 2> Array2d;
const ShapeBase* shapes[2];
struct ShapeData {
std::vector<int8_t> visited;
};
ShapeData data[2];
Matrix3f oR1;
Vec3f ot1;
Array2d inflation;
int linear_log_convex_threshold;
bool normalize_support_direction;
typedef void (*GetSupportFunction)(const MinkowskiDiff& minkowskiDiff,
const Vec3f& dir, bool dirIsNormalized,
Vec3f& support0, Vec3f& support1,
support_func_guess_t& hint,
ShapeData data[2]);
GetSupportFunction getSupportFunc;
MinkowskiDiff()
: linear_log_convex_threshold(32),
normalize_support_direction(false),
getSupportFunc(NULL) {}
void set(const ShapeBase* shape0, const ShapeBase* shape1);
void set(const ShapeBase* shape0, const ShapeBase* shape1,
const Transform3f& tf0, const Transform3f& tf1);
inline Vec3f support0(const Vec3f& d, bool dIsNormalized, int& hint) const {
return getSupport(shapes[0], d, dIsNormalized, hint);
}
inline Vec3f support1(const Vec3f& d, bool dIsNormalized, int& hint) const {
return oR1 *
getSupport(shapes[1], oR1.transpose() * d, dIsNormalized, hint) +
ot1;
}
inline void support(const Vec3f& d, bool dIsNormalized, Vec3f& supp0,
Vec3f& supp1, support_func_guess_t& hint) const {
assert(getSupportFunc != NULL);
getSupportFunc(*this, d, dIsNormalized, supp0, supp1, hint,
const_cast<ShapeData*>(data));
}
};
struct HPP_FCL_DLLAPI GJK {
struct HPP_FCL_DLLAPI SimplexV {
Vec3f w0, w1;
Vec3f w;
};
typedef unsigned char vertex_id_t;
struct HPP_FCL_DLLAPI Simplex {
SimplexV* vertex[4];
vertex_id_t rank;
Simplex() {}
};
enum Status { Valid, Inside, Failed, EarlyStopped };
MinkowskiDiff const* shape;
Vec3f ray;
GJKVariant gjk_variant;
GJKConvergenceCriterion convergence_criterion;
GJKConvergenceCriterionType convergence_criterion_type;
support_func_guess_t support_hint;
FCL_REAL distance;
Simplex simplices[2];
GJK(unsigned int max_iterations_, FCL_REAL tolerance_)
: max_iterations(max_iterations_), tolerance(tolerance_) {
initialize();
}
void initialize();
Status evaluate(
const MinkowskiDiff& shape, const Vec3f& guess,
const support_func_guess_t& supportHint = support_func_guess_t::Zero());
inline void getSupport(const Vec3f& d, bool dIsNormalized, SimplexV& sv,
support_func_guess_t& hint) const {
shape->support(d, dIsNormalized, sv.w0, sv.w1, hint);
sv.w = sv.w0 - sv.w1;
}
bool encloseOrigin();
inline Simplex* getSimplex() const { return simplex; }
bool hasClosestPoints() { return distance < distance_upper_bound; }
bool hasPenetrationInformation(const MinkowskiDiff& shape) {
return distance > -shape.inflation.sum();
}
bool getClosestPoints(const MinkowskiDiff& shape, Vec3f& w0, Vec3f& w1);
Vec3f getGuessFromSimplex() const;
void setDistanceEarlyBreak(const FCL_REAL& dup) {
distance_upper_bound = dup;
}
bool checkConvergence(const Vec3f& w, const FCL_REAL& rl, FCL_REAL& alpha,
const FCL_REAL& omega);
inline size_t getIterations() { return iterations; }
inline FCL_REAL getTolerance() { return tolerance; }
private:
SimplexV store_v[4];
SimplexV* free_v[4];
vertex_id_t nfree;
vertex_id_t current;
Simplex* simplex;
Status status;
unsigned int max_iterations;
FCL_REAL tolerance;
FCL_REAL distance_upper_bound;
size_t iterations;
inline void removeVertex(Simplex& simplex);
inline void appendVertex(Simplex& simplex, const Vec3f& v, bool isNormalized,
support_func_guess_t& hint);
// of the simplex are added. To know more about these, visit
// https://caseymuratori.com/blog_0003.
bool projectLineOrigin(const Simplex& current, Simplex& next);
bool projectTriangleOrigin(const Simplex& current, Simplex& next);
bool projectTetrahedraOrigin(const Simplex& current, Simplex& next);
};
static const size_t EPA_MAX_FACES = 128;
static const size_t EPA_MAX_VERTICES = 64;
static const FCL_REAL EPA_EPS = 0.000001;
static const size_t EPA_MAX_ITERATIONS = 255;
struct HPP_FCL_DLLAPI EPA {
typedef GJK::SimplexV SimplexV;
struct HPP_FCL_DLLAPI SimplexF {
Vec3f n;
FCL_REAL d;
SimplexV* vertex[3]; // a face has three vertices
SimplexF* f[3]; // a face has three adjacent faces
SimplexF* l[2]; // the pre and post faces in the list
size_t e[3];
size_t pass;
SimplexF() : n(Vec3f::Zero()){};
};
struct HPP_FCL_DLLAPI SimplexList {
SimplexF* root;
size_t count;
SimplexList() : root(NULL), count(0) {}
void append(SimplexF* face) {
face->l[0] = NULL;
face->l[1] = root;
if (root) root->l[0] = face;
root = face;
++count;
}
void remove(SimplexF* face) {
if (face->l[1]) face->l[1]->l[0] = face->l[0];
if (face->l[0]) face->l[0]->l[1] = face->l[1];
if (face == root) root = face->l[1];
--count;
}
};
static inline void bind(SimplexF* fa, size_t ea, SimplexF* fb, size_t eb) {
fa->e[ea] = eb;
fa->f[ea] = fb;
fb->e[eb] = ea;
fb->f[eb] = fa;
}
struct HPP_FCL_DLLAPI SimplexHorizon {
SimplexF* cf; // current face in the horizon
SimplexF* ff; // first face in the horizon
size_t nf; // number of faces in the horizon
SimplexHorizon() : cf(NULL), ff(NULL), nf(0) {}
};
private:
unsigned int max_face_num;
unsigned int max_vertex_num;
unsigned int max_iterations;
FCL_REAL tolerance;
public:
enum Status {
Failed = 0,
Valid = 1,
AccuracyReached = 1 << 1 | Valid,
Degenerated = 1 << 1 | Failed,
NonConvex = 2 << 1 | Failed,
InvalidHull = 3 << 1 | Failed,
OutOfFaces = 4 << 1 | Failed,
OutOfVertices = 5 << 1 | Failed,
FallBack = 6 << 1 | Failed
};
Status status;
GJK::Simplex result;
Vec3f normal;
FCL_REAL depth;
SimplexV* sv_store;
SimplexF* fc_store;
size_t nextsv;
SimplexList hull, stock;
EPA(unsigned int max_face_num_, unsigned int max_vertex_num_,
unsigned int max_iterations_, FCL_REAL tolerance_)
: max_face_num(max_face_num_),
max_vertex_num(max_vertex_num_),
max_iterations(max_iterations_),
tolerance(tolerance_) {
initialize();
}
~EPA() {
delete[] sv_store;
delete[] fc_store;
}
void initialize();
Status evaluate(GJK& gjk, const Vec3f& guess);
bool getClosestPoints(const MinkowskiDiff& shape, Vec3f& w0, Vec3f& w1);
private:
bool getEdgeDist(SimplexF* face, SimplexV* a, SimplexV* b, FCL_REAL& dist);
SimplexF* newFace(SimplexV* a, SimplexV* b, SimplexV* vertex, bool forced);
SimplexF* findBest();
bool expand(size_t pass, SimplexV* w, SimplexF* f, size_t e,
SimplexHorizon& horizon);
};
} // namespace details
} // namespace fcl
} // namespace hpp
#endif