special-orthogonal.hpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2016-2020 CNRS INRIA
3 //
4 
5 #ifndef __pinocchio_multibody_liegroup_special_orthogonal_operation_hpp__
6 #define __pinocchio_multibody_liegroup_special_orthogonal_operation_hpp__
7 
8 #include <limits>
9 
10 #include "pinocchio/spatial/explog.hpp"
11 #include "pinocchio/math/quaternion.hpp"
12 #include "pinocchio/multibody/liegroup/liegroup-base.hpp"
13 #include "pinocchio/utils/static-if.hpp"
14 
15 namespace pinocchio
16 {
17  template<int Dim, typename Scalar, int Options = 0>
19  {};
20 
21  template<int Dim, typename Scalar, int Options>
23  {};
24 
25  template<typename _Scalar, int _Options>
26  struct traits< SpecialOrthogonalOperationTpl<2,_Scalar,_Options> >
27  {
28  typedef _Scalar Scalar;
29  enum
30  {
31  Options = _Options,
32  NQ = 2,
33  NV = 1
34  };
35  };
36 
37  template<typename _Scalar, int _Options >
38  struct traits<SpecialOrthogonalOperationTpl<3,_Scalar,_Options> > {
39  typedef _Scalar Scalar;
40  enum
41  {
42  Options = _Options,
43  NQ = 4,
44  NV = 3
45  };
46  };
47 
48  template<typename _Scalar, int _Options>
49  struct SpecialOrthogonalOperationTpl<2,_Scalar,_Options>
50  : public LieGroupBase< SpecialOrthogonalOperationTpl<2,_Scalar,_Options> >
51  {
53  typedef Eigen::Matrix<Scalar,2,2> Matrix2;
54  typedef typename Eigen::NumTraits<Scalar>::Real RealScalar;
55 
56  template<typename Matrix2Like>
57  static typename Matrix2Like::Scalar
58  log(const Eigen::MatrixBase<Matrix2Like> & R)
59  {
60  typedef typename Matrix2Like::Scalar Scalar;
61  EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Matrix2Like,2,2);
62 
63  const Scalar tr = R.trace();
64 
65  static const Scalar PI_value = PI<Scalar>();
66 
68  Scalar theta =
70  Scalar(0), // then
72  if_then_else(internal::GE, R (1, 0), Scalar(0),
73  PI_value, -PI_value), // then
74  if_then_else(internal::GT, tr, Scalar(2) - 1e-2,
75  asin((R(1,0) - R(0,1)) / Scalar(2)), // then
76  if_then_else(internal::GE, R (1, 0), Scalar(0),
77  acos(tr/Scalar(2)), // then
78  -acos(tr/Scalar(2))
79  )
80  )
81  )
82  );
83 
84 
85 // const bool pos = (R (1, 0) > Scalar(0));
86 // if (tr > Scalar(2)) theta = Scalar(0); // acos((3-1)/2)
87 // else if (tr < Scalar(-2)) theta = (pos ? PI_value : -PI_value); // acos((-1-1)/2)
88  // Around 0, asin is numerically more stable than acos because
89  // acos(x) = PI/2 - x and asin(x) = x (the precision of x is not lost in PI/2).
90 // else if (tr > Scalar(2) - 1e-2) theta = asin ((R(1,0) - R(0,1)) / Scalar(2));
91 // else theta = (pos ? acos (tr/Scalar(2)) : -acos(tr/Scalar(2)));
92  assert (theta == theta); // theta != NaN
93 // assert ((cos (theta) * R(0,0) + sin (theta) * R(1,0) > 0) &&
94 // (cos (theta) * R(1,0) - sin (theta) * R(0,0) < 1e-6));
95  return theta;
96  }
97 
98  template<typename Matrix2Like>
99  static typename Matrix2Like::Scalar
100  Jlog(const Eigen::MatrixBase<Matrix2Like> &)
101  {
102  typedef typename Matrix2Like::Scalar Scalar;
103  EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Matrix2Like,2,2);
104  return Scalar(1);
105  }
106 
111  static Index nq()
112  {
113  return NQ;
114  }
115 
117  static Index nv()
118  {
119  return NV;
120  }
121 
123  {
124  ConfigVector_t n; n << Scalar(1), Scalar(0);
125  return n;
126  }
127 
128  static std::string name()
129  {
130  return std::string("SO(2)");
131  }
132 
133  template <class ConfigL_t, class ConfigR_t, class Tangent_t>
134  static void difference_impl(const Eigen::MatrixBase<ConfigL_t> & q0,
135  const Eigen::MatrixBase<ConfigR_t> & q1,
136  const Eigen::MatrixBase<Tangent_t> & d)
137  {
138  Matrix2 R; // R0.transpose() * R1;
139  R(0,0) = R(1,1) = q0.dot(q1);
140  R(1,0) = q0(0) * q1(1) - q0(1) * q1(0);
141  R(0,1) = - R(1,0);
142  PINOCCHIO_EIGEN_CONST_CAST(Tangent_t,d)[0] = log(R);
143  }
144 
145  template <ArgumentPosition arg, class ConfigL_t, class ConfigR_t, class JacobianOut_t>
146  void dDifference_impl(const Eigen::MatrixBase<ConfigL_t> & q0,
147  const Eigen::MatrixBase<ConfigR_t> & q1,
148  const Eigen::MatrixBase<JacobianOut_t> & J) const
149  {
150  Matrix2 R; // R0.transpose() * R1;
151  R(0,0) = R(1,1) = q0.dot(q1);
152  R(1,0) = q0(0) * q1(1) - q0(1) * q1(0);
153  R(0,1) = - R(1,0);
154 
155  Scalar w (Jlog(R));
156  PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t,J).coeffRef(0,0) = ((arg==ARG0) ? -w : w);
157  }
158 
159  template <class ConfigIn_t, class Velocity_t, class ConfigOut_t>
160  static void integrate_impl(const Eigen::MatrixBase<ConfigIn_t> & q,
161  const Eigen::MatrixBase<Velocity_t> & v,
162  const Eigen::MatrixBase<ConfigOut_t> & qout)
163  {
164  ConfigOut_t & out = PINOCCHIO_EIGEN_CONST_CAST(ConfigOut_t,qout);
165 
166  const Scalar & ca = q(0);
167  const Scalar & sa = q(1);
168  const Scalar & omega = v(0);
169 
170  Scalar cosOmega,sinOmega; SINCOS(omega, &sinOmega, &cosOmega);
171  // TODO check the cost of atan2 vs SINCOS
172 
173  out << cosOmega * ca - sinOmega * sa,
174  sinOmega * ca + cosOmega * sa;
175  // First order approximation of the normalization of the unit complex
176  // See quaternion::firstOrderNormalize for equations.
177  const Scalar norm2 = out.squaredNorm();
178  out *= (3 - norm2) / 2;
179  }
180 
181  template <class Config_t, class Jacobian_t>
182  static void integrateCoeffWiseJacobian_impl(const Eigen::MatrixBase<Config_t> & q,
183  const Eigen::MatrixBase<Jacobian_t> & J)
184  {
185  assert(J.rows() == nq() && J.cols() == nv() && "J is not of the right dimension");
186  Jacobian_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(Jacobian_t,J);
187  Jout << -q[1], q[0];
188  }
189 
190  template <class Config_t, class Tangent_t, class JacobianOut_t>
191  static void dIntegrate_dq_impl(const Eigen::MatrixBase<Config_t > & /*q*/,
192  const Eigen::MatrixBase<Tangent_t> & /*v*/,
193  const Eigen::MatrixBase<JacobianOut_t> & J,
194  const AssignmentOperatorType op=SETTO)
195  {
196  JacobianOut_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t,J);
197  switch(op)
198  {
199  case SETTO:
200  Jout(0,0) = Scalar(1);
201  break;
202  case ADDTO:
203  Jout(0,0) += Scalar(1);
204  break;
205  case RMTO:
206  Jout(0,0) -= Scalar(1);
207  break;
208  default:
209  assert(false && "Wrong Op requesed value");
210  break;
211  }
212  }
213 
214  template <class Config_t, class Tangent_t, class JacobianOut_t>
215  static void dIntegrate_dv_impl(const Eigen::MatrixBase<Config_t > & /*q*/,
216  const Eigen::MatrixBase<Tangent_t> & /*v*/,
217  const Eigen::MatrixBase<JacobianOut_t> & J,
218  const AssignmentOperatorType op=SETTO)
219  {
220  JacobianOut_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t,J);
221  switch(op)
222  {
223  case SETTO:
224  Jout(0,0) = Scalar(1);
225  break;
226  case ADDTO:
227  Jout(0,0) += Scalar(1);
228  break;
229  case RMTO:
230  Jout(0,0) -= Scalar(1);
231  break;
232  default:
233  assert(false && "Wrong Op requesed value");
234  break;
235  }
236  }
237 
238  template <class Config_t, class Tangent_t, class JacobianIn_t, class JacobianOut_t>
239  void dIntegrateTransport_dq_impl(const Eigen::MatrixBase<Config_t > & /*q*/,
240  const Eigen::MatrixBase<Tangent_t> & /*v*/,
241  const Eigen::MatrixBase<JacobianIn_t> & Jin,
242  const Eigen::MatrixBase<JacobianOut_t> & Jout) const
243  {
244  PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t,Jout) = Jin;
245  }
246 
247  template <class Config_t, class Tangent_t, class JacobianIn_t, class JacobianOut_t>
248  void dIntegrateTransport_dv_impl(const Eigen::MatrixBase<Config_t > & /*q*/,
249  const Eigen::MatrixBase<Tangent_t> & /*v*/,
250  const Eigen::MatrixBase<JacobianIn_t> & Jin,
251  const Eigen::MatrixBase<JacobianOut_t> & Jout) const
252  {
253  PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t,Jout) = Jin;
254  }
255 
256  template <class Config_t, class Tangent_t, class Jacobian_t>
257  void dIntegrateTransport_dq_impl(const Eigen::MatrixBase<Config_t > & /*q*/,
258  const Eigen::MatrixBase<Tangent_t> & /*v*/,
259  const Eigen::MatrixBase<Jacobian_t> & /*J*/) const {}
260 
261  template <class Config_t, class Tangent_t, class Jacobian_t>
262  void dIntegrateTransport_dv_impl(const Eigen::MatrixBase<Config_t > & /*q*/,
263  const Eigen::MatrixBase<Tangent_t> & /*v*/,
264  const Eigen::MatrixBase<Jacobian_t> & /*J*/) const {}
265 
266 
267 
268  template <class ConfigL_t, class ConfigR_t, class ConfigOut_t>
269  static void interpolate_impl(const Eigen::MatrixBase<ConfigL_t> & q0,
270  const Eigen::MatrixBase<ConfigR_t> & q1,
271  const Scalar& u,
272  const Eigen::MatrixBase<ConfigOut_t>& qout)
273  {
274  ConfigOut_t & out = PINOCCHIO_EIGEN_CONST_CAST(ConfigOut_t,qout);
275 
276  assert ( std::abs(q0.norm() - 1) < 1e-8 && "initial configuration not normalized");
277  assert ( std::abs(q1.norm() - 1) < 1e-8 && "final configuration not normalized");
278  Scalar cosTheta = q0.dot(q1);
279  Scalar sinTheta = q0(0)*q1(1) - q0(1)*q1(0);
280  Scalar theta = atan2(sinTheta, cosTheta);
281  assert (fabs (sin (theta) - sinTheta) < 1e-8);
282 
283  const Scalar PI_value = PI<Scalar>();
284 
285  if (fabs (theta) > 1e-6 && fabs (theta) < PI_value - 1e-6)
286  {
287  out = (sin ((1-u)*theta)/sinTheta) * q0
288  + (sin ( u *theta)/sinTheta) * q1;
289  }
290  else if (fabs (theta) < 1e-6) // theta = 0
291  {
292  out = (1-u) * q0 + u * q1;
293  }
294  else // theta = +-PI
295  {
296  Scalar theta0 = atan2 (q0(1), q0(0));
297  SINCOS(theta0,&out[1],&out[0]);
298  }
299  }
300 
301  template <class Config_t>
302  static void normalize_impl (const Eigen::MatrixBase<Config_t> & qout)
303  {
304  Config_t & qout_ = PINOCCHIO_EIGEN_CONST_CAST(Config_t,qout).derived();
305  qout_.normalize();
306  }
307 
308  template <class Config_t>
309  static bool isNormalized_impl (const Eigen::MatrixBase<Config_t> & qin,
310  const Scalar& prec)
311  {
312  const Scalar norm = qin.norm();
313  using std::abs;
314  return abs(norm - Scalar(1.0)) < prec;
315  }
316 
317  template <class Config_t>
318  void random_impl (const Eigen::MatrixBase<Config_t>& qout) const
319  {
320  Config_t & out = PINOCCHIO_EIGEN_CONST_CAST(Config_t,qout);
321 
322  const Scalar PI_value = PI<Scalar>();
323  const Scalar angle = -PI_value + Scalar(2)* PI_value * ((Scalar)rand())/RAND_MAX;
324  SINCOS(angle, &out(1), &out(0));
325  }
326 
327  template <class ConfigL_t, class ConfigR_t, class ConfigOut_t>
328  void randomConfiguration_impl(const Eigen::MatrixBase<ConfigL_t> &,
329  const Eigen::MatrixBase<ConfigR_t> &,
330  const Eigen::MatrixBase<ConfigOut_t> & qout) const
331  {
332  random_impl(qout);
333  }
334  }; // struct SpecialOrthogonalOperationTpl<2,_Scalar,_Options>
335 
336  template<typename _Scalar, int _Options>
337  struct SpecialOrthogonalOperationTpl<3,_Scalar,_Options>
338  : public LieGroupBase< SpecialOrthogonalOperationTpl<3,_Scalar,_Options> >
339  {
341 
342  typedef Eigen::Quaternion<Scalar> Quaternion_t;
343  typedef Eigen::Map< Quaternion_t> QuaternionMap_t;
344  typedef Eigen::Map<const Quaternion_t> ConstQuaternionMap_t;
346  typedef typename Eigen::NumTraits<Scalar>::Real RealScalar;
347 
352  static Index nq()
353  {
354  return NQ;
355  }
356 
358  static Index nv()
359  {
360  return NV;
361  }
362 
364  {
365  ConfigVector_t n; n.setZero (); n[3] = Scalar(1);
366  return n;
367  }
368 
369  static std::string name()
370  {
371  return std::string("SO(3)");
372  }
373 
374  template <class ConfigL_t, class ConfigR_t, class Tangent_t>
375  static void difference_impl(const Eigen::MatrixBase<ConfigL_t> & q0,
376  const Eigen::MatrixBase<ConfigR_t> & q1,
377  const Eigen::MatrixBase<Tangent_t> & d)
378  {
379  ConstQuaternionMap_t quat0 (q0.derived().data());
381  ConstQuaternionMap_t quat1 (q1.derived().data());
383 
384  PINOCCHIO_EIGEN_CONST_CAST(Tangent_t,d)
385  = log3((quat0.matrix().transpose() * quat1.matrix()).eval());
386  }
387 
388  template <ArgumentPosition arg, class ConfigL_t, class ConfigR_t, class JacobianOut_t>
389  void dDifference_impl (const Eigen::MatrixBase<ConfigL_t> & q0,
390  const Eigen::MatrixBase<ConfigR_t> & q1,
391  const Eigen::MatrixBase<JacobianOut_t> & J) const
392  {
393  typedef typename SE3::Matrix3 Matrix3;
394 
395  ConstQuaternionMap_t quat0 (q0.derived().data());
397  ConstQuaternionMap_t quat1 (q1.derived().data());
399 
400  const Matrix3 R = quat0.matrix().transpose() * quat1.matrix(); // TODO: perform first the Quaternion multiplications and then return a Rotation Matrix
401 
402  if (arg == ARG0) {
403  JacobianMatrix_t J1;
404  Jlog3 (R, J1);
405 
406  PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t,J).noalias() = - J1 * R.transpose();
407  } else if (arg == ARG1) {
408  Jlog3 (R, J);
409  }
410  }
411 
412  template <class ConfigIn_t, class Velocity_t, class ConfigOut_t>
413  static void integrate_impl(const Eigen::MatrixBase<ConfigIn_t> & q,
414  const Eigen::MatrixBase<Velocity_t> & v,
415  const Eigen::MatrixBase<ConfigOut_t> & qout)
416  {
417  ConstQuaternionMap_t quat(q.derived().data());
419  QuaternionMap_t quat_map(PINOCCHIO_EIGEN_CONST_CAST(ConfigOut_t,qout).data());
420 
421  Quaternion_t pOmega; quaternion::exp3(v,pOmega);
422  quat_map = quat * pOmega;
425  }
426 
427  template <class Config_t, class Jacobian_t>
428  static void integrateCoeffWiseJacobian_impl(const Eigen::MatrixBase<Config_t> & q,
429  const Eigen::MatrixBase<Jacobian_t> & J)
430  {
431  assert(J.rows() == nq() && J.cols() == nv() && "J is not of the right dimension");
432 
433  typedef typename PINOCCHIO_EIGEN_PLAIN_TYPE(Jacobian_t) JacobianPlainType;
434  typedef typename SE3::Vector3 Vector3;
435  typedef typename SE3::Matrix3 Matrix3;
436 
437  ConstQuaternionMap_t quat_map(q.derived().data());
439 
440  Eigen::Matrix<Scalar,NQ,NV,JacobianPlainType::Options|Eigen::RowMajor> Jexp3QuatCoeffWise;
441 
442  Scalar theta;
443  const Vector3 v = quaternion::log3(quat_map,theta);
444  quaternion::Jexp3CoeffWise(v,Jexp3QuatCoeffWise);
445  Matrix3 Jlog;
446  Jlog3(theta,v,Jlog);
447 
448 // if(quat_map.w() >= 0.) // comes from the log3 for quaternions which may change the sign.
449  if(quat_map.coeffs()[3] >= 0.) // comes from the log3 for quaternions which may change the sign.
450  PINOCCHIO_EIGEN_CONST_CAST(Jacobian_t,J).noalias() = Jexp3QuatCoeffWise * Jlog;
451  else
452  PINOCCHIO_EIGEN_CONST_CAST(Jacobian_t,J).noalias() = -Jexp3QuatCoeffWise * Jlog;
453 
454 // Jexp3(quat_map,PINOCCHIO_EIGEN_CONST_CAST(Jacobian_t,J).template topLeftCorner<NQ,NV>());
455  }
456 
457  template <class Config_t, class Tangent_t, class JacobianOut_t>
458  static void dIntegrate_dq_impl(const Eigen::MatrixBase<Config_t > & /*q*/,
459  const Eigen::MatrixBase<Tangent_t> & v,
460  const Eigen::MatrixBase<JacobianOut_t> & J,
461  const AssignmentOperatorType op=SETTO)
462  {
463  JacobianOut_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t,J);
464  switch(op)
465  {
466  case SETTO:
467  Jout = exp3(-v);
468  break;
469  case ADDTO:
470  Jout += exp3(-v);
471  break;
472  case RMTO:
473  Jout -= exp3(-v);
474  break;
475  default:
476  assert(false && "Wrong Op requesed value");
477  break;
478  }
479  }
480 
481  template <class Config_t, class Tangent_t, class JacobianOut_t>
482  static void dIntegrate_dv_impl(const Eigen::MatrixBase<Config_t > & /*q*/,
483  const Eigen::MatrixBase<Tangent_t> & v,
484  const Eigen::MatrixBase<JacobianOut_t> & J,
485  const AssignmentOperatorType op=SETTO)
486  {
487  switch(op)
488  {
489  case SETTO:
490  Jexp3<SETTO>(v, J.derived());
491  break;
492  case ADDTO:
493  Jexp3<ADDTO>(v, J.derived());
494  break;
495  case RMTO:
496  Jexp3<RMTO>(v, J.derived());
497  break;
498  default:
499  assert(false && "Wrong Op requesed value");
500  break;
501  }
502  }
503 
504  template <class Config_t, class Tangent_t, class JacobianIn_t, class JacobianOut_t>
505  void dIntegrateTransport_dq_impl(const Eigen::MatrixBase<Config_t > & /*q*/,
506  const Eigen::MatrixBase<Tangent_t> & v,
507  const Eigen::MatrixBase<JacobianIn_t> & Jin,
508  const Eigen::MatrixBase<JacobianOut_t> & J_out) const
509  {
510  typedef typename SE3::Matrix3 Matrix3;
511  JacobianOut_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t,J_out);
512  const Matrix3 Jtmp3 = exp3(-v);
513  Jout.noalias() = Jtmp3 * Jin;
514  }
515 
516  template <class Config_t, class Tangent_t, class JacobianIn_t, class JacobianOut_t>
517  void dIntegrateTransport_dv_impl(const Eigen::MatrixBase<Config_t > & /*q*/,
518  const Eigen::MatrixBase<Tangent_t> & v,
519  const Eigen::MatrixBase<JacobianIn_t> & Jin,
520  const Eigen::MatrixBase<JacobianOut_t> & J_out) const
521  {
522  typedef typename SE3::Matrix3 Matrix3;
523  JacobianOut_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t,J_out);
524  Matrix3 Jtmp3;
525  Jexp3<SETTO>(v, Jtmp3);
526  Jout.noalias() = Jtmp3 * Jin;
527  }
528 
529  template <class Config_t, class Tangent_t, class Jacobian_t>
530  void dIntegrateTransport_dq_impl(const Eigen::MatrixBase<Config_t > & /*q*/,
531  const Eigen::MatrixBase<Tangent_t> & v,
532  const Eigen::MatrixBase<Jacobian_t> & J_out) const
533  {
534  typedef typename SE3::Matrix3 Matrix3;
535  Jacobian_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(Jacobian_t,J_out);
536  const Matrix3 Jtmp3 = exp3(-v);
537  Jout = Jtmp3 * Jout;
538  }
539 
540  template <class Config_t, class Tangent_t, class Jacobian_t>
541  void dIntegrateTransport_dv_impl(const Eigen::MatrixBase<Config_t > & /*q*/,
542  const Eigen::MatrixBase<Tangent_t> & v,
543  const Eigen::MatrixBase<Jacobian_t> & J_out) const
544  {
545  typedef typename SE3::Matrix3 Matrix3;
546  Jacobian_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(Jacobian_t,J_out);
547  Matrix3 Jtmp3;
548  Jexp3<SETTO>(v, Jtmp3);
549  Jout = Jtmp3 * Jout;
550  }
551 
552 
553  template <class ConfigL_t, class ConfigR_t, class ConfigOut_t>
554  static void interpolate_impl(const Eigen::MatrixBase<ConfigL_t> & q0,
555  const Eigen::MatrixBase<ConfigR_t> & q1,
556  const Scalar & u,
557  const Eigen::MatrixBase<ConfigOut_t> & qout)
558  {
559  ConstQuaternionMap_t quat0 (q0.derived().data());
561  ConstQuaternionMap_t quat1 (q1.derived().data());
563 
564  QuaternionMap_t quat_map(PINOCCHIO_EIGEN_CONST_CAST(ConfigOut_t,qout).data());
565 
566  quat_map = quat0.slerp(u, quat1);
568  }
569 
570  template <class ConfigL_t, class ConfigR_t>
571  static Scalar squaredDistance_impl(const Eigen::MatrixBase<ConfigL_t> & q0,
572  const Eigen::MatrixBase<ConfigR_t> & q1)
573  {
575  difference_impl(q0, q1, t);
576  return t.squaredNorm();
577  }
578 
579  template <class Config_t>
580  static void normalize_impl(const Eigen::MatrixBase<Config_t> & qout)
581  {
582  Config_t & qout_ = PINOCCHIO_EIGEN_CONST_CAST(Config_t,qout);
583  qout_.normalize();
584  }
585 
586  template <class Config_t>
587  static bool isNormalized_impl (const Eigen::MatrixBase<Config_t> & qin,
588  const Scalar& prec)
589  {
590  const Scalar norm = qin.norm();
591  using std::abs;
592  return abs(norm - Scalar(1.0)) < prec;
593  }
594 
595  template <class Config_t>
596  void random_impl(const Eigen::MatrixBase<Config_t> & qout) const
597  {
598  QuaternionMap_t quat_map(PINOCCHIO_EIGEN_CONST_CAST(Config_t,qout).data());
599  quaternion::uniformRandom(quat_map);
600 
602  }
603 
604  template <class ConfigL_t, class ConfigR_t, class ConfigOut_t>
605  void randomConfiguration_impl(const Eigen::MatrixBase<ConfigL_t> &,
606  const Eigen::MatrixBase<ConfigR_t> &,
607  const Eigen::MatrixBase<ConfigOut_t> & qout) const
608  {
609  random_impl(qout);
610  }
611 
612  template <class ConfigL_t, class ConfigR_t>
613  static bool isSameConfiguration_impl(const Eigen::MatrixBase<ConfigL_t> & q0,
614  const Eigen::MatrixBase<ConfigR_t> & q1,
615  const Scalar & prec)
616  {
617  ConstQuaternionMap_t quat1(q0.derived().data());
619  ConstQuaternionMap_t quat2(q1.derived().data());
621 
622  return quaternion::defineSameRotation(quat1,quat2,prec);
623  }
624  }; // struct SpecialOrthogonalOperationTpl<3,_Scalar,_Options>
625 
626 } // namespace pinocchio
627 
628 #endif // ifndef __pinocchio_multibody_liegroup_special_orthogonal_operation_hpp__
Eigen::Matrix< typename Matrix3Like::Scalar, 3, 1, PINOCCHIO_EIGEN_PLAIN_TYPE(Matrix3Like)::Options > log3(const Eigen::MatrixBase< Matrix3Like > &R, typename Matrix3Like::Scalar &theta)
Same as log3.
JointCollectionTpl const Eigen::MatrixBase< ConfigVectorType > const Eigen::MatrixBase< TangentVectorType > & v
static bool isSameConfiguration_impl(const Eigen::MatrixBase< ConfigL_t > &q0, const Eigen::MatrixBase< ConfigR_t > &q1, const Scalar &prec)
int nv(const JointModelTpl< Scalar, Options, JointCollectionTpl > &jmodel)
Visit a JointModelTpl through JointNvVisitor to get the dimension of the joint tangent space...
static void integrateCoeffWiseJacobian_impl(const Eigen::MatrixBase< Config_t > &q, const Eigen::MatrixBase< Jacobian_t > &J)
void dIntegrateTransport_dq_impl(const Eigen::MatrixBase< Config_t > &, const Eigen::MatrixBase< Tangent_t > &v, const Eigen::MatrixBase< JacobianIn_t > &Jin, const Eigen::MatrixBase< JacobianOut_t > &J_out) const
int NQ
Definition: dpendulum.py:8
void dIntegrateTransport_dv_impl(const Eigen::MatrixBase< Config_t > &, const Eigen::MatrixBase< Tangent_t > &, const Eigen::MatrixBase< Jacobian_t > &) const
static bool isNormalized_impl(const Eigen::MatrixBase< Config_t > &qin, const Scalar &prec)
bool defineSameRotation(const Eigen::QuaternionBase< D1 > &q1, const Eigen::QuaternionBase< D2 > &q2, const typename D1::RealScalar &prec=Eigen::NumTraits< typename D1::Scalar >::dummy_precision())
Check if two quaternions define the same rotations.
static void difference_impl(const Eigen::MatrixBase< ConfigL_t > &q0, const Eigen::MatrixBase< ConfigR_t > &q1, const Eigen::MatrixBase< Tangent_t > &d)
void randomConfiguration_impl(const Eigen::MatrixBase< ConfigL_t > &, const Eigen::MatrixBase< ConfigR_t > &, const Eigen::MatrixBase< ConfigOut_t > &qout) const
int nq(const JointModelTpl< Scalar, Options, JointCollectionTpl > &jmodel)
Visit a JointModelTpl through JointNqVisitor to get the dimension of the joint configuration space...
void randomConfiguration_impl(const Eigen::MatrixBase< ConfigL_t > &, const Eigen::MatrixBase< ConfigR_t > &, const Eigen::MatrixBase< ConfigOut_t > &qout) const
void Jlog3(const Scalar &theta, const Eigen::MatrixBase< Vector3Like > &log, const Eigen::MatrixBase< Matrix3Like > &Jlog)
Derivative of log3.
void dIntegrateTransport_dv_impl(const Eigen::MatrixBase< Config_t > &, const Eigen::MatrixBase< Tangent_t > &v, const Eigen::MatrixBase< JacobianIn_t > &Jin, const Eigen::MatrixBase< JacobianOut_t > &J_out) const
void dDifference_impl(const Eigen::MatrixBase< ConfigL_t > &q0, const Eigen::MatrixBase< ConfigR_t > &q1, const Eigen::MatrixBase< JacobianOut_t > &J) const
static void normalize_impl(const Eigen::MatrixBase< Config_t > &qout)
void dIntegrateTransport_dq_impl(const Eigen::MatrixBase< Config_t > &, const Eigen::MatrixBase< Tangent_t > &v, const Eigen::MatrixBase< Jacobian_t > &J_out) const
void dIntegrateTransport_dv_impl(const Eigen::MatrixBase< Config_t > &, const Eigen::MatrixBase< Tangent_t > &v, const Eigen::MatrixBase< Jacobian_t > &J_out) const
static void interpolate_impl(const Eigen::MatrixBase< ConfigL_t > &q0, const Eigen::MatrixBase< ConfigR_t > &q1, const Scalar &u, const Eigen::MatrixBase< ConfigOut_t > &qout)
static Index nv()
Get dimension of Lie Group tangent space.
void firstOrderNormalize(const Eigen::QuaternionBase< D > &q)
#define PINOCCHIO_LIE_GROUP_TPL_PUBLIC_INTERFACE(Derived)
static void difference_impl(const Eigen::MatrixBase< ConfigL_t > &q0, const Eigen::MatrixBase< ConfigR_t > &q1, const Eigen::MatrixBase< Tangent_t > &d)
void exp3(const Eigen::MatrixBase< Vector3Like > &v, Eigen::QuaternionBase< QuaternionLike > &quat_out)
Exp: so3 -> SO3 (quaternion)
data
JointCollectionTpl const Eigen::MatrixBase< ConfigVectorType > & q
#define PINOCCHIO_EIGEN_CONST_CAST(TYPE, OBJ)
Macro for an automatic const_cast.
void dDifference_impl(const Eigen::MatrixBase< ConfigL_t > &q0, const Eigen::MatrixBase< ConfigR_t > &q1, const Eigen::MatrixBase< JacobianOut_t > &J) const
void Jexp3CoeffWise(const Eigen::MatrixBase< Vector3Like > &v, const Eigen::MatrixBase< Matrix43Like > &Jexp)
Derivative of where is a small perturbation of at identity.
SE3::Scalar Scalar
Definition: conversions.cpp:13
Eigen::Matrix< typename Vector3Like::Scalar, 3, 3, PINOCCHIO_EIGEN_PLAIN_TYPE(Vector3Like)::Options > exp3(const Eigen::MatrixBase< Vector3Like > &v)
Exp: so3 -> SO3.
static Index nv()
Get dimension of Lie Group tangent space.
static void integrate_impl(const Eigen::MatrixBase< ConfigIn_t > &q, const Eigen::MatrixBase< Velocity_t > &v, const Eigen::MatrixBase< ConfigOut_t > &qout)
JointCollectionTpl const Eigen::MatrixBase< ConfigVectorIn1 > const Eigen::MatrixBase< ConfigVectorIn2 > const Scalar & u
AssignmentOperatorType
Definition: src/fwd.hpp:68
static void normalize_impl(const Eigen::MatrixBase< Config_t > &qout)
Eigen::Matrix< typename QuaternionLike::Scalar, 3, 1, PINOCCHIO_EIGEN_PLAIN_TYPE(typename QuaternionLike::Vector3)::Options > log3(const Eigen::QuaternionBase< QuaternionLike > &quat, typename QuaternionLike::Scalar &theta)
Same as log3 but with a unit quaternion as input.
d
Definition: ur5x4.py:45
static Matrix2Like::Scalar log(const Eigen::MatrixBase< Matrix2Like > &R)
void random_impl(const Eigen::MatrixBase< Config_t > &qout) const
static Matrix2Like::Scalar Jlog(const Eigen::MatrixBase< Matrix2Like > &)
static void dIntegrate_dq_impl(const Eigen::MatrixBase< Config_t > &, const Eigen::MatrixBase< Tangent_t > &, const Eigen::MatrixBase< JacobianOut_t > &J, const AssignmentOperatorType op=SETTO)
static Scalar squaredDistance_impl(const Eigen::MatrixBase< ConfigL_t > &q0, const Eigen::MatrixBase< ConfigR_t > &q1)
static void interpolate_impl(const Eigen::MatrixBase< ConfigL_t > &q0, const Eigen::MatrixBase< ConfigR_t > &q1, const Scalar &u, const Eigen::MatrixBase< ConfigOut_t > &qout)
JointCollectionTpl const Eigen::MatrixBase< ConfigVectorIn1 > const Eigen::MatrixBase< ConfigVectorIn2 > & q1
R
quat
void SINCOS(const S1 &a, S2 *sa, S3 *ca)
Computes sin/cos values of a given input scalar.
Definition: sincos.hpp:26
traits< SE3Tpl >::Vector3 Vector3
static void dIntegrate_dv_impl(const Eigen::MatrixBase< Config_t > &, const Eigen::MatrixBase< Tangent_t > &v, const Eigen::MatrixBase< JacobianOut_t > &J, const AssignmentOperatorType op=SETTO)
void uniformRandom(const Eigen::QuaternionBase< Derived > &q)
Uniformly random quaternion sphere.
void random_impl(const Eigen::MatrixBase< Config_t > &qout) const
Main pinocchio namespace.
Definition: timings.cpp:30
JointCollectionTpl const Eigen::MatrixBase< ConfigVectorIn1 > & q0
PINOCCHIO_EIGEN_PLAIN_TYPE(ConfigVectorType) integrate(const ModelTpl< Scalar
Integrate a configuration vector for the specified model for a tangent vector during one unit time...
bool isNormalized(const Eigen::QuaternionBase< Quaternion > &quat, const typename Quaternion::Coefficients::RealScalar &prec=Eigen::NumTraits< typename Quaternion::Coefficients::RealScalar >::dummy_precision())
Check whether the input quaternion is Normalized within the given precision.
#define PINOCCHIO_DEFAULT_QUATERNION_NORM_TOLERANCE_VALUE
Common traits structure to fully define base classes for CRTP.
Definition: src/fwd.hpp:44
if_then_else_impl< LhsType, RhsType, ThenType, ElseType >::ReturnType if_then_else(const ComparisonOperators op, const LhsType &lhs_value, const RhsType &rhs_value, const ThenType &then_value, const ElseType &else_value)
static bool isNormalized_impl(const Eigen::MatrixBase< Config_t > &qin, const Scalar &prec)
void dIntegrateTransport_dq_impl(const Eigen::MatrixBase< Config_t > &, const Eigen::MatrixBase< Tangent_t > &, const Eigen::MatrixBase< Jacobian_t > &) const
static void integrateCoeffWiseJacobian_impl(const Eigen::MatrixBase< Config_t > &q, const Eigen::MatrixBase< Jacobian_t > &J)
traits< SE3Tpl >::Matrix3 Matrix3
static void integrate_impl(const Eigen::MatrixBase< ConfigIn_t > &q, const Eigen::MatrixBase< Velocity_t > &v, const Eigen::MatrixBase< ConfigOut_t > &qout)
NV
Definition: dcrba.py:444
w
Definition: ur5x4.py:45
void dIntegrateTransport_dv_impl(const Eigen::MatrixBase< Config_t > &, const Eigen::MatrixBase< Tangent_t > &, const Eigen::MatrixBase< JacobianIn_t > &Jin, const Eigen::MatrixBase< JacobianOut_t > &Jout) const
static void dIntegrate_dv_impl(const Eigen::MatrixBase< Config_t > &, const Eigen::MatrixBase< Tangent_t > &, const Eigen::MatrixBase< JacobianOut_t > &J, const AssignmentOperatorType op=SETTO)
void dIntegrateTransport_dq_impl(const Eigen::MatrixBase< Config_t > &, const Eigen::MatrixBase< Tangent_t > &, const Eigen::MatrixBase< JacobianIn_t > &Jin, const Eigen::MatrixBase< JacobianOut_t > &Jout) const
static void dIntegrate_dq_impl(const Eigen::MatrixBase< Config_t > &, const Eigen::MatrixBase< Tangent_t > &v, const Eigen::MatrixBase< JacobianOut_t > &J, const AssignmentOperatorType op=SETTO)


pinocchio
Author(s):
autogenerated on Tue Jun 1 2021 02:45:04