hpp-constraints  4.9.1
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 // 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_TOOL_HH
18 #define HPP_CONSTRAINTS_TOOL_HH
19 
20 #include <boost/math/constants/constants.hpp>
21 
22 #include <pinocchio/spatial/se3.hpp>
23 
24 #include <hpp/constraints/fwd.hh>
25 
26 namespace hpp {
27  namespace constraints {
28 
29  template < typename VectorType, typename MatrixType >
30  static void computeCrossMatrix (const VectorType& v, MatrixType& m)
31  {
32  m.diagonal ().setZero ();
33  m (0,1) = -v [2]; m (1,0) = v [2];
34  m (0,2) = v [1]; m (2,0) = -v [1];
35  m (1,2) = -v [0]; m (2,1) = v [0];
36  }
37 
40 
47  template <typename Derived> inline void logSO3
48  (const matrix3_t& R, value_type& theta,
49  Eigen::MatrixBase<Derived> const& result)
50  {
51  Eigen::MatrixBase<Derived>& value = const_cast<Eigen::MatrixBase<Derived>&> (result);
52  const value_type PI = ::boost::math::constants::pi<value_type>();
53  const value_type tr = R.trace();
54  if (tr > 3) theta = 0; // acos((3-1)/2)
55  else if (tr < -1) theta = PI; // acos((-1-1)/2)
56  else theta = acos ((tr - 1)/2);
57  assert (theta == theta);
58  // From runs of tests/logarithm.cc: 1e-6 is too small.
59  if (theta < PI - 1e-2) {
60  const value_type t = ((theta > 1e-6)? theta / sin(theta) : 1) / 2;
61  value(0) = t * (R (2, 1) - R (1, 2));
62  value(1) = t * (R (0, 2) - R (2, 0));
63  value(2) = t * (R (1, 0) - R (0, 1));
64  } else {
65  // 1e-2: A low value is not required since the computation is
66  // using explicit formula. However, the precision of this method
67  // is the square root of the precision with the antisymmetric
68  // method (Nominal case).
69  const value_type cphi = cos(theta - PI);
70  const value_type beta = theta*theta / ( 1 + cphi );
71  const value_type tmp0 = (R (0, 0) + cphi) * beta;
72  const value_type tmp1 = (R (1, 1) + cphi) * beta;
73  const value_type tmp2 = (R (2, 2) + cphi) * beta;
74  value(0) = (R (2, 1) > R (1, 2) ? 1 : -1) * (tmp0 > 0 ? sqrt(tmp0) : 0);
75  value(1) = (R (0, 2) > R (2, 0) ? 1 : -1) * (tmp1 > 0 ? sqrt(tmp1) : 0);
76  value(2) = (R (1, 0) > R (0, 1) ? 1 : -1) * (tmp2 > 0 ? sqrt(tmp2) : 0);
77  }
78  }
79 
80 
108  template <typename Derived>
109  void JlogSO3 (const value_type& theta,
110  const Eigen::MatrixBase<Derived>& log, matrix3_t& Jlog)
111  {
112  if (theta < 1e-6)
113  Jlog.setIdentity();
114  else {
115  // Jlog = alpha I
116  const value_type ct = cos(theta), st = sin(theta);
117  const value_type st_1mct = st/(1-ct);
118 
119  Jlog.setZero ();
120  Jlog.diagonal().setConstant (theta*st_1mct);
121 
122  // Jlog += r_{\times}/2
123  Jlog(0,1) = -log(2); Jlog(1,0) = log(2);
124  Jlog(0,2) = log(1); Jlog(2,0) = -log(1);
125  Jlog(1,2) = -log(0); Jlog(2,1) = log(0);
126  Jlog /= 2;
127 
128  const value_type alpha = 1/(theta*theta) - st_1mct/(2*theta);
129  Jlog.noalias() += alpha * log * log.transpose ();
130  }
131  }
132 
141  template <typename Derived> inline void logSE3
142  (const Transform3f& M, Eigen::MatrixBase<Derived>& result)
143  {
144  assert (result.size () == 6);
145  Eigen::MatrixBase<Derived>& value =
146  const_cast<Eigen::MatrixBase<Derived>&> (result);
147  const matrix3_t & R = M.rotation();
148  const vector3_t & p = M.translation();
149  value_type theta;
150  vector3_t r;
151  logSO3 (R, theta, r);
152  value.segment (3, 3) = r;
153  value_type alpha, beta;
154  if (fabs (theta) < 1e-2) {
155  alpha = 1 - theta*theta/12 - theta*theta*theta*theta/720;
156  beta = 1./12 + theta*theta/720;
157  } else {
158  alpha = theta*sin(theta)/(2*(1-cos(theta)));
159  beta = 1/(theta*theta) - sin (theta)/(2*theta*(1-cos(theta)));
160  }
161  matrix3_t rcross; computeCrossMatrix (r, rcross);
162  value.segment (0, 3) = alpha*p - .5*rcross*p + beta*r.dot (p)*r;
163  }
164 
165  template <typename Derived>
166  void JlogSE3 (const Transform3f& M,
167  Eigen::MatrixBase<Derived> const& Jlog)
168  {
169  Eigen::MatrixBase<Derived>& value =
170  const_cast<Eigen::MatrixBase<Derived>&> (Jlog);
171  const matrix3_t & R = M.rotation();
172  const vector3_t & p = M.translation();
173  value_type theta;
174  vector3_t r;
175  logSO3 (R, theta, r);
176  matrix3_t Jlog3; JlogSO3 (theta, r, Jlog3);
177  value_type alpha, beta, beta_dot_over_theta;
178  if (fabs (theta) < 1e-2) {
179  alpha = 1 - theta*theta/12 - theta*theta*theta*theta/720;
180  beta = 1./12 + theta*theta/720;
181  beta_dot_over_theta = 1. / 360.;
182  } else {
183  alpha = theta*sin(theta)/(2*(1-cos(theta)));
184  beta = 1/(theta*theta) - sin (theta)/(2*theta*(1-cos(theta)));
185  beta_dot_over_theta = -2/(theta*theta*theta*theta) +
186  (theta + sin (theta)) / (2*theta*theta*theta*(1-cos(theta)));
187  }
188  matrix3_t rcross; computeCrossMatrix (r, rcross);
189  matrix3_t V (alpha * matrix3_t::Identity () - .5*rcross +
190  beta * r * r.transpose ());
191  value_type rTp (r.dot (p));
192  matrix3_t pcross; computeCrossMatrix (p, pcross);
193  matrix3_t J ((.5*pcross + (beta_dot_over_theta*rTp)*r*r.transpose ()
194  - (theta*theta*beta_dot_over_theta+2*beta)*p*r.transpose ()
195  + rTp * beta * matrix3_t::Identity ()
196  + beta * r*p.transpose ()) * Jlog3);
197  value.block (0, 0, 3, 3) = V * R;
198  value.block (0, 3, 3, 3) = J;
199  Eigen::Block<Derived> b (value.block (3, 0, 3, 3));
200  b.setZero ();
201  value.block (3, 3, 3, 3) = Jlog3;
202  }
203 
204  template <typename Derived1, typename Derived2> void matrixToQuat
205  (const Eigen::MatrixBase<Derived1>& M, Eigen::MatrixBase<Derived2> const& q)
206  {
207  Derived2& _q = const_cast<Derived2&> (q.derived());
208  assert (q.size() == 4);
209  Eigen::Map<Transform3f::Quaternion> quat (_q.data());
210  quat = M;
211  }
212 
213  template <typename Derived> void se3ToConfig
214  (const Transform3f& M, Eigen::MatrixBase<Derived> const& q)
215  {
216  Derived& _q = const_cast<Derived&> (q.derived());
217  assert (q.size() == 7);
218  _q.template head<3>() = M.translation();
219  matrixToQuat (M.rotation(), _q.template tail<4>());
220  }
221 
223  } // namespace constraints
224 } // namespace hpp
225 
226 #endif // HPP_CONSTRAINTS_TOOL_HH
Vec3f b
FCL_REAL r
pinocchio::matrix3_t matrix3_t
Definition: fwd.hh:40
void JlogSO3(const value_type &theta, const Eigen::MatrixBase< Derived > &log, matrix3_t &Jlog)
Definition: tools.hh:109
pinocchio::vector3_t vector3_t
Definition: fwd.hh:39
void matrixToQuat(const Eigen::MatrixBase< Derived1 > &M, Eigen::MatrixBase< Derived2 > const &q)
Definition: tools.hh:205
assert(d.lhs()._blocks()==d.rhs()._blocks())
void se3ToConfig(const Transform3f &M, Eigen::MatrixBase< Derived > const &q)
Definition: tools.hh:214
void JlogSE3(const Transform3f &M, Eigen::MatrixBase< Derived > const &Jlog)
Definition: tools.hh:166
void logSO3(const matrix3_t &R, value_type &theta, Eigen::MatrixBase< Derived > const &result)
Definition: tools.hh:48
Transform3f t
pinocchio::value_type value_type
Definition: fwd.hh:36
void logSE3(const Transform3f &M, Eigen::MatrixBase< Derived > &result)
Definition: tools.hh:142
pinocchio::Transform3f Transform3f
Definition: fwd.hh:50