hpp-constraints 6.0.0
Definition of basic geometric constraints for motion planning
Loading...
Searching...
No Matches
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
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9// 1. Redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer.
11//
12// 2. Redistributions in binary form must reproduce the above copyright
13// notice, this list of conditions and the following disclaimer in the
14// documentation and/or other materials provided with the distribution.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
27// DAMAGE.
28
29#ifndef HPP_CONSTRAINTS_CONVEX_SHAPE_HH
30#define HPP_CONSTRAINTS_CONVEX_SHAPE_HH
31
32#include <coal/shape/geometric_shapes.h>
33
34#include <vector>
35
36// Only for specialization of vector3_t. This is a bad design of Pinocchio.
39#include <hpp/pinocchio/joint.hh>
40#include <pinocchio/multibody/model.hpp>
41
42namespace hpp {
43namespace constraints {
48inline void closestPointToSegment(const vector3_t& P, const vector3_t& A,
49 const vector3_t& v, vector3_t& B) {
50 vector3_t w = A - P;
51 value_type c1, c2;
52 c1 = v.dot(w);
53 c2 = v.dot(v);
54 if (c1 <= 0)
55 B = A;
56 else if (c2 <= c1)
57 B = A + v;
58 else
59 B = A + c1 / c2 * v;
60}
61
68 const vector3_t& P, const vector3_t& n) {
69 assert(std::abs(n.dot(u)) > 1e-8);
70 return A + u * (n.dot(P - A)) / n.dot(u);
71}
72
74 public:
83 ConvexShape(const std::vector<vector3_t>& pts,
84 JointPtr_t joint = JointPtr_t())
85 : Pts_(pts), joint_(joint) {
86 init();
87 }
88
89 ConvexShape(const coal::TriangleP& t, const JointPtr_t& joint = JointPtr_t())
90 : Pts_(triangleToPoints(t)), joint_(joint) {
91 init();
92 }
93
96 ConvexShape(const vector3_t& p0, const vector3_t& p1, const vector3_t& p2,
97 const JointPtr_t& joint = JointPtr_t())
98 : Pts_(points(p0, p1, p2)), joint_(joint) {
99 init();
100 }
101
102 // Copy constructor
103 ConvexShape(const ConvexShape& t) : Pts_(t.Pts_), joint_(t.joint_) { init(); }
104
105 void reverse() {
106 std::reverse(Pts_.begin(), Pts_.end());
107 init();
108 }
109
113 const vector3_t& u) const {
114 return linePlaneIntersection(A, u, C_, N_);
115 }
116
118 inline bool isInsideLocal(const vector3_t& Ap) const {
119 assert(shapeDimension_ > 2);
120 for (std::size_t i = 0; i < shapeDimension_; ++i) {
121 if (Ns_[i].dot(Ap - Pts_[i]) > 0) return false;
122 }
123 return true;
124 }
125
130 inline value_type distanceLocal(const vector3_t& a) const {
131 assert(shapeDimension_ > 1);
132 const value_type inf = std::numeric_limits<value_type>::infinity();
133 value_type minPosDist = inf, maxNegDist = -inf;
134 bool outside = false;
135 for (std::size_t i = 0; i < shapeDimension_; ++i) {
136 value_type d = dist(a - Pts_[i], Ls_[i], Us_[i], Ns_[i]);
137 if (d > 0) {
138 outside = true;
139 if (d < minPosDist) minPosDist = d;
140 }
141 if (d <= 0 && d > maxNegDist) maxNegDist = d;
142 }
143 if (outside) return minPosDist;
144 return maxNegDist;
145 }
146
148 inline const vector3_t& planeXaxis() const {
149 assert(shapeDimension_ > 2);
150 return Ns_[0];
151 }
154 inline const vector3_t& planeYaxis() const {
155 assert(shapeDimension_ > 2);
156 return Us_[0];
157 }
158
160 inline const Transform3s& positionInJoint() const { return MinJoint_; }
161
162 bool operator==(ConvexShape const& other) const {
163 if (Pts_ != other.Pts_) return false;
164 if (shapeDimension_ != other.shapeDimension_) return false;
165 if (C_ != other.C_) return false;
166 if (N_ != other.N_) return false;
167 if (Ns_ != other.Ns_) return false;
168 if (Us_ != other.Us_) return false;
169 if (Ls_ != other.Ls_) return false;
170 if (MinJoint_ != other.MinJoint_) return false;
171 if (joint_ != other.joint_) return false;
172 return true;
173 }
174 bool operator!=(ConvexShape const& other) const {
175 return !(this->operator==(other));
176 }
177
179 std::vector<vector3_t> Pts_;
189 std::vector<vector3_t> Ns_, Us_;
193
194 private:
198 inline value_type dist(const vector3_t& w, const value_type& c2,
199 const vector3_t& v, const vector3_t& u) const {
200 value_type c1;
201 c1 = v.dot(w);
202 if (c1 <= 0) return (u.dot(w) > 0) ? (w.norm()) : (-w.norm());
203 if (c2 <= c1)
204 // TODO: (w - c2 * v).norm() == sqrt((u.dot(w)**2 + (c1 - c2)**2)
205 // second should be cheaper.
206 return (u.dot(w) > 0) ? ((w - c2 * v).norm()) : (-(w - c2 * v).norm());
207 return u.dot(w);
208 }
209
210 static std::vector<vector3_t> triangleToPoints(const coal::TriangleP& t) {
211 // TODO
212 // return points (t.a, t.b, t.c);
213 std::vector<vector3_t> ret(3);
214 ret[0] = t.a;
215 ret[1] = t.b;
216 ret[2] = t.c;
217 return ret;
218 }
219 static std::vector<vector3_t> points(const vector3_t& p0, const vector3_t& p1,
220 const vector3_t& p2) {
221 std::vector<vector3_t> ret(3);
222 ret[0] = p0;
223 ret[1] = p1;
224 ret[2] = p2;
225 return ret;
226 }
227
228 void init() {
229 shapeDimension_ = Pts_.size();
230
231 switch (shapeDimension_) {
232 case 0:
233 throw std::logic_error("Cannot represent an empty shape.");
234 break;
235 case 1:
236 C_ = Pts_[0];
237 // The transformation will be (N_, Ns_[0], Us_[0])
238 // Fill vectors so as to be consistent
239 N_ = vector3_t(1, 0, 0);
240 Ns_.push_back(vector3_t(0, 1, 0));
241 Us_.push_back(vector3_t(0, 0, 1));
242 break;
243 case 2:
244 Ls_ = vector_t(1);
245 C_ = (Pts_[0] + Pts_[1]) / 2;
246 // The transformation will be (N_, Ns_[0], Us_[0])
247 // Fill vectors so as to be consistent
248 Us_.push_back(Pts_[1] - Pts_[0]);
249 Ls_[0] = Us_[0].norm();
250 Us_[0].normalize();
251 if (Us_[0][0] != 0)
252 N_ = vector3_t(-Us_[0][1], Us_[0][0], 0);
253 else
254 N_ = vector3_t(0, -Us_[0][2], Us_[0][1]);
255 N_.normalize();
256 Ns_.push_back(Us_[0].cross(N_));
257 Ns_[0].normalize(); // Should be unnecessary
258 break;
259 default:
260 Ls_ = vector_t(shapeDimension_);
261 C_.setZero();
262 for (std::size_t i = 0; i < shapeDimension_; ++i) C_ += Pts_[i];
263 // TODO This is very ugly. Why Eigen does not have the operator/=(int)
264 // ...
265 C_ /= (value_type)Pts_.size();
266 N_ = (Pts_[1] - Pts_[0]).cross(Pts_[2] - Pts_[1]);
267 assert(!N_.isZero());
268 N_.normalize();
269
270 Us_.resize(Pts_.size());
271 Ns_.resize(Pts_.size());
272 for (std::size_t i = 0; i < shapeDimension_; ++i) {
273 Us_[i] = Pts_[(i + 1) % shapeDimension_] - Pts_[i];
274 Ls_[i] = Us_[i].norm();
275 Us_[i].normalize();
276 Ns_[i] = Us_[i].cross(N_);
277 Ns_[i].normalize();
278 }
279 for (std::size_t i = 0; i < shapeDimension_; ++i) {
280 assert(Us_[(i + 1) % shapeDimension_].dot(Ns_[i]) < 0 &&
281 "The sequence does not define a convex surface");
282 }
283 break;
284 }
285
286 MinJoint_.translation() = C_;
287 MinJoint_.rotation().col(0) = N_;
288 MinJoint_.rotation().col(1) = Ns_[0];
289 MinJoint_.rotation().col(2) = Us_[0];
290 }
291};
292
294 // normal in the world frame
296 // center in the world frame
298 // Current joint position
300
302 inline void updateToCurrentTransform(const ConvexShape& cs) {
303 if (cs.joint_ == NULL) {
304 oMj_.setIdentity();
305 _recompute<true>(cs);
306 } else {
307 oMj_ = cs.joint_->currentTransformation();
308 _recompute<false>(cs);
309 }
310 }
311
315 const pinocchio::DeviceData& d) {
316 if (cs.joint_ == NULL) {
317 oMj_.setIdentity();
318 _recompute<true>(cs);
319 } else {
320 oMj_ = cs.joint_->currentTransformation(d);
321 _recompute<false>(cs);
322 }
323 }
324
325 template <bool WorldFrame>
326 inline void _recompute(const ConvexShape& cs) {
327 if (WorldFrame) {
328 center_ = cs.C_;
329 normal_ = cs.N_;
330 } else {
331 center_ = oMj_.act(cs.C_);
332 normal_ = oMj_.rotation() * cs.N_;
333 }
334 }
335
338 inline vector3_t intersection(const vector3_t& A, const vector3_t& u) const {
339 return linePlaneIntersection(A, u, center_, normal_);
340 }
341
346 inline bool isInside(const ConvexShape& cs, const vector3_t& A,
347 const vector3_t& u) const {
348 return isInside(cs, intersection(A, u));
349 }
351 inline bool isInside(const ConvexShape& cs, const vector3_t& Ap) const {
352 if (cs.joint_ == NULL) return cs.isInsideLocal(Ap);
353 vector3_t Ap_loc = oMj_.actInv(Ap);
354 return cs.isInsideLocal(Ap_loc);
355 }
356
359 vector3_t yaxis) const {
360 assert(cs.shapeDimension_ > 2);
361 // Project vector onto the plane
362 yaxis = oMj_.actInv(yaxis);
363 vector3_t yproj = yaxis - yaxis.dot(cs.N_) * cs.N_;
364 if (yproj.isZero())
365 return cs.MinJoint_;
366 else {
367 Transform3s M;
368 M.translation() = cs.C_;
369 M.rotation().col(0) = cs.N_;
370 M.rotation().col(1) = yaxis;
371 M.rotation().col(2) = cs.N_.cross(yaxis);
372 return M;
373 }
374 }
375
379 inline value_type distance(const ConvexShape& cs, vector3_t a) const {
380 if (cs.joint_ != NULL) a = oMj_.actInv(a);
381 return cs.distanceLocal(a);
382 }
383};
384} // namespace constraints
385} // namespace hpp
386
387#endif // HPP_CONSTRAINTS_CONVEX_SHAPE_HH
Definition convex-shape.hh:73
ConvexShape(const std::vector< vector3_t > &pts, JointPtr_t joint=JointPtr_t())
Definition convex-shape.hh:83
Transform3s MinJoint_
Definition convex-shape.hh:191
ConvexShape(const vector3_t &p0, const vector3_t &p1, const vector3_t &p2, const JointPtr_t &joint=JointPtr_t())
Definition convex-shape.hh:96
const vector3_t & planeYaxis() const
Definition convex-shape.hh:154
bool operator!=(ConvexShape const &other) const
Definition convex-shape.hh:174
vector3_t C_
the center in the joint frame. It is constant.
Definition convex-shape.hh:182
std::vector< vector3_t > Us_
Definition convex-shape.hh:189
std::vector< vector3_t > Pts_
The points in the joint frame. It is constant.
Definition convex-shape.hh:179
bool operator==(ConvexShape const &other) const
Definition convex-shape.hh:162
ConvexShape(const ConvexShape &t)
Definition convex-shape.hh:103
bool isInsideLocal(const vector3_t &Ap) const
As isInside but consider A as expressed in joint frame.
Definition convex-shape.hh:118
void reverse()
Definition convex-shape.hh:105
vector3_t N_
the normal to the shape in the joint frame. It is constant.
Definition convex-shape.hh:184
value_type distanceLocal(const vector3_t &a) const
Definition convex-shape.hh:130
vector_t Ls_
Definition convex-shape.hh:190
std::vector< vector3_t > Ns_
Definition convex-shape.hh:189
ConvexShape(const coal::TriangleP &t, const JointPtr_t &joint=JointPtr_t())
Definition convex-shape.hh:89
vector3_t intersectionLocal(const vector3_t &A, const vector3_t &u) const
Definition convex-shape.hh:112
const Transform3s & positionInJoint() const
Transform of the shape in the joint frame.
Definition convex-shape.hh:160
const vector3_t & planeXaxis() const
Return the X axis of the plane in the joint frame.
Definition convex-shape.hh:148
JointPtr_t joint_
Definition convex-shape.hh:192
size_t shapeDimension_
Definition convex-shape.hh:180
#define HPP_CONSTRAINTS_DLLAPI
Definition config.hh:88
assert(d.lhs()._blocks()==d.rhs()._blocks())
pinocchio::vector3_t vector3_t
Definition fwd.hh:52
void closestPointToSegment(const vector3_t &P, const vector3_t &A, const vector3_t &v, vector3_t &B)
Definition convex-shape.hh:48
pinocchio::Transform3s Transform3s
Definition fwd.hh:64
pinocchio::value_type value_type
Definition fwd.hh:48
bool operator==(const ComparisonTypes_t &v, const internal::ReplicateCompType &r)
Definition comparison-types.hh:117
pinocchio::vector_t vector_t
Definition fwd.hh:59
vector3_t linePlaneIntersection(const vector3_t &A, const vector3_t &u, const vector3_t &P, const vector3_t &n)
Definition convex-shape.hh:67
pinocchio::JointPtr_t JointPtr_t
Definition fwd.hh:49
Definition active-set-differentiable-function.hh:36
Definition convex-shape.hh:293
Transform3s alignedPositionInJoint(const ConvexShape &cs, vector3_t yaxis) const
Definition convex-shape.hh:358
vector3_t normal_
Definition convex-shape.hh:295
void updateToCurrentTransform(const ConvexShape &cs, const pinocchio::DeviceData &d)
Definition convex-shape.hh:314
Transform3s oMj_
Definition convex-shape.hh:299
void _recompute(const ConvexShape &cs)
Definition convex-shape.hh:326
bool isInside(const ConvexShape &cs, const vector3_t &A, const vector3_t &u) const
Definition convex-shape.hh:346
vector3_t intersection(const vector3_t &A, const vector3_t &u) const
Definition convex-shape.hh:338
void updateToCurrentTransform(const ConvexShape &cs)
Compute center and normal in world frame.
Definition convex-shape.hh:302
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:351
value_type distance(const ConvexShape &cs, vector3_t a) const
Definition convex-shape.hh:379
vector3_t center_
Definition convex-shape.hh:297