hpp-constraints  6.0.0
Definition of basic geometric constraints for motion planning
tools.hh
Go to the documentation of this file.
1 // Copyright (c) 2014, 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_TOOL_HH
30 #define HPP_CONSTRAINTS_TOOL_HH
31 
32 #include <boost/math/constants/constants.hpp>
33 #include <hpp/constraints/fwd.hh>
34 #include <pinocchio/spatial/se3.hpp>
35 
36 namespace hpp {
37 namespace constraints {
38 
39 template <typename VectorType, typename MatrixType>
40 static void computeCrossMatrix(const VectorType& v, MatrixType& m) {
41  m.diagonal().setZero();
42  m(0, 1) = -v[2];
43  m(1, 0) = v[2];
44  m(0, 2) = v[1];
45  m(2, 0) = -v[1];
46  m(1, 2) = -v[0];
47  m(2, 1) = v[0];
48 }
49 
52 
59 template <typename Derived>
60 inline void logSO3(const matrix3_t& R, value_type& theta,
61  Eigen::MatrixBase<Derived> const& result) {
62  Eigen::MatrixBase<Derived>& value =
63  const_cast<Eigen::MatrixBase<Derived>&>(result);
64  const value_type PI = ::boost::math::constants::pi<value_type>();
65  const value_type tr = R.trace();
66  if (tr > 3)
67  theta = 0; // acos((3-1)/2)
68  else if (tr < -1)
69  theta = PI; // acos((-1-1)/2)
70  else
71  theta = acos((tr - 1) / 2);
72  assert(theta == theta);
73  // From runs of tests/logarithm.cc: 1e-6 is too small.
74  if (theta < PI - 1e-2) {
75  const value_type t = ((theta > 1e-6) ? theta / sin(theta) : 1) / 2;
76  value(0) = t * (R(2, 1) - R(1, 2));
77  value(1) = t * (R(0, 2) - R(2, 0));
78  value(2) = t * (R(1, 0) - R(0, 1));
79  } else {
80  // 1e-2: A low value is not required since the computation is
81  // using explicit formula. However, the precision of this method
82  // is the square root of the precision with the antisymmetric
83  // method (Nominal case).
84  const value_type cphi = cos(theta - PI);
85  const value_type beta = theta * theta / (1 + cphi);
86  const value_type tmp0 = (R(0, 0) + cphi) * beta;
87  const value_type tmp1 = (R(1, 1) + cphi) * beta;
88  const value_type tmp2 = (R(2, 2) + cphi) * beta;
89  value(0) = (R(2, 1) > R(1, 2) ? 1 : -1) * (tmp0 > 0 ? sqrt(tmp0) : 0);
90  value(1) = (R(0, 2) > R(2, 0) ? 1 : -1) * (tmp1 > 0 ? sqrt(tmp1) : 0);
91  value(2) = (R(1, 0) > R(0, 1) ? 1 : -1) * (tmp2 > 0 ? sqrt(tmp2) : 0);
92  }
93 }
94 
128 template <typename Derived>
129 void JlogSO3(const value_type& theta, const Eigen::MatrixBase<Derived>& log,
130  matrix3_t& Jlog) {
131  if (theta < 1e-6)
132  Jlog.setIdentity();
133  else {
134  // Jlog = alpha I
135  const value_type ct = cos(theta), st = sin(theta);
136  const value_type st_1mct = st / (1 - ct);
137 
138  Jlog.setZero();
139  Jlog.diagonal().setConstant(theta * st_1mct);
140 
141  // Jlog += r_{\times}/2
142  Jlog(0, 1) = -log(2);
143  Jlog(1, 0) = log(2);
144  Jlog(0, 2) = log(1);
145  Jlog(2, 0) = -log(1);
146  Jlog(1, 2) = -log(0);
147  Jlog(2, 1) = log(0);
148  Jlog /= 2;
149 
150  const value_type alpha = 1 / (theta * theta) - st_1mct / (2 * theta);
151  Jlog.noalias() += alpha * log * log.transpose();
152  }
153 }
154 
163 template <typename Derived>
164 inline void logSE3(const Transform3s& M, Eigen::MatrixBase<Derived>& result) {
165  assert(result.size() == 6);
166  Eigen::MatrixBase<Derived>& value =
167  const_cast<Eigen::MatrixBase<Derived>&>(result);
168  const matrix3_t& R = M.rotation();
169  const vector3_t& p = M.translation();
170  value_type theta;
171  vector3_t r;
172  logSO3(R, theta, r);
173  value.segment(3, 3) = r;
174  value_type alpha, beta;
175  if (fabs(theta) < 1e-2) {
176  alpha = 1 - theta * theta / 12 - theta * theta * theta * theta / 720;
177  beta = 1. / 12 + theta * theta / 720;
178  } else {
179  alpha = theta * sin(theta) / (2 * (1 - cos(theta)));
180  beta = 1 / (theta * theta) - sin(theta) / (2 * theta * (1 - cos(theta)));
181  }
182  matrix3_t rcross;
183  computeCrossMatrix(r, rcross);
184  value.segment(0, 3) = alpha * p - .5 * rcross * p + beta * r.dot(p) * r;
185 }
186 
187 template <typename Derived>
188 void JlogSE3(const Transform3s& M, Eigen::MatrixBase<Derived> const& Jlog) {
189  Eigen::MatrixBase<Derived>& value =
190  const_cast<Eigen::MatrixBase<Derived>&>(Jlog);
191  const matrix3_t& R = M.rotation();
192  const vector3_t& p = M.translation();
193  value_type theta;
194  vector3_t r;
195  r.setZero();
196  logSO3(R, theta, r);
197  matrix3_t Jlog3;
198  JlogSO3(theta, r, Jlog3);
199  value_type alpha, beta, beta_dot_over_theta;
200  if (fabs(theta) < 1e-2) {
201  alpha = 1 - theta * theta / 12 - theta * theta * theta * theta / 720;
202  beta = 1. / 12 + theta * theta / 720;
203  beta_dot_over_theta = 1. / 360.;
204  } else {
205  alpha = theta * sin(theta) / (2 * (1 - cos(theta)));
206  beta = 1 / (theta * theta) - sin(theta) / (2 * theta * (1 - cos(theta)));
207  beta_dot_over_theta =
208  -2 / (theta * theta * theta * theta) +
209  (theta + sin(theta)) / (2 * theta * theta * theta * (1 - cos(theta)));
210  }
211  matrix3_t rcross;
212  computeCrossMatrix(r, rcross);
213  matrix3_t V(alpha * matrix3_t::Identity() - .5 * rcross +
214  beta * r * r.transpose());
215  value_type rTp(r.dot(p));
216  matrix3_t pcross;
217  computeCrossMatrix(p, pcross);
218  matrix3_t J(
219  (.5 * pcross + (beta_dot_over_theta * rTp) * r * r.transpose() -
220  (theta * theta * beta_dot_over_theta + 2 * beta) * p * r.transpose() +
221  rTp * beta * matrix3_t::Identity() + beta * r * p.transpose()) *
222  Jlog3);
223  value.block(0, 0, 3, 3) = V * R;
224  value.block(0, 3, 3, 3) = J;
225  Eigen::Block<Derived> b(value.block(3, 0, 3, 3));
226  b.setZero();
227  value.block(3, 3, 3, 3) = Jlog3;
228 }
229 
230 template <typename Derived1, typename Derived2>
231 void matrixToQuat(const Eigen::MatrixBase<Derived1>& M,
232  Eigen::MatrixBase<Derived2> const& q) {
233  Derived2& _q = const_cast<Derived2&>(q.derived());
234  assert(q.size() == 4);
235  Eigen::Map<Transform3s::Quaternion> quat(_q.data());
236  quat = M;
237 }
238 
239 template <typename Derived>
240 void se3ToConfig(const Transform3s& M, Eigen::MatrixBase<Derived> const& q) {
241  Derived& _q = const_cast<Derived&>(q.derived());
242  assert(q.size() == 7);
243  _q.template head<3>() = M.translation();
244  matrixToQuat(M.rotation(), _q.template tail<4>());
245 }
246 
248 } // namespace constraints
249 } // namespace hpp
250 
251 #endif // HPP_CONSTRAINTS_TOOL_HH
void matrixToQuat(const Eigen::MatrixBase< Derived1 > &M, Eigen::MatrixBase< Derived2 > const &q)
Definition: tools.hh:231
void logSO3(const matrix3_t &R, value_type &theta, Eigen::MatrixBase< Derived > const &result)
Definition: tools.hh:60
void JlogSE3(const Transform3s &M, Eigen::MatrixBase< Derived > const &Jlog)
Definition: tools.hh:188
void JlogSO3(const value_type &theta, const Eigen::MatrixBase< Derived > &log, matrix3_t &Jlog)
Definition: tools.hh:129
void se3ToConfig(const Transform3s &M, Eigen::MatrixBase< Derived > const &q)
Definition: tools.hh:240
void logSE3(const Transform3s &M, Eigen::MatrixBase< Derived > &result)
Definition: tools.hh:164
assert(d.lhs()._blocks()==d.rhs()._blocks())
pinocchio::matrix3_t matrix3_t
Definition: fwd.hh:53
pinocchio::vector3_t vector3_t
Definition: fwd.hh:52
pinocchio::Transform3s Transform3s
Definition: fwd.hh:64
pinocchio::value_type value_type
Definition: fwd.hh:48
Definition: active-set-differentiable-function.hh:36