minkowski_difference.cpp
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 
41 
42 namespace coal {
43 namespace details {
44 
45 // ============================================================================
46 template <typename Shape0, typename Shape1, bool TransformIsIdentity,
47  int _SupportOptions>
48 void getSupportTpl(const Shape0* s0, const Shape1* s1, const Matrix3s& oR1,
49  const Vec3s& ot1, const Vec3s& dir, Vec3s& support0,
50  Vec3s& support1, support_func_guess_t& hint,
51  ShapeSupportData data[2]) {
52  assert(dir.norm() > Eigen::NumTraits<CoalScalar>::epsilon());
53  getShapeSupport<_SupportOptions>(s0, dir, support0, hint[0], data[0]);
54 
55  if (TransformIsIdentity) {
56  getShapeSupport<_SupportOptions>(s1, -dir, support1, hint[1], data[1]);
57  } else {
58  getShapeSupport<_SupportOptions>(s1, -oR1.transpose() * dir, support1,
59  hint[1], data[1]);
60  support1 = oR1 * support1 + ot1;
61  }
62 }
63 
64 // ============================================================================
65 template <typename Shape0, typename Shape1, bool TransformIsIdentity,
66  int _SupportOptions>
67 void getSupportFuncTpl(const MinkowskiDiff& md, const Vec3s& dir,
68  Vec3s& support0, Vec3s& support1,
69  support_func_guess_t& hint, ShapeSupportData data[2]) {
70  getSupportTpl<Shape0, Shape1, TransformIsIdentity, _SupportOptions>(
71  static_cast<const Shape0*>(md.shapes[0]),
72  static_cast<const Shape1*>(md.shapes[1]), md.oR1, md.ot1, dir, support0,
73  support1, hint, data);
74 }
75 
76 // ============================================================================
77 template <typename Shape0, int _SupportOptions>
79  const ShapeBase* s1, bool identity,
80  Eigen::Array<CoalScalar, 1, 2>& swept_sphere_radius,
81  ShapeSupportData data[2]) {
82  if (_SupportOptions == SupportOptions::WithSweptSphere) {
83  // No need to store the information of swept sphere radius
84  swept_sphere_radius[1] = 0;
85  } else {
86  // We store the information of swept sphere radius.
87  // GJK and EPA will use this information to correct the solution they find.
88  swept_sphere_radius[1] = s1->getSweptSphereRadius();
89  }
90 
91  switch (s1->getNodeType()) {
92  case GEOM_TRIANGLE:
93  if (identity)
94  return getSupportFuncTpl<Shape0, TriangleP, true, _SupportOptions>;
95  else
96  return getSupportFuncTpl<Shape0, TriangleP, false, _SupportOptions>;
97  case GEOM_BOX:
98  if (identity)
99  return getSupportFuncTpl<Shape0, Box, true, _SupportOptions>;
100  else
101  return getSupportFuncTpl<Shape0, Box, false, _SupportOptions>;
102  case GEOM_SPHERE:
103  if (_SupportOptions == SupportOptions::NoSweptSphere) {
104  // Sphere can be considered a swept-sphere point.
105  swept_sphere_radius[1] += static_cast<const Sphere*>(s1)->radius;
106  }
107  if (identity)
108  return getSupportFuncTpl<Shape0, Sphere, true, _SupportOptions>;
109  else
110  return getSupportFuncTpl<Shape0, Sphere, false, _SupportOptions>;
111  case GEOM_ELLIPSOID:
112  if (identity)
113  return getSupportFuncTpl<Shape0, Ellipsoid, true, _SupportOptions>;
114  else
115  return getSupportFuncTpl<Shape0, Ellipsoid, false, _SupportOptions>;
116  case GEOM_CAPSULE:
117  if (_SupportOptions == SupportOptions::NoSweptSphere) {
118  // Sphere can be considered as a swept-sphere segment.
119  swept_sphere_radius[1] += static_cast<const Capsule*>(s1)->radius;
120  }
121  if (identity)
122  return getSupportFuncTpl<Shape0, Capsule, true, _SupportOptions>;
123  else
124  return getSupportFuncTpl<Shape0, Capsule, false, _SupportOptions>;
125  case GEOM_CONE:
126  if (identity)
127  return getSupportFuncTpl<Shape0, Cone, true, _SupportOptions>;
128  else
129  return getSupportFuncTpl<Shape0, Cone, false, _SupportOptions>;
130  case GEOM_CYLINDER:
131  if (identity)
132  return getSupportFuncTpl<Shape0, Cylinder, true, _SupportOptions>;
133  else
134  return getSupportFuncTpl<Shape0, Cylinder, false, _SupportOptions>;
135  case GEOM_CONVEX: {
136  const ConvexBase* convex1 = static_cast<const ConvexBase*>(s1);
137  if (static_cast<size_t>(convex1->num_points) >
139  data[1].visited.assign(convex1->num_points, false);
140  data[1].last_dir.setZero();
141  if (identity)
142  return getSupportFuncTpl<Shape0, LargeConvex, true, _SupportOptions>;
143  else
144  return getSupportFuncTpl<Shape0, LargeConvex, false, _SupportOptions>;
145  } else {
146  if (identity)
147  return getSupportFuncTpl<Shape0, SmallConvex, true, _SupportOptions>;
148  else
149  return getSupportFuncTpl<Shape0, SmallConvex, false, _SupportOptions>;
150  }
151  }
152  default:
153  COAL_THROW_PRETTY("Unsupported geometric shape.", std::logic_error);
154  }
155 }
156 
157 // ============================================================================
158 template <int _SupportOptions>
160  const ShapeBase* s0, const ShapeBase* s1, bool identity,
161  Eigen::Array<CoalScalar, 1, 2>& swept_sphere_radius,
162  ShapeSupportData data[2]) {
163  if (_SupportOptions == SupportOptions::WithSweptSphere) {
164  // No need to store the information of swept sphere radius
165  swept_sphere_radius[0] = 0;
166  } else {
167  // We store the information of swept sphere radius.
168  // GJK and EPA will use this information to correct the solution they find.
169  swept_sphere_radius[0] = s0->getSweptSphereRadius();
170  }
171 
172  switch (s0->getNodeType()) {
173  case GEOM_TRIANGLE:
174  return makeGetSupportFunction1<TriangleP, _SupportOptions>(
175  s1, identity, swept_sphere_radius, data);
176  break;
177  case GEOM_BOX:
178  return makeGetSupportFunction1<Box, _SupportOptions>(
179  s1, identity, swept_sphere_radius, data);
180  break;
181  case GEOM_SPHERE:
182  if (_SupportOptions == SupportOptions::NoSweptSphere) {
183  // Sphere can always be considered as a swept-sphere point.
184  swept_sphere_radius[0] += static_cast<const Sphere*>(s0)->radius;
185  }
186  return makeGetSupportFunction1<Sphere, _SupportOptions>(
187  s1, identity, swept_sphere_radius, data);
188  break;
189  case GEOM_ELLIPSOID:
190  return makeGetSupportFunction1<Ellipsoid, _SupportOptions>(
191  s1, identity, swept_sphere_radius, data);
192  break;
193  case GEOM_CAPSULE:
194  if (_SupportOptions == SupportOptions::NoSweptSphere) {
195  // Capsule can always be considered as a swept-sphere segment.
196  swept_sphere_radius[0] += static_cast<const Capsule*>(s0)->radius;
197  }
198  return makeGetSupportFunction1<Capsule, _SupportOptions>(
199  s1, identity, swept_sphere_radius, data);
200  break;
201  case GEOM_CONE:
202  return makeGetSupportFunction1<Cone, _SupportOptions>(
203  s1, identity, swept_sphere_radius, data);
204  break;
205  case GEOM_CYLINDER:
206  return makeGetSupportFunction1<Cylinder, _SupportOptions>(
207  s1, identity, swept_sphere_radius, data);
208  break;
209  case GEOM_CONVEX: {
210  const ConvexBase* convex0 = static_cast<const ConvexBase*>(s0);
211  if (static_cast<size_t>(convex0->num_points) >
213  data[0].visited.assign(convex0->num_points, false);
214  data[0].last_dir.setZero();
215  return makeGetSupportFunction1<LargeConvex, _SupportOptions>(
216  s1, identity, swept_sphere_radius, data);
217  } else
218  return makeGetSupportFunction1<SmallConvex, _SupportOptions>(
219  s1, identity, swept_sphere_radius, data);
220  break;
221  }
222  default:
223  COAL_THROW_PRETTY("Unsupported geometric shape", std::logic_error);
224  }
225 }
226 
227 // ============================================================================
229  switch (shape->getNodeType()) {
230  case GEOM_TRIANGLE:
232  break;
233  case GEOM_BOX:
235  break;
236  case GEOM_SPHERE:
238  break;
239  case GEOM_ELLIPSOID:
241  break;
242  case GEOM_CAPSULE:
244  break;
245  case GEOM_CONE:
247  break;
248  case GEOM_CYLINDER:
250  break;
251  case GEOM_CONVEX:
253  break;
254  default:
255  COAL_THROW_PRETTY("Unsupported geometric shape", std::logic_error);
256  }
257 }
258 
259 // ============================================================================
261  const ShapeBase* shape1,
262  bool& normalize_support_direction) {
263  normalize_support_direction = getNormalizeSupportDirection(shape0) &&
265 }
266 
267 // ============================================================================
268 template <int _SupportOptions>
269 void MinkowskiDiff::set(const ShapeBase* shape0, const ShapeBase* shape1,
270  const Transform3s& tf0, const Transform3s& tf1) {
271  shapes[0] = shape0;
272  shapes[1] = shape1;
275 
276  oR1.noalias() = tf0.getRotation().transpose() * tf1.getRotation();
277  ot1.noalias() = tf0.getRotation().transpose() *
278  (tf1.getTranslation() - tf0.getTranslation());
279 
280  bool identity = (oR1.isIdentity() && ot1.isZero());
281 
282  getSupportFunc = makeGetSupportFunction0<_SupportOptions>(
283  shape0, shape1, identity, swept_sphere_radius, data);
284 }
285 // clang-format off
286 template void COAL_DLLAPI MinkowskiDiff::set<SupportOptions::NoSweptSphere>(const ShapeBase*, const ShapeBase*);
287 
288 template void COAL_DLLAPI MinkowskiDiff::set<SupportOptions::WithSweptSphere>(const ShapeBase*, const ShapeBase*);
289 // clang-format on
290 
291 // ============================================================================
292 template <int _SupportOptions>
293 void MinkowskiDiff::set(const ShapeBase* shape0, const ShapeBase* shape1) {
294  shapes[0] = shape0;
295  shapes[1] = shape1;
298 
299  oR1.setIdentity();
300  ot1.setZero();
301 
302  getSupportFunc = makeGetSupportFunction0<_SupportOptions>(
303  shape0, shape1, true, swept_sphere_radius, data);
304 }
305 // clang-format off
306 template void COAL_DLLAPI MinkowskiDiff::set<SupportOptions::NoSweptSphere>(const ShapeBase*, const ShapeBase*, const Transform3s&, const Transform3s&);
307 
308 template void COAL_DLLAPI MinkowskiDiff::set<SupportOptions::WithSweptSphere>(const ShapeBase*, const ShapeBase*, const Transform3s&, const Transform3s&);
309 // clang-format on
310 
311 // ============================================================================
312 // clang-format off
313 template Vec3s COAL_DLLAPI MinkowskiDiff::support0<SupportOptions::NoSweptSphere>(const Vec3s&, int&) const;
314 
315 template Vec3s COAL_DLLAPI MinkowskiDiff::support0<SupportOptions::WithSweptSphere>(const Vec3s&, int&) const;
316 
317 template Vec3s COAL_DLLAPI MinkowskiDiff::support1<SupportOptions::NoSweptSphere>(const Vec3s&, int&) const;
318 
319 template Vec3s COAL_DLLAPI MinkowskiDiff::support1<SupportOptions::WithSweptSphere>(const Vec3s&, int&) const;
320 // clang-format on
321 
322 } // namespace details
323 } // namespace coal
coal::CollisionGeometry::getNodeType
virtual NODE_TYPE getNodeType() const
get the node type
Definition: coal/collision_object.h:130
coal::details::makeGetSupportFunction1
MinkowskiDiff::GetSupportFunction makeGetSupportFunction1(const ShapeBase *s1, bool identity, Eigen::Array< CoalScalar, 1, 2 > &swept_sphere_radius, ShapeSupportData data[2])
Definition: minkowski_difference.cpp:78
coal::details::getSupportTpl
void getSupportTpl(const Shape0 *s0, const Shape1 *s1, const Matrix3s &oR1, const Vec3s &ot1, const Vec3s &dir, Vec3s &support0, Vec3s &support1, support_func_guess_t &hint, ShapeSupportData data[2])
Definition: minkowski_difference.cpp:48
coal::Vec3s
Eigen::Matrix< CoalScalar, 3, 1 > Vec3s
Definition: coal/data_types.h:77
coal::details::getNormalizeSupportDirectionFromShapes
void getNormalizeSupportDirectionFromShapes(const ShapeBase *shape0, const ShapeBase *shape1, bool &normalize_support_direction)
Definition: minkowski_difference.cpp:260
coal::ConvexBase::num_points
unsigned int num_points
Definition: coal/shape/geometric_shapes.h:720
coal::details::MinkowskiDiff::normalize_support_direction
bool normalize_support_direction
Wether or not to use the normalize heuristic in the GJK Nesterov acceleration. This setting is only a...
Definition: coal/narrowphase/minkowski_difference.h:79
coal::details::ShapeSupportData
Stores temporary data for the computation of support points.
Definition: coal/narrowphase/support_functions.h:80
coal::details::MinkowskiDiff
Minkowski difference class of two shapes.
Definition: coal/narrowphase/minkowski_difference.h:53
coal::GEOM_CONE
@ GEOM_CONE
Definition: coal/collision_object.h:77
coal::GEOM_CONVEX
@ GEOM_CONVEX
Definition: coal/collision_object.h:79
gjk.tf1
tuple tf1
Definition: test/scripts/gjk.py:27
coal::details::MinkowskiDiff::GetSupportFunction
void(* GetSupportFunction)(const MinkowskiDiff &minkowskiDiff, const Vec3s &dir, Vec3s &support0, Vec3s &support1, support_func_guess_t &hint, ShapeSupportData data[2])
Definition: coal/narrowphase/minkowski_difference.h:81
coal::Capsule
Capsule It is where is the distance between the point x and the capsule segment AB,...
Definition: coal/shape/geometric_shapes.h:383
data
data
coal
Main namespace.
Definition: coal/broadphase/broadphase_bruteforce.h:44
coal::GEOM_CAPSULE
@ GEOM_CAPSULE
Definition: coal/collision_object.h:76
coal::details::NoSweptSphere
@ NoSweptSphere
Definition: coal/narrowphase/support_functions.h:59
coal::shape_traits
Definition: coal/shape/geometric_shapes_traits.h:55
coal::GEOM_SPHERE
@ GEOM_SPHERE
Definition: coal/collision_object.h:75
coal::details::WithSweptSphere
@ WithSweptSphere
Definition: coal/narrowphase/support_functions.h:60
coal::details::getSupportFuncTpl
void getSupportFuncTpl(const MinkowskiDiff &md, const Vec3s &dir, Vec3s &support0, Vec3s &support1, support_func_guess_t &hint, ShapeSupportData data[2])
Definition: minkowski_difference.cpp:67
coal::details::MinkowskiDiff::getSupportFunc
GetSupportFunction getSupportFunc
Definition: coal/narrowphase/minkowski_difference.h:86
coal::Sphere
Center at zero point sphere.
Definition: coal/shape/geometric_shapes.h:240
coal::Transform3s
Simple transform class used locally by InterpMotion.
Definition: coal/math/transform.h:55
coal::details::MinkowskiDiff::swept_sphere_radius
Array2d swept_sphere_radius
The radii of the sphere swepted around each shape of the Minkowski difference. The 2 values correspon...
Definition: coal/narrowphase/minkowski_difference.h:74
coal::support_func_guess_t
Eigen::Vector2i support_func_guess_t
Definition: coal/data_types.h:87
coal::GEOM_ELLIPSOID
@ GEOM_ELLIPSOID
Definition: coal/collision_object.h:84
coal::details::makeGetSupportFunction0
MinkowskiDiff::GetSupportFunction makeGetSupportFunction0(const ShapeBase *s0, const ShapeBase *s1, bool identity, Eigen::Array< CoalScalar, 1, 2 > &swept_sphere_radius, ShapeSupportData data[2])
Definition: minkowski_difference.cpp:159
coal::ShapeBase
Base class for all basic geometric shapes.
Definition: coal/shape/geometric_shapes.h:58
COAL_THROW_PRETTY
#define COAL_THROW_PRETTY(message, exception)
Definition: include/coal/fwd.hh:64
geometric_shapes_traits.h
coal::GEOM_TRIANGLE
@ GEOM_TRIANGLE
Definition: coal/collision_object.h:82
coal::details::getNormalizeSupportDirection
bool getNormalizeSupportDirection(const ShapeBase *shape)
Definition: minkowski_difference.cpp:228
coal::details::MinkowskiDiff::ot1
Vec3s ot1
translation from shape1 to shape0 such that .
Definition: coal/narrowphase/minkowski_difference.h:69
minkowski_difference.h
coal::Transform3s::getRotation
const Matrix3s & getRotation() const
get rotation
Definition: coal/math/transform.h:110
coal::GEOM_CYLINDER
@ GEOM_CYLINDER
Definition: coal/collision_object.h:78
coal::ShapeBase::getSweptSphereRadius
CoalScalar getSweptSphereRadius() const
Get radius of sphere swept around the shape. This radius is always >= 0.
Definition: coal/shape/geometric_shapes.h:86
epsilon
static CoalScalar epsilon
Definition: simple.cpp:12
coal::details::MinkowskiDiff::set
void set(const ShapeBase *shape0, const ShapeBase *shape1)
Set the two shapes, assuming the relative transformation between them is identity....
Definition: minkowski_difference.cpp:293
coal::details::MinkowskiDiff::data
ShapeSupportData data[2]
Store temporary data for the computation of the support point for each shape.
Definition: coal/narrowphase/minkowski_difference.h:61
coal::Matrix3s
Eigen::Matrix< CoalScalar, 3, 3 > Matrix3s
Definition: coal/data_types.h:81
coal::details::MinkowskiDiff::oR1
Matrix3s oR1
rotation from shape1 to shape0 such that .
Definition: coal/narrowphase/minkowski_difference.h:65
coal::details::MinkowskiDiff::shapes
const ShapeBase * shapes[2]
points to two shapes
Definition: coal/narrowphase/minkowski_difference.h:57
coal::GEOM_BOX
@ GEOM_BOX
Definition: coal/collision_object.h:74
coal::ConvexBase::num_vertices_large_convex_threshold
static constexpr size_t num_vertices_large_convex_threshold
Above this threshold, the convex polytope is considered large. This influcences the way the support f...
Definition: coal/shape/geometric_shapes.h:716
coal::ConvexBase
Base for convex polytope.
Definition: coal/shape/geometric_shapes.h:645
coal::Transform3s::getTranslation
const Vec3s & getTranslation() const
get translation
Definition: coal/math/transform.h:101


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