pinocchio  2.1.3
joint-spherical.hpp
1 //
2 // Copyright (c) 2015-2019 CNRS INRIA
3 // Copyright (c) 2015-2016 Wandercraft, 86 rue de Paris 91400 Orsay, France.
4 //
5 
6 #ifndef __pinocchio_joint_spherical_hpp__
7 #define __pinocchio_joint_spherical_hpp__
8 
9 #include "pinocchio/macros.hpp"
10 #include "pinocchio/multibody/joint/joint-base.hpp"
11 #include "pinocchio/multibody/constraint.hpp"
12 #include "pinocchio/math/sincos.hpp"
13 #include "pinocchio/spatial/inertia.hpp"
14 #include "pinocchio/spatial/skew.hpp"
15 
16 namespace pinocchio
17 {
18 
19  template<typename Scalar, int Options = 0> struct MotionSphericalTpl;
21 
22  namespace internal
23  {
24  template<typename Scalar, int Options>
25  struct SE3GroupAction< MotionSphericalTpl<Scalar,Options> >
26  {
27  typedef MotionTpl<Scalar,Options> ReturnType;
28  };
29 
30  template<typename Scalar, int Options, typename MotionDerived>
31  struct MotionAlgebraAction< MotionSphericalTpl<Scalar,Options>, MotionDerived>
32  {
33  typedef MotionTpl<Scalar,Options> ReturnType;
34  };
35  }
36 
37  template<typename _Scalar, int _Options>
38  struct traits< MotionSphericalTpl<_Scalar,_Options> >
39  {
40  typedef _Scalar Scalar;
41  enum { Options = _Options };
42  typedef Eigen::Matrix<Scalar,3,1,Options> Vector3;
43  typedef Eigen::Matrix<Scalar,6,1,Options> Vector6;
44  typedef Eigen::Matrix<Scalar,6,6,Options> Matrix6;
45  typedef typename PINOCCHIO_EIGEN_REF_CONST_TYPE(Vector6) ToVectorConstReturnType;
46  typedef typename PINOCCHIO_EIGEN_REF_TYPE(Vector6) ToVectorReturnType;
47  typedef Vector3 AngularType;
48  typedef Vector3 LinearType;
49  typedef const Vector3 ConstAngularType;
50  typedef const Vector3 ConstLinearType;
51  typedef Matrix6 ActionMatrixType;
53  enum {
54  LINEAR = 0,
55  ANGULAR = 3
56  };
57  }; // traits MotionSphericalTpl
58 
59  template<typename _Scalar, int _Options>
60  struct MotionSphericalTpl : MotionBase< MotionSphericalTpl<_Scalar,_Options> >
61  {
62  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
63 
64  MOTION_TYPEDEF_TPL(MotionSphericalTpl);
65 
67 
68  template<typename Vector3Like>
69  MotionSphericalTpl(const Eigen::MatrixBase<Vector3Like> & w)
70  : w(w)
71  {}
72 
73  Vector3 & operator() () { return w; }
74  const Vector3 & operator() () const { return w; }
75 
76 // operator MotionPlain() const
77 // {
78 // return MotionPlain(MotionPlain::Vector3::Zero(), w);
79 // }
80 
81  template<typename MotionDerived>
82  void addTo(MotionDense<MotionDerived> & other) const
83  {
84  other.angular() += w;
85  }
86 
87  template<typename Derived>
88  void setTo(MotionDense<Derived> & other) const
89  {
90  other.linear().setZero();
91  other.angular() = w;
92  }
93 
94  MotionSphericalTpl __plus__(const MotionSphericalTpl & other) const
95  {
96  return MotionSphericalTpl(w + other.w);
97  }
98 
99  bool isEqual_impl(const MotionSphericalTpl & other) const
100  {
101  return w == other.w;
102  }
103 
104  template<typename MotionDerived>
105  bool isEqual_impl(const MotionDense<MotionDerived> & other) const
106  {
107  return other.angular() == w && other.linear().isZero(0);
108  }
109 
110  template<typename S2, int O2, typename D2>
111  void se3Action_impl(const SE3Tpl<S2,O2> & m, MotionDense<D2> & v) const
112  {
113  // Angular
114  v.angular().noalias() = m.rotation() * w;
115 
116  // Linear
117  v.linear().noalias() = m.translation().cross(v.angular());
118  }
119 
120  template<typename S2, int O2>
121  MotionPlain se3Action_impl(const SE3Tpl<S2,O2> & m) const
122  {
123  MotionPlain res;
124  se3Action_impl(m,res);
125  return res;
126  }
127 
128  template<typename S2, int O2, typename D2>
129  void se3ActionInverse_impl(const SE3Tpl<S2,O2> & m, MotionDense<D2> & v) const
130  {
131  // Linear
132  // TODO: use v.angular() as temporary variable
133  Vector3 v3_tmp;
134  v3_tmp.noalias() = w.cross(m.translation());
135  v.linear().noalias() = m.rotation().transpose() * v3_tmp;
136 
137  // Angular
138  v.angular().noalias() = m.rotation().transpose() * w;
139  }
140 
141  template<typename S2, int O2>
142  MotionPlain se3ActionInverse_impl(const SE3Tpl<S2,O2> & m) const
143  {
144  MotionPlain res;
145  se3ActionInverse_impl(m,res);
146  return res;
147  }
148 
149  template<typename M1, typename M2>
150  void motionAction(const MotionDense<M1> & v, MotionDense<M2> & mout) const
151  {
152  // Linear
153  mout.linear().noalias() = v.linear().cross(w);
154 
155  // Angular
156  mout.angular().noalias() = v.angular().cross(w);
157  }
158 
159  template<typename M1>
160  MotionPlain motionAction(const MotionDense<M1> & v) const
161  {
162  MotionPlain res;
163  motionAction(v,res);
164  return res;
165  }
166 
167  // data
168  Vector3 w;
169  }; // struct MotionSphericalTpl
170 
171  template<typename S1, int O1, typename MotionDerived>
172  inline typename MotionDerived::MotionPlain
173  operator+(const MotionSphericalTpl<S1,O1> & m1, const MotionDense<MotionDerived> & m2)
174  {
175  return typename MotionDerived::MotionPlain(m2.linear(),m2.angular() + m1.w);
176  }
177 
178  template<typename Scalar, int Options> struct ConstraintSphericalTpl;
179 
180  template<typename _Scalar, int _Options>
181  struct traits< ConstraintSphericalTpl<_Scalar,_Options> >
182  {
183  typedef _Scalar Scalar;
184  enum { Options = _Options };
185  typedef Eigen::Matrix<Scalar,3,1,Options> Vector3;
186  typedef Eigen::Matrix<Scalar,4,1,Options> Vector4;
187  typedef Eigen::Matrix<Scalar,6,1,Options> Vector6;
188  typedef Eigen::Matrix<Scalar,3,3,Options> Matrix3;
189  typedef Eigen::Matrix<Scalar,4,4,Options> Matrix4;
190  typedef Eigen::Matrix<Scalar,6,6,Options> Matrix6;
191  typedef Matrix3 Angular_t;
192  typedef Vector3 Linear_t;
193  typedef const Matrix3 ConstAngular_t;
194  typedef const Vector3 ConstLinear_t;
195  typedef Matrix6 ActionMatrix_t;
196  typedef Eigen::Quaternion<Scalar,Options> Quaternion_t;
197  typedef SE3Tpl<Scalar,Options> SE3;
201  enum {
202  LINEAR = 0,
203  ANGULAR = 3
204  };
206  typedef Eigen::Matrix<Scalar,3,1,Options> JointForce;
207  typedef Eigen::Matrix<Scalar,6,3,Options> DenseBase;
208  typedef DenseBase MatrixReturnType;
209  typedef const DenseBase ConstMatrixReturnType;
210  }; // struct traits struct ConstraintSphericalTpl
211 
212  template<typename _Scalar, int _Options>
214  : public ConstraintBase< ConstraintSphericalTpl<_Scalar,_Options> >
215  {
216  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
217 
218  SPATIAL_TYPEDEF_TEMPLATE(ConstraintSphericalTpl);
219 
220  enum { NV = 3, Options = _Options };
222  typedef typename traits<ConstraintSphericalTpl>::JointForce JointForce;
223  typedef typename traits<ConstraintSphericalTpl>::DenseBase DenseBase;
224 
225  int nv_impl() const { return NV; }
226 
227  template<typename Vector3Like>
228  JointMotion __mult__(const Eigen::MatrixBase<Vector3Like> & w) const
229  {
230  EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Vector3Like,3);
231  return JointMotion(w);
232  }
233 
235  {
236  template<typename Derived>
238  operator* (const ForceDense<Derived> & phi)
239  { return phi.angular(); }
240 
241  /* [CRBA] MatrixBase operator* (Constraint::Transpose S, ForceSet::Block) */
242  template<typename MatrixDerived>
243  const typename SizeDepType<3>::RowsReturn<MatrixDerived>::ConstType
244  operator*(const Eigen::MatrixBase<MatrixDerived> & F) const
245  {
246  assert(F.rows()==6);
247  return F.derived().template middleRows<3>(Inertia::ANGULAR);
248  }
249  };
250 
251  TransposeConst transpose() const { return TransposeConst(); }
252 
253  DenseBase matrix_impl() const
254  {
255  DenseBase S;
256  S.template block <3,3>(LINEAR,0).setZero();
257  S.template block <3,3>(ANGULAR,0).setIdentity();
258  return S;
259  }
260 
261  template<typename S1, int O1>
262  Eigen::Matrix<S1,6,3,O1> se3Action(const SE3Tpl<S1,O1> & m) const
263  {
264  Eigen::Matrix<S1,6,3,O1> X_subspace;
265  cross(m.translation(),m.rotation(),X_subspace.template block<3,3>(LINEAR,0));
266  X_subspace.template block<3,3>(ANGULAR,0) = m.rotation();
267 
268  return X_subspace;
269  }
270 
271  template<typename MotionDerived>
272  DenseBase motionAction(const MotionDense<MotionDerived> & m) const
273  {
274  const typename MotionDerived::ConstLinearType v = m.linear();
275  const typename MotionDerived::ConstAngularType w = m.angular();
276 
277  DenseBase res;
278  skew(v,res.template middleRows<3>(LINEAR));
279  skew(w,res.template middleRows<3>(ANGULAR));
280 
281  return res;
282  }
283 
284  }; // struct ConstraintSphericalTpl
285 
286  template<typename MotionDerived, typename S2, int O2>
287  inline typename MotionDerived::MotionPlain
288  operator^(const MotionDense<MotionDerived> & m1,
289  const MotionSphericalTpl<S2,O2> & m2)
290  {
291  return m2.motionAction(m1);
292  }
293 
294  /* [CRBA] ForceSet operator* (Inertia Y,Constraint S) */
295  template<typename S1, int O1, typename S2, int O2>
296  inline Eigen::Matrix<S2,6,3,O2>
297  operator*(const InertiaTpl<S1,O1> & Y,
299  {
300  typedef InertiaTpl<S1,O1> Inertia;
301  typedef typename Inertia::Symmetric3 Symmetric3;
302  Eigen::Matrix<S2,6,3,O2> M;
303  // M.block <3,3> (Inertia::LINEAR, 0) = - Y.mass () * skew(Y.lever ());
304  M.template block<3,3>(Inertia::LINEAR,0) = alphaSkew(-Y.mass(), Y.lever());
305  M.template block<3,3>(Inertia::ANGULAR,0) = (Y.inertia() - typename Symmetric3::AlphaSkewSquare(Y.mass(), Y.lever())).matrix();
306  return M;
307  }
308 
309  /* [ABA] Y*S operator*/
310  template<typename M6Like, typename S2, int O2>
311  inline typename SizeDepType<3>::ColsReturn<M6Like>::ConstType
312  operator*(const Eigen::MatrixBase<M6Like> & Y,
314  {
315  typedef ConstraintSphericalTpl<S2,O2> Constraint;
316  return Y.derived().template middleCols<3>(Constraint::ANGULAR);
317  }
318 
319  namespace internal
320  {
321  template<typename S1, int O1>
322  struct SE3GroupAction< ConstraintSphericalTpl<S1,O1> >
323  { typedef Eigen::Matrix<S1,6,3,O1> ReturnType; };
324 
325  template<typename S1, int O1, typename MotionDerived>
326  struct MotionAlgebraAction< ConstraintSphericalTpl<S1,O1>,MotionDerived >
327  { typedef Eigen::Matrix<S1,6,3,O1> ReturnType; };
328  }
329 
330  template<typename Scalar, int Options> struct JointSphericalTpl;
331 
332  template<typename _Scalar, int _Options>
333  struct traits< JointSphericalTpl<_Scalar,_Options> >
334  {
335  enum {
336  NQ = 4,
337  NV = 3
338  };
339  typedef _Scalar Scalar;
340  enum { Options = _Options };
347  typedef Eigen::Matrix<Scalar,6,NV,Options> F_t;
348 
349  // [ABA]
350  typedef Eigen::Matrix<Scalar,6,NV,Options> U_t;
351  typedef Eigen::Matrix<Scalar,NV,NV,Options> D_t;
352  typedef Eigen::Matrix<Scalar,6,NV,Options> UD_t;
353 
354  PINOCCHIO_JOINT_DATA_BASE_ACCESSOR_DEFAULT_RETURN_TYPE
355 
356  typedef Eigen::Matrix<Scalar,NQ,1,Options> ConfigVector_t;
357  typedef Eigen::Matrix<Scalar,NV,1,Options> TangentVector_t;
358  };
359 
360  template<typename Scalar, int Options>
361  struct traits< JointDataSphericalTpl<Scalar,Options> >
363 
364  template<typename Scalar, int Options>
365  struct traits< JointModelSphericalTpl<Scalar,Options> >
367 
368  template<typename _Scalar, int _Options>
369  struct JointDataSphericalTpl : public JointDataBase< JointDataSphericalTpl<_Scalar,_Options> >
370  {
371  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
372 
374  PINOCCHIO_JOINT_DATA_TYPEDEF_TEMPLATE;
375  PINOCCHIO_JOINT_DATA_BASE_DEFAULT_ACCESSOR
376 
377  Constraint_t S;
378  Transformation_t M;
379  Motion_t v;
380  Bias_t c;
381 
382  F_t F;
383 
384  // [ABA] specific data
385  U_t U;
386  D_t Dinv;
387  UD_t UDinv;
388 
389  JointDataSphericalTpl () : M(1), U(), Dinv(), UDinv() {}
390 
391  static std::string classname() { return std::string("JointDataSpherical"); }
392  std::string shortname() const { return classname(); }
393 
394  }; // struct JointDataSphericalTpl
395 
396  PINOCCHIO_JOINT_CAST_TYPE_SPECIALIZATION(JointModelSphericalTpl);
397  template<typename _Scalar, int _Options>
399  : public JointModelBase< JointModelSphericalTpl<_Scalar,_Options> >
400  {
401  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
402 
404  PINOCCHIO_JOINT_TYPEDEF_TEMPLATE;
405 
407  using Base::id;
408  using Base::idx_q;
409  using Base::idx_v;
410  using Base::setIndexes;
411 
412  JointDataDerived createData() const { return JointDataDerived(); }
413 
414  template<typename ConfigVectorLike>
415  inline void forwardKinematics(Transformation_t & M, const Eigen::MatrixBase<ConfigVectorLike> & q_joint) const
416  {
417  EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(ConfigVector_t,ConfigVectorLike);
418  typedef typename Eigen::Quaternion<typename ConfigVectorLike::Scalar,PINOCCHIO_EIGEN_PLAIN_TYPE(ConfigVectorLike)::Options> Quaternion;
419  typedef Eigen::Map<const Quaternion> ConstQuaternionMap;
420 
421  ConstQuaternionMap quat(q_joint.derived().data());
422  //assert(math::fabs(quat.coeffs().squaredNorm()-1.) <= sqrt(Eigen::NumTraits<typename V::Scalar>::epsilon())); TODO: check validity of the rhs precision
423  assert(math::fabs(quat.coeffs().squaredNorm()-1.) <= 1e-4);
424 
425  M.rotation(quat.matrix());
426  M.translation().setZero();
427  }
428 
429  template<typename QuaternionDerived>
430  void calc(JointDataDerived & data,
431  const typename Eigen::QuaternionBase<QuaternionDerived> & quat) const
432  {
433  data.M.rotation(quat.matrix());
434  }
435 
436  template<typename ConfigVector>
437  EIGEN_DONT_INLINE
438  void calc(JointDataDerived & data,
439  const typename Eigen::PlainObjectBase<ConfigVector> & qs) const
440  {
441  typedef typename Eigen::Quaternion<typename ConfigVector::Scalar,ConfigVector::Options> Quaternion;
442  typedef Eigen::Map<const Quaternion> ConstQuaternionMap;
443 
444  ConstQuaternionMap quat(qs.template segment<NQ>(idx_q()).data());
445  calc(data,quat);
446  }
447 
448  template<typename ConfigVector>
449  EIGEN_DONT_INLINE
450  void calc(JointDataDerived & data,
451  const typename Eigen::MatrixBase<ConfigVector> & qs) const
452  {
453  typedef typename Eigen::Quaternion<Scalar,Options> Quaternion;
454 
455  const Quaternion quat(qs.template segment<NQ>(idx_q()));
456  calc(data,quat);
457  }
458 
459  template<typename ConfigVector, typename TangentVector>
460  void calc(JointDataDerived & data,
461  const typename Eigen::MatrixBase<ConfigVector> & qs,
462  const typename Eigen::MatrixBase<TangentVector> & vs) const
463  {
464  calc(data,qs.derived());
465 
466  data.v() = vs.template segment<NV>(idx_v());
467  }
468 
469  template<typename Matrix6Like>
470  void calc_aba(JointDataDerived & data, const Eigen::MatrixBase<Matrix6Like> & I, const bool update_I) const
471  {
472  data.U = I.template block<6,3>(0,Inertia::ANGULAR);
473 
474  // compute inverse
475  data.Dinv.setIdentity();
476  data.U.template middleRows<3>(Inertia::ANGULAR).llt().solveInPlace(data.Dinv);
477 
478  data.UDinv.template middleRows<3>(Inertia::ANGULAR).setIdentity(); // can be put in data constructor
479  data.UDinv.template middleRows<3>(Inertia::LINEAR).noalias() = data.U.template block<3,3>(Inertia::LINEAR, 0) * data.Dinv;
480 
481  if (update_I)
482  {
483  Matrix6Like & I_ = PINOCCHIO_EIGEN_CONST_CAST(Matrix6Like,I);
484  I_.template block<3,3>(Inertia::LINEAR,Inertia::LINEAR)
485  -= data.UDinv.template middleRows<3>(Inertia::LINEAR) * I_.template block<3,3> (Inertia::ANGULAR, Inertia::LINEAR);
486  I_.template block<6,3>(0,Inertia::ANGULAR).setZero();
487  I_.template block<3,3>(Inertia::ANGULAR,Inertia::LINEAR).setZero();
488  }
489  }
490 
491  Scalar finiteDifferenceIncrement() const
492  {
493  using math::sqrt;
494  return 2.*sqrt(sqrt(Eigen::NumTraits<Scalar>::epsilon()));
495  }
496 
497  static std::string classname() { return std::string("JointModelSpherical"); }
498  std::string shortname() const { return classname(); }
499 
501  template<typename NewScalar>
503  {
505  ReturnType res;
506  res.setIndexes(id(),idx_q(),idx_v());
507  return res;
508  }
509 
510 
511  }; // struct JointModelSphericalTpl
512 
513 } // namespace pinocchio
514 
515 #include <boost/type_traits.hpp>
516 
517 namespace boost
518 {
519  template<typename Scalar, int Options>
520  struct has_nothrow_constructor< ::pinocchio::JointModelSphericalTpl<Scalar,Options> >
521  : public integral_constant<bool,true> {};
522 
523  template<typename Scalar, int Options>
524  struct has_nothrow_copy< ::pinocchio::JointModelSphericalTpl<Scalar,Options> >
525  : public integral_constant<bool,true> {};
526 
527  template<typename Scalar, int Options>
528  struct has_nothrow_constructor< ::pinocchio::JointDataSphericalTpl<Scalar,Options> >
529  : public integral_constant<bool,true> {};
530 
531  template<typename Scalar, int Options>
532  struct has_nothrow_copy< ::pinocchio::JointDataSphericalTpl<Scalar,Options> >
533  : public integral_constant<bool,true> {};
534 }
535 
536 #endif // ifndef __pinocchio_joint_spherical_hpp__
int idx_q(const JointModelTpl< Scalar, Options, JointCollectionTpl > &jmodel)
Visit a JointModelTpl through JointIdxQVisitor to get the index in the full model configuration space...
int idx_v(const JointModelTpl< Scalar, Options, JointCollectionTpl > &jmodel)
Visit a JointModelTpl through JointIdxVVisitor to get the index in the full model tangent space corre...
JointDataTpl< Scalar, Options, JointCollectionTpl > createData(const JointModelTpl< Scalar, Options, JointCollectionTpl > &jmodel)
Visit a JointModelTpl through CreateData visitor to create a JointDataTpl.
ModelTpl< Scalar, Options, JointCollectionTpl >::TangentVectorType finiteDifferenceIncrement(const ModelTpl< Scalar, Options, JointCollectionTpl > &model)
Computes the finite difference increments for each degree of freedom according to the current joint c...
void forwardKinematics(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< ConfigVectorType > &q)
Update the joint placements according to the current joint configuration.
std::string shortname(const JointModelTpl< Scalar, Options, JointCollectionTpl > &jmodel)
Visit a JointModelTpl through JointShortnameVisitor to get the shortname of the derived joint model...
void cross(const Eigen::MatrixBase< Vector3 > &v, const Eigen::MatrixBase< Matrix3xIn > &Min, const Eigen::MatrixBase< Matrix3xOut > &Mout)
Applies the cross product onto the columns of M.
Definition: skew.hpp:211
ConstAngularType angular() const
Return the angular part of the force vector.
Definition: force-base.hpp:40
JointModelSphericalTpl< NewScalar, Options > cast() const
Main pinocchio namespace.
Definition: treeview.dox:24
void alphaSkew(const Scalar alpha, const Eigen::MatrixBase< Vector3 > &v, const Eigen::MatrixBase< Matrix3 > &M)
Computes the skew representation of a given 3d vector multiplied by a given scalar. i.e. the antisymmetric matrix representation of the cross product operator ( )
Definition: skew.hpp:124
Common traits structure to fully define base classes for CRTP.
Definition: spatial/fwd.hpp:29
void skew(const Eigen::MatrixBase< Vector3 > &v, const Eigen::MatrixBase< Matrix3 > &M)
Computes the skew representation of a given 3d vector, i.e. the antisymmetric matrix representation o...
Definition: skew.hpp:21
void calc_aba(const JointModelTpl< Scalar, Options, JointCollectionTpl > &jmodel, JointDataTpl< Scalar, Options, JointCollectionTpl > &jdata, const Eigen::MatrixBase< Matrix6Type > &I, const bool update_I)
Visit a JointModelTpl and the corresponding JointDataTpl through JointCalcAbaVisitor to...