hpp-constraints  4.9.1
Definition of basic geometric constraints for motion planning
convex-shape.hh
Go to the documentation of this file.
1 // Copyright (c) 2015, LAAS-CNRS
2 // Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
3 //
4 // This file is part of hpp-constraints.
5 // hpp-constraints is free software: you can redistribute it
6 // and/or modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation, either version
8 // 3 of the License, or (at your option) any later version.
9 //
10 // hpp-constraints is distributed in the hope that it will be
11 // useful, but WITHOUT ANY WARRANTY; without even the implied warranty
12 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Lesser Public License for more details. You should have
14 // received a copy of the GNU Lesser General Public License along with
15 // hpp-constraints. If not, see <http://www.gnu.org/licenses/>.
16 
17 #ifndef HPP_CONSTRAINTS_CONVEX_SHAPE_HH
18 # define HPP_CONSTRAINTS_CONVEX_SHAPE_HH
19 
20 # include <vector>
21 
22 # include <hpp/fcl/shape/geometric_shapes.h>
23 
24 // Only for specialization of vector3_t. This is a bad design of Pinocchio.
25 # include <pinocchio/multibody/model.hpp>
26 
27 # include <hpp/pinocchio/joint.hh>
28 
29 # include <hpp/constraints/fwd.hh>
30 # include <hpp/constraints/config.hh>
31 
32 namespace hpp {
33  namespace constraints {
39  inline void closestPointToSegment (const vector3_t& P,
40  const vector3_t& A, const vector3_t& v, vector3_t& B) {
41  vector3_t w = A - P;
42  value_type c1, c2;
43  c1 = v.dot (w);
44  c2 = v.dot(v);
45  if (c1 <= 0) B = A;
46  else if (c2 <= c1) B = A + v;
47  else B = A + c1 / c2 * v;
48  }
49 
56  const vector3_t& A, const vector3_t& u,
57  const vector3_t& P, const vector3_t& n)
58  {
59  assert (std::abs (n.dot(u)) > 1e-8);
60  return A + u * (n.dot(P - A)) / n.dot (u);
61  }
62 
63 
64  class HPP_CONSTRAINTS_DLLAPI ConvexShape
65  {
66  public:
75  ConvexShape (const std::vector <vector3_t>& pts, JointPtr_t joint = JointPtr_t()):
76  Pts_ (pts), joint_ (joint)
77  {
78  init ();
79  }
80 
81  ConvexShape (const fcl::TriangleP& t, const JointPtr_t& joint = JointPtr_t()):
82  Pts_ (triangleToPoints (t)), joint_ (joint)
83  {
84  init ();
85  }
86 
89  ConvexShape (const vector3_t& p0, const vector3_t& p1,
90  const vector3_t& p2, const JointPtr_t& joint = JointPtr_t()):
91  Pts_ (points(p0,p1,p2)), joint_ (joint)
92  {
93  init ();
94  }
95 
96  // Copy constructor
97  ConvexShape (const ConvexShape& t) :
98  Pts_ (t.Pts_), joint_ (t.joint_)
99  {
100  init ();
101  }
102 
103  void reverse () {
104  std::reverse (Pts_.begin (), Pts_.end());
105  init ();
106  }
107 
110  inline vector3_t intersectionLocal (const vector3_t& A, const vector3_t& u) const {
111  return linePlaneIntersection (A, u, C_, N_);
112  }
113 
115  inline bool isInsideLocal (const vector3_t& Ap) const {
116  assert (shapeDimension_ > 2);
117  for (std::size_t i = 0; i < shapeDimension_; ++i) {
118  if (Ns_[i].dot (Ap-Pts_[i]) > 0) return false;
119  }
120  return true;
121  }
122 
127  inline value_type distanceLocal (const vector3_t& a) const {
128  assert (shapeDimension_ > 1);
129  const value_type inf = std::numeric_limits<value_type>::infinity();
130  value_type minPosDist = inf, maxNegDist = - inf;
131  bool outside = false;
132  for (std::size_t i = 0; i < shapeDimension_; ++i) {
133  value_type d = dist (a - Pts_[i], Ls_[i], Us_[i], Ns_[i]);
134  if (d > 0) {
135  outside = true;
136  if (d < minPosDist) minPosDist = d;
137  }
138  if (d <= 0 && d > maxNegDist) maxNegDist = d;
139  }
140  if (outside) return minPosDist;
141  return maxNegDist;
142  }
143 
145  inline const vector3_t& planeXaxis () const {
146  assert (shapeDimension_ > 2);
147  return Ns_[0];
148  }
151  inline const vector3_t& planeYaxis () const {
152  assert (shapeDimension_ > 2);
153  return Us_[0];
154  }
155 
157  inline const Transform3f& positionInJoint () const { return MinJoint_; }
158 
160  std::vector <vector3_t> Pts_;
170  std::vector <vector3_t> Ns_, Us_;
174 
175  private:
179  inline value_type dist (const vector3_t& w, const value_type& c2, const vector3_t& v, const vector3_t& u) const {
180  value_type c1;
181  c1 = v.dot (w);
182  if (c1 <= 0)
183  return (u.dot (w) > 0)?(w.norm()):(- w.norm());
184  if (c2 <= c1)
185  // TODO: (w - c2 * v).norm() == sqrt((u.dot(w)**2 + (c1 - c2)**2)
186  // second should be cheaper.
187  return (u.dot (w) > 0)?((w-c2*v).norm()):(-(w-c2*v).norm());
188  return u.dot (w);
189  }
190 
191  static std::vector <vector3_t> triangleToPoints (const fcl::TriangleP& t) {
192  // TODO
193  // return points (t.a, t.b, t.c);
194  std::vector <vector3_t> ret (3);
195  ret[0] = t.a;
196  ret[1] = t.b;
197  ret[2] = t.c;
198  return ret;
199  }
200  static std::vector <vector3_t> points (const vector3_t& p0,
201  const vector3_t& p1, const vector3_t& p2) {
202  std::vector <vector3_t> ret (3);
203  ret[0] = p0; ret[1] = p1; ret[2] = p2;
204  return ret;
205  }
206 
207  void init ()
208  {
209  shapeDimension_ = Pts_.size ();
210 
211  switch (shapeDimension_) {
212  case 0:
213  throw std::logic_error ("Cannot represent an empty shape.");
214  break;
215  case 1:
216  C_ = Pts_[0];
217  // The transformation will be (N_, Ns_[0], Us_[0])
218  // Fill vectors so as to be consistent
219  N_ = vector3_t(1,0,0);
220  Ns_.push_back (vector3_t(0,1,0));
221  Us_.push_back (vector3_t(0,0,1));
222  break;
223  case 2:
224  Ls_ = vector_t(1);
225  C_ = (Pts_[0] + Pts_[1])/2;
226  // The transformation will be (N_, Ns_[0], Us_[0])
227  // Fill vectors so as to be consistent
228  Us_.push_back (Pts_[1] - Pts_[0]);
229  Ls_[0] = Us_[0].norm();
230  Us_[0].normalize ();
231  if (Us_[0][0] != 0) N_ = vector3_t(-Us_[0][1],Us_[0][0],0);
232  else N_ = vector3_t(0,-Us_[0][2],Us_[0][1]);
233  N_.normalize ();
234  Ns_.push_back (Us_[0].cross (N_));
235  Ns_[0].normalize (); // Should be unnecessary
236  break;
237  default:
238  Ls_ = vector_t(shapeDimension_);
239  C_.setZero ();
240  for (std::size_t i = 0; i < shapeDimension_; ++i)
241  C_ += Pts_[i];
242  // TODO This is very ugly. Why Eigen does not have the operator/=(int) ...
243  C_ /= (value_type)Pts_.size();
244  N_ = (Pts_[1] - Pts_[0]).cross (Pts_[2] - Pts_[1]);
245  assert (!N_.isZero ());
246  N_.normalize ();
247 
248  Us_.resize (Pts_.size());
249  Ns_.resize (Pts_.size());
250  for (std::size_t i = 0; i < shapeDimension_; ++i) {
251  Us_[i] = Pts_[(i+1)%shapeDimension_] - Pts_[i];
252  Ls_[i] = Us_[i].norm();
253  Us_[i].normalize ();
254  Ns_[i] = Us_[i].cross (N_);
255  Ns_[i].normalize ();
256  }
257  for (std::size_t i = 0; i < shapeDimension_; ++i) {
258  assert (Us_[(i+1)%shapeDimension_].dot (Ns_[i]) < 0 &&
259  "The sequence does not define a convex surface");
260  }
261  break;
262  }
263 
264  MinJoint_.translation() = C_;
265  MinJoint_.rotation().col(0) = N_;
266  MinJoint_.rotation().col(1) = Ns_[0];
267  MinJoint_.rotation().col(2) = Us_[0];
268  }
269  };
270 
271  struct HPP_CONSTRAINTS_DLLAPI ConvexShapeData
272  {
273  // normal in the world frame
275  // center in the world frame
277  // Current joint position
279 
281  inline void updateToCurrentTransform (const ConvexShape& cs)
282  {
283  if (cs.joint_ == NULL) {
284  oMj_.setIdentity();
285  _recompute<true> (cs);
286  } else {
287  oMj_ = cs.joint_->currentTransformation();
288  _recompute<false> (cs);
289  }
290  }
291 
295  {
296  if (cs.joint_ == NULL) {
297  oMj_.setIdentity();
298  _recompute<true> (cs);
299  } else {
300  oMj_ = cs.joint_->currentTransformation(d);
301  _recompute<false> (cs);
302  }
303  }
304 
305  template <bool WorldFrame>
306  inline void _recompute (const ConvexShape& cs)
307  {
308  if (WorldFrame) {
309  center_ = cs.C_;
310  normal_ = cs.N_;
311  } else {
312  center_ = oMj_.act (cs.C_);
313  normal_ = oMj_.rotation () * cs.N_;
314  }
315  }
316 
319  inline vector3_t intersection (const vector3_t& A, const vector3_t& u) const
320  {
321  return linePlaneIntersection (A, u, center_, normal_);
322  }
323 
327  inline bool isInside (const ConvexShape& cs,
328  const vector3_t& A, const vector3_t& u) const
329  {
330  return isInside (cs, intersection (A, u));
331  }
333  inline bool isInside (const ConvexShape& cs, const vector3_t& Ap) const
334  {
335  if (cs.joint_ == NULL) return cs.isInsideLocal (Ap);
336  vector3_t Ap_loc = oMj_.actInv(Ap);
337  return cs.isInsideLocal (Ap_loc);
338  }
339 
341  inline Transform3f alignedPositionInJoint (const ConvexShape& cs, vector3_t yaxis) const
342  {
343  assert (cs.shapeDimension_ > 2);
344  // Project vector onto the plane
345  yaxis = oMj_.actInv(yaxis);
346  vector3_t yproj = yaxis - yaxis.dot (cs.N_) * cs.N_;
347  if (yproj.isZero ()) return cs.MinJoint_;
348  else {
349  Transform3f M;
350  M.translation() = cs.C_;
351  M.rotation().col(0) = cs.N_;
352  M.rotation().col(1) = yaxis;
353  M.rotation().col(2) = cs.N_.cross (yaxis);
354  return M;
355  }
356  }
357 
361  inline value_type distance (const ConvexShape& cs, vector3_t a) const
362  {
363  if (cs.joint_!=NULL) a = oMj_.actInv(a);
364  return cs.distanceLocal (a);
365  }
366  };
367  } // namespace constraints
368 } // namespace hpp
369 
370 #endif // HPP_CONSTRAINTS_CONVEX_SHAPE_HH
JointPtr_t joint_
Definition: convex-shape.hh:173
pinocchio::vector_t vector_t
Definition: fwd.hh:45
void closestPointToSegment(const vector3_t &P, const vector3_t &A, const vector3_t &v, vector3_t &B)
Definition: convex-shape.hh:39
vector3_t intersectionLocal(const vector3_t &A, const vector3_t &u) const
Definition: convex-shape.hh:110
vector3_t C_
the center in the joint frame. It is constant.
Definition: convex-shape.hh:163
Vec3f n
ConvexShape(const std::vector< vector3_t > &pts, JointPtr_t joint=JointPtr_t())
Definition: convex-shape.hh:75
bool isInside(const ConvexShape &cs, const vector3_t &A, const vector3_t &u) const
Definition: convex-shape.hh:327
void updateToCurrentTransform(const ConvexShape &cs, const pinocchio::DeviceData &d)
Definition: convex-shape.hh:294
vector_t Ls_
Definition: convex-shape.hh:171
bool isInside(const ConvexShape &cs, const vector3_t &Ap) const
Check whether the point As in world frame is inside the triangle.
Definition: convex-shape.hh:333
const Transform3f & positionInJoint() const
Transform of the shape in the joint frame.
Definition: convex-shape.hh:157
ConvexShape(const ConvexShape &t)
Definition: convex-shape.hh:97
vector3_t linePlaneIntersection(const vector3_t &A, const vector3_t &u, const vector3_t &P, const vector3_t &n)
Definition: convex-shape.hh:55
const vector3_t & planeXaxis() const
Return the X axis of the plane in the joint frame.
Definition: convex-shape.hh:145
Definition: convex-shape.hh:271
vector3_t center_
Definition: convex-shape.hh:276
Transform3f MinJoint_
Definition: convex-shape.hh:172
pinocchio::vector3_t vector3_t
Definition: fwd.hh:39
vector3_t intersection(const vector3_t &A, const vector3_t &u) const
Definition: convex-shape.hh:319
void reverse()
Definition: convex-shape.hh:103
vector3_t N_
the normal to the shape in the joint frame. It is constant.
Definition: convex-shape.hh:165
assert(d.lhs()._blocks()==d.rhs()._blocks())
pinocchio::JointPtr_t JointPtr_t
Definition: fwd.hh:37
std::vector< vector3_t > Pts_
The points in the joint frame. It is constant.
Definition: convex-shape.hh:160
value_type distanceLocal(const vector3_t &a) const
Definition: convex-shape.hh:127
ConvexShape(const fcl::TriangleP &t, const JointPtr_t &joint=JointPtr_t())
Definition: convex-shape.hh:81
Transform3f oMj_
Definition: convex-shape.hh:278
Vec3f a
FCL_REAL d
FCL_REAL dist(short i) const
void _recompute(const ConvexShape &cs)
Definition: convex-shape.hh:306
void updateToCurrentTransform(const ConvexShape &cs)
Compute center and normal in world frame.
Definition: convex-shape.hh:281
Transform3f t
Definition: convex-shape.hh:64
pinocchio::value_type value_type
Definition: fwd.hh:36
Transform3f alignedPositionInJoint(const ConvexShape &cs, vector3_t yaxis) const
Definition: convex-shape.hh:341
bool isInsideLocal(const vector3_t &Ap) const
As isInside but consider A as expressed in joint frame.
Definition: convex-shape.hh:115
value_type distance(const ConvexShape &cs, vector3_t a) const
Definition: convex-shape.hh:361
std::vector< vector3_t > Us_
Definition: convex-shape.hh:170
ConvexShape(const vector3_t &p0, const vector3_t &p1, const vector3_t &p2, const JointPtr_t &joint=JointPtr_t())
Definition: convex-shape.hh:89
const vector3_t & planeYaxis() const
Definition: convex-shape.hh:151
vector3_t normal_
Definition: convex-shape.hh:274
pinocchio::Transform3f Transform3f
Definition: fwd.hh:50
size_t shapeDimension_
Definition: convex-shape.hh:161
Vec3f * points