collision_data.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  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  * * Neither the name of Open Source Robotics Foundation nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35 
38 #ifndef HPP_FCL_COLLISION_DATA_H
39 #define HPP_FCL_COLLISION_DATA_H
40 
41 #include <vector>
42 #include <set>
43 #include <limits>
44 
46 #include <hpp/fcl/config.hh>
47 #include <hpp/fcl/data_types.h>
48 #include <hpp/fcl/timings.h>
49 
50 namespace hpp {
51 namespace fcl {
52 
54 struct HPP_FCL_DLLAPI Contact {
57 
60 
65  int b1;
66 
71  int b2;
72 
75 
78 
81 
83  static const int NONE = -1;
84 
86  Contact() : o1(NULL), o2(NULL), b1(NONE), b2(NONE) {}
87 
88  Contact(const CollisionGeometry* o1_, const CollisionGeometry* o2_, int b1_,
89  int b2_)
90  : o1(o1_), o2(o2_), b1(b1_), b2(b2_) {}
91 
92  Contact(const CollisionGeometry* o1_, const CollisionGeometry* o2_, int b1_,
93  int b2_, const Vec3f& pos_, const Vec3f& normal_, FCL_REAL depth_)
94  : o1(o1_),
95  o2(o2_),
96  b1(b1_),
97  b2(b2_),
98  normal(normal_),
99  pos(pos_),
100  penetration_depth(depth_) {}
101 
102  bool operator<(const Contact& other) const {
103  if (b1 == other.b1) return b2 < other.b2;
104  return b1 < other.b1;
105  }
106 
107  bool operator==(const Contact& other) const {
108  return o1 == other.o1 && o2 == other.o2 && b1 == other.b1 &&
109  b2 == other.b2 && normal == other.normal && pos == other.pos &&
110  penetration_depth == other.penetration_depth;
111  }
112 
113  bool operator!=(const Contact& other) const { return !(*this == other); }
114 };
115 
116 struct QueryResult;
117 
119 struct HPP_FCL_DLLAPI QueryRequest {
120  // @briefInitial guess to use for the GJK algorithm
122 
125  HPP_FCL_DEPRECATED_MESSAGE("Use gjk_initial_guess instead")
126  bool enable_cached_gjk_guess;
127 
129  GJKVariant gjk_variant;
130 
132  GJKConvergenceCriterion gjk_convergence_criterion;
133 
135  GJKConvergenceCriterionType gjk_convergence_criterion_type;
136 
138  FCL_REAL gjk_tolerance;
139 
141  size_t gjk_max_iterations;
142 
144  Vec3f cached_gjk_guess;
145 
147  support_func_guess_t cached_support_func_guess;
148 
150  bool enable_timings;
151 
153  FCL_REAL collision_distance_threshold;
154 
159  : gjk_initial_guess(GJKInitialGuess::DefaultGuess),
160  enable_cached_gjk_guess(false),
161  gjk_variant(GJKVariant::DefaultGJK),
162  gjk_convergence_criterion(GJKConvergenceCriterion::VDB),
163  gjk_convergence_criterion_type(GJKConvergenceCriterionType::Relative),
164  gjk_tolerance(1e-6),
165  gjk_max_iterations(128),
166  cached_gjk_guess(1, 0, 0),
167  cached_support_func_guess(support_func_guess_t::Zero()),
168  enable_timings(false),
169  collision_distance_threshold(
170  Eigen::NumTraits<FCL_REAL>::dummy_precision()) {}
171 
173  QueryRequest(const QueryRequest& other) = default;
174 
176  QueryRequest& operator=(const QueryRequest& other) = default;
178 
179  void updateGuess(const QueryResult& result);
180 
182  inline bool operator==(const QueryRequest& other) const {
185  return gjk_initial_guess == other.gjk_initial_guess &&
186  enable_cached_gjk_guess == other.enable_cached_gjk_guess &&
187  cached_gjk_guess == other.cached_gjk_guess &&
188  cached_support_func_guess == other.cached_support_func_guess &&
189  enable_timings == other.enable_timings;
191  }
192 };
193 
195 struct HPP_FCL_DLLAPI QueryResult {
198 
201 
204 
206  : cached_gjk_guess(Vec3f::Zero()),
207  cached_support_func_guess(support_func_guess_t::Constant(-1)) {}
208 };
209 
210 inline void QueryRequest::updateGuess(const QueryResult& result) {
211  if (gjk_initial_guess == GJKInitialGuess::CachedGuess) {
212  cached_gjk_guess = result.cached_gjk_guess;
213  cached_support_func_guess = result.cached_support_func_guess;
214  }
215  // TODO: use gjk_initial_guess instead
218  if (enable_cached_gjk_guess) {
219  cached_gjk_guess = result.cached_gjk_guess;
220  cached_support_func_guess = result.cached_support_func_guess;
221  }
223 }
224 
225 struct CollisionResult;
226 
229  CONTACT = 0x00001,
231  NO_REQUEST = 0x01000
232 };
233 
235 struct HPP_FCL_DLLAPI CollisionRequest : QueryRequest {
238 
242 
245 
252 
256 
264 
270  CollisionRequest(const CollisionRequestFlag flag, size_t num_max_contacts_)
271  : num_max_contacts(num_max_contacts_),
272  enable_contact(flag & CONTACT),
273  enable_distance_lower_bound(flag & DISTANCE_LOWER_BOUND),
274  security_margin(0),
275  break_distance(1e-3),
276  distance_upper_bound((std::numeric_limits<FCL_REAL>::max)()) {}
277 
280  : num_max_contacts(1),
281  enable_contact(false),
282  enable_distance_lower_bound(false),
283  security_margin(0),
284  break_distance(1e-3),
285  distance_upper_bound((std::numeric_limits<FCL_REAL>::max)()) {}
286 
287  bool isSatisfied(const CollisionResult& result) const;
288 
290  inline bool operator==(const CollisionRequest& other) const {
291  return QueryRequest::operator==(other) &&
292  num_max_contacts == other.num_max_contacts &&
293  enable_contact == other.enable_contact &&
294  enable_distance_lower_bound == other.enable_distance_lower_bound &&
295  security_margin == other.security_margin &&
296  break_distance == other.break_distance &&
297  distance_upper_bound == other.distance_upper_bound;
298  }
299 };
300 
302 struct HPP_FCL_DLLAPI CollisionResult : QueryResult {
303  private:
305  std::vector<Contact> contacts;
306 
307  public:
313 
317  Vec3f nearest_points[2];
318 
319  public:
321  : distance_lower_bound((std::numeric_limits<FCL_REAL>::max)()) {}
322 
324  inline void updateDistanceLowerBound(const FCL_REAL& distance_lower_bound_) {
325  if (distance_lower_bound_ < distance_lower_bound)
326  distance_lower_bound = distance_lower_bound_;
327  }
328 
330  inline void addContact(const Contact& c) { contacts.push_back(c); }
331 
333  inline bool operator==(const CollisionResult& other) const {
334  return contacts == other.contacts &&
335  distance_lower_bound == other.distance_lower_bound;
336  }
337 
339  bool isCollision() const { return contacts.size() > 0; }
340 
342  size_t numContacts() const { return contacts.size(); }
343 
345  const Contact& getContact(size_t i) const {
346  if (contacts.size() == 0)
347  throw std::invalid_argument(
348  "The number of contacts is zero. No Contact can be returned.");
349 
350  if (i < contacts.size())
351  return contacts[i];
352  else
353  return contacts.back();
354  }
355 
357  void setContact(size_t i, const Contact& c) {
358  if (contacts.size() == 0)
359  throw std::invalid_argument(
360  "The number of contacts is zero. No Contact can be returned.");
361 
362  if (i < contacts.size())
363  contacts[i] = c;
364  else
365  contacts.back() = c;
366  }
367 
369  void getContacts(std::vector<Contact>& contacts_) const {
370  contacts_.resize(contacts.size());
371  std::copy(contacts.begin(), contacts.end(), contacts_.begin());
372  }
373 
374  const std::vector<Contact>& getContacts() const { return contacts; }
375 
377  void clear() {
378  distance_lower_bound = (std::numeric_limits<FCL_REAL>::max)();
379  contacts.clear();
380  distance_lower_bound = (std::numeric_limits<FCL_REAL>::max)();
381  timings.clear();
382  }
383 
386  void swapObjects();
387 };
388 
389 struct DistanceResult;
390 
392 struct HPP_FCL_DLLAPI DistanceRequest : QueryRequest {
395 
397  FCL_REAL rel_err; // relative error, between 0 and 1
398  FCL_REAL abs_err; // absolute error
399 
403  DistanceRequest(bool enable_nearest_points_ = false, FCL_REAL rel_err_ = 0.0,
404  FCL_REAL abs_err_ = 0.0)
405  : enable_nearest_points(enable_nearest_points_),
406  rel_err(rel_err_),
407  abs_err(abs_err_) {}
408 
409  bool isSatisfied(const DistanceResult& result) const;
410 
412  inline bool operator==(const DistanceRequest& other) const {
413  return QueryRequest::operator==(other) &&
414  enable_nearest_points == other.enable_nearest_points &&
415  rel_err == other.rel_err && abs_err == other.abs_err;
416  }
417 };
418 
420 struct HPP_FCL_DLLAPI DistanceResult : QueryResult {
421  public:
425 
427  Vec3f nearest_points[2];
428 
431 
434 
437 
442  int b1;
443 
448  int b2;
449 
451  static const int NONE = -1;
452 
454  FCL_REAL min_distance_ = (std::numeric_limits<FCL_REAL>::max)())
455  : min_distance(min_distance_), o1(NULL), o2(NULL), b1(NONE), b2(NONE) {
456  const Vec3f nan(
457  Vec3f::Constant(std::numeric_limits<FCL_REAL>::quiet_NaN()));
458  nearest_points[0] = nearest_points[1] = normal = nan;
459  }
460 
463  const CollisionGeometry* o2_, int b1_, int b2_) {
464  if (min_distance > distance) {
465  min_distance = distance;
466  o1 = o1_;
467  o2 = o2_;
468  b1 = b1_;
469  b2 = b2_;
470  }
471  }
472 
475  const CollisionGeometry* o2_, int b1_, int b2_, const Vec3f& p1,
476  const Vec3f& p2, const Vec3f& normal_) {
477  if (min_distance > distance) {
478  min_distance = distance;
479  o1 = o1_;
480  o2 = o2_;
481  b1 = b1_;
482  b2 = b2_;
483  nearest_points[0] = p1;
484  nearest_points[1] = p2;
485  normal = normal_;
486  }
487  }
488 
490  void update(const DistanceResult& other_result) {
491  if (min_distance > other_result.min_distance) {
492  min_distance = other_result.min_distance;
493  o1 = other_result.o1;
494  o2 = other_result.o2;
495  b1 = other_result.b1;
496  b2 = other_result.b2;
497  nearest_points[0] = other_result.nearest_points[0];
498  nearest_points[1] = other_result.nearest_points[1];
499  normal = other_result.normal;
500  }
501  }
502 
504  void clear() {
505  const Vec3f nan(
506  Vec3f::Constant(std::numeric_limits<FCL_REAL>::quiet_NaN()));
507  min_distance = (std::numeric_limits<FCL_REAL>::max)();
508  o1 = NULL;
509  o2 = NULL;
510  b1 = NONE;
511  b2 = NONE;
512  nearest_points[0] = nearest_points[1] = normal = nan;
513  timings.clear();
514  }
515 
517  inline bool operator==(const DistanceResult& other) const {
518  bool is_same = min_distance == other.min_distance &&
519  nearest_points[0] == other.nearest_points[0] &&
520  nearest_points[1] == other.nearest_points[1] &&
521  normal == other.normal && o1 == other.o1 && o2 == other.o2 &&
522  b1 == other.b1 && b2 == other.b2;
523 
524  // TODO: check also that two GeometryObject are indeed equal.
525  if ((o1 != NULL) ^ (other.o1 != NULL)) return false;
526  is_same &= (o1 == other.o1);
527  // else if (o1 != NULL and other.o1 != NULL) is_same &= *o1 == *other.o1;
528 
529  if ((o2 != NULL) ^ (other.o2 != NULL)) return false;
530  is_same &= (o2 == other.o2);
531  // else if (o2 != NULL and other.o2 != NULL) is_same &= *o2 == *other.o2;
532 
533  return is_same;
534  }
535 };
536 
537 namespace internal {
539  CollisionResult& res,
540  const FCL_REAL& sqrDistLowerBound) {
541  // BV cannot find negative distance.
542  if (res.distance_lower_bound <= 0) return;
543  FCL_REAL new_dlb = std::sqrt(sqrDistLowerBound); // - req.security_margin;
544  if (new_dlb < res.distance_lower_bound) res.distance_lower_bound = new_dlb;
545 }
546 
548  CollisionResult& res,
549  const FCL_REAL& distance,
550  const Vec3f& p0, const Vec3f& p1) {
551  if (distance < res.distance_lower_bound) {
553  res.nearest_points[0] = p0;
554  res.nearest_points[1] = p1;
555  }
556 }
557 } // namespace internal
558 
560  return static_cast<CollisionRequestFlag>(~static_cast<int>(a));
561 }
562 
565  return static_cast<CollisionRequestFlag>(static_cast<int>(a) |
566  static_cast<int>(b));
567 }
568 
571  return static_cast<CollisionRequestFlag>(static_cast<int>(a) &
572  static_cast<int>(b));
573 }
574 
577  return static_cast<CollisionRequestFlag>(static_cast<int>(a) ^
578  static_cast<int>(b));
579 }
580 
583  return (CollisionRequestFlag&)((int&)(a) |= static_cast<int>(b));
584 }
585 
588  return (CollisionRequestFlag&)((int&)(a) &= static_cast<int>(b));
589 }
590 
593  return (CollisionRequestFlag&)((int&)(a) ^= static_cast<int>(b));
594 }
595 
596 } // namespace fcl
597 
598 } // namespace hpp
599 
600 #endif
Contact(const CollisionGeometry *o1_, const CollisionGeometry *o2_, int b1_, int b2_)
support_func_guess_t cached_support_func_guess
the support function initial guess set by user
size_t num_max_contacts
The maximum number of contacts will return.
GJKConvergenceCriterionType
Wether the convergence criterion is scaled on the norm of the solution or not.
Definition: data_types.h:93
CollisionRequestFlag operator|(CollisionRequestFlag a, CollisionRequestFlag b)
GJKInitialGuess gjk_initial_guess
request to the distance computation
bool operator==(const QueryRequest &other) const
whether two QueryRequest are the same or not
void update(const DistanceResult &other_result)
add distance information into the result
support_func_guess_t cached_support_func_guess
stores the last support function vertex index, when relevant.
tuple p1
Definition: octree.py:55
GJKVariant
Variant to use for the GJK algorithm.
Definition: data_types.h:83
const CollisionGeometry * o1
collision object 1
base class for all query results
FCL_REAL distance_upper_bound
Distance above which GJK solver makes an early stopping. GJK stops searching for the closest points w...
bool operator==(const DistanceRequest &other) const
whether two DistanceRequest are the same or not
Main namespace.
std::vector< Contact > contacts
contact information
int b2
information about the nearest point in object 2 if object 2 is mesh or point cloud, it is the triangle or point id if object 2 is geometry shape, it is NONE (-1), if object 2 is octree, it is the id of the cell
Vec3f nearest_points[2]
nearest points
bool operator==(const Contact &other) const
bool enable_cached_gjk_guess
whether enable gjk initial guess Use gjk_initial_guess instead
void updateDistanceLowerBound(const FCL_REAL &distance_lower_bound_)
Update the lower bound only if the distance is inferior.
CollisionRequestFlag & operator|=(CollisionRequestFlag &a, CollisionRequestFlag b)
size_t numContacts() const
number of contacts found
void addContact(const Contact &c)
add one contact into result structure
bool operator!=(const Contact &other) const
bool operator==(const CollisionResult &other) const
whether two CollisionResult are the same or not
void clear()
clear the result
const CollisionGeometry * o1
collision object 1
CollisionRequestFlag & operator &=(CollisionRequestFlag &a, CollisionRequestFlag b)
#define HPP_FCL_COMPILER_DIAGNOSTIC_POP
#define HPP_FCL_COMPILER_DIAGNOSTIC_IGNORED_DEPRECECATED_DECLARATIONS
CollisionRequestFlag
flag declaration for specifying required params in CollisionResult
Vec3f nearest_points[2]
nearest points available only when distance_lower_bound is inferior to CollisionRequest::break_distan...
CollisionRequestFlag operator^(CollisionRequestFlag a, CollisionRequestFlag b)
request to the collision algorithm
void clear()
clear the results obtained
HPP_FCL_DLLAPI FCL_REAL distance(const Matrix3f &R0, const Vec3f &T0, const kIOS &b1, const kIOS &b2, Vec3f *P=NULL, Vec3f *Q=NULL)
Approximate distance between two kIOS bounding volumes.
Definition: kIOS.cpp:181
FCL_REAL penetration_depth
penetration depth
double FCL_REAL
Definition: data_types.h:65
HPP_FCL_COMPILER_DIAGNOSTIC_POP void updateGuess(const QueryResult &result)
CollisionRequestFlag & operator^=(CollisionRequestFlag &a, CollisionRequestFlag b)
bool operator<(const Contact &other) const
FCL_REAL min_distance
minimum distance between two objects. if two objects are in collision, min_distance <= 0...
int b1
information about the nearest point in object 1 if object 1 is mesh or point cloud, it is the triangle or point id if object 1 is geometry shape, it is NONE (-1), if object 1 is octree, it is the id of the cell
Vec3f normal
In case both objects are in collision, store the normal.
GJKInitialGuess
Initial guess to use for the GJK algorithm DefaultGuess: Vec3f(1, 0, 0) CachedGuess: previous vector ...
Definition: data_types.h:80
void getContacts(std::vector< Contact > &contacts_) const
get all the contacts
void updateDistanceLowerBoundFromLeaf(const CollisionRequest &, CollisionResult &res, const FCL_REAL &distance, const Vec3f &p0, const Vec3f &p1)
Vec3f cached_gjk_guess
the gjk initial guess set by user
Contact(const CollisionGeometry *o1_, const CollisionGeometry *o2_, int b1_, int b2_, const Vec3f &pos_, const Vec3f &normal_, FCL_REAL depth_)
Eigen::Vector2i support_func_guess_t
Definition: data_types.h:72
Vec3f pos
contact position, in world space
CPUTimes timings
timings for the given request
bool enable_timings
enable timings when performing collision/distance request
DistanceResult(FCL_REAL min_distance_=(std::numeric_limits< FCL_REAL >::max)())
FCL_REAL break_distance
Distance below which bounding volumes are broken down. See Collision.
void setContact(size_t i, const Contact &c)
set the i-th contact calculated
FCL_REAL rel_err
error threshold for approximate distance
CollisionRequest()
Default constructor.
bool enable_nearest_points
whether to return the nearest points
void updateDistanceLowerBoundFromBV(const CollisionRequest &, CollisionResult &res, const FCL_REAL &sqrDistLowerBound)
bool enable_distance_lower_bound
Whether a lower bound on distance is returned when objects are disjoint.
bool operator==(const DistanceResult &other) const
whether two DistanceResult are the same or not
bool operator==(const CollisionRequest &other) const
whether two CollisionRequest are the same or not
int b1
contact primitive in object 1 if object 1 is mesh or point cloud, it is the triangle or point id if o...
const Contact & getContact(size_t i) const
get the i-th contact calculated
CollisionRequestFlag operator &(CollisionRequestFlag a, CollisionRequestFlag b)
bool enable_contact
whether the contact information (normal, penetration depth and contact position) will return ...
Vec3f cached_gjk_guess
stores the last GJK ray when relevant.
bool isCollision() const
return binary collision result
base class for all query requests
CollisionRequestFlag operator~(CollisionRequestFlag a)
#define HPP_FCL_COMPILER_DIAGNOSTIC_PUSH
Eigen::Matrix< FCL_REAL, 3, 1 > Vec3f
Definition: data_types.h:66
const CollisionGeometry * o2
collision object 2
void update(FCL_REAL distance, const CollisionGeometry *o1_, const CollisionGeometry *o2_, int b1_, int b2_)
add distance information into the result
Contact information returned by collision.
GJKConvergenceCriterion
Which convergence criterion is used to stop the algorithm (when the shapes are not in collision)...
Definition: data_types.h:89
void update(FCL_REAL distance, const CollisionGeometry *o1_, const CollisionGeometry *o2_, int b1_, int b2_, const Vec3f &p1, const Vec3f &p2, const Vec3f &normal_)
add distance information into the result
int b2
contact primitive in object 2 if object 2 is mesh or point cloud, it is the triangle or point id if o...
The geometry for the object for collision or distance computation.
const std::vector< Contact > & getContacts() const
Vec3f normal
contact normal, pointing from o1 to o2
const CollisionGeometry * o2
collision object 2
DistanceRequest(bool enable_nearest_points_=false, FCL_REAL rel_err_=0.0, FCL_REAL abs_err_=0.0)
CollisionRequest(const CollisionRequestFlag flag, size_t num_max_contacts_)
Constructor from a flag and a maximal number of contacts.
FCL_REAL security_margin
Distance below which objects are considered in collision. See Collision.
Contact()
Default constructor.


hpp-fcl
Author(s):
autogenerated on Fri Jun 2 2023 02:39:00