pinocchio  UNKNOWN
joint-revolute.hpp
1 //
2 // Copyright (c) 2015-2018 CNRS
3 // Copyright (c) 2015-2016 Wandercraft, 86 rue de Paris 91400 Orsay, France.
4 //
5 // This file is part of Pinocchio
6 // Pinocchio is free software: you can redistribute it
7 // and/or modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation, either version
9 // 3 of the License, or (at your option) any later version.
10 //
11 // Pinocchio is distributed in the hope that it will be
12 // useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // General Lesser Public License for more details. You should have
15 // received a copy of the GNU Lesser General Public License along with
16 // Pinocchio If not, see
17 // <http://www.gnu.org/licenses/>.
18 
19 #ifndef __se3_joint_revolute_hpp__
20 #define __se3_joint_revolute_hpp__
21 
22 #include "pinocchio/math/sincos.hpp"
23 #include "pinocchio/spatial/inertia.hpp"
24 #include "pinocchio/multibody/constraint.hpp"
25 #include "pinocchio/multibody/joint/joint-base.hpp"
26 #include "pinocchio/spatial/spatial-axis.hpp"
27 #include "pinocchio/utils/axis-label.hpp"
28 
29 namespace se3
30 {
31 
32  template<typename Scalar, int Options, int axis> struct MotionRevoluteTpl;
33 
34  namespace revolute
35  {
36  template<int axis>
38  {
39  double w;
40  CartesianVector3(const double w) : w(w) {}
41  CartesianVector3() : w(NAN) {}
42 
43  Eigen::Vector3d vector() const;
44  operator Eigen::Vector3d () const { return vector(); }
45  }; // struct CartesianVector3
46  template<> inline Eigen::Vector3d CartesianVector3<0>::vector() const { return Eigen::Vector3d(w,0,0); }
47  template<> inline Eigen::Vector3d CartesianVector3<1>::vector() const { return Eigen::Vector3d(0,w,0); }
48  template<> inline Eigen::Vector3d CartesianVector3<2>::vector() const { return Eigen::Vector3d(0,0,w); }
49 
50  inline Eigen::Vector3d operator+ (const Eigen::Vector3d & w1,const CartesianVector3<0> & wx)
51  { return Eigen::Vector3d(w1[0]+wx.w,w1[1],w1[2]); }
52  inline Eigen::Vector3d operator+ (const Eigen::Vector3d & w1,const CartesianVector3<1> & wy)
53  { return Eigen::Vector3d(w1[0],w1[1]+wy.w,w1[2]); }
54  inline Eigen::Vector3d operator+ (const Eigen::Vector3d & w1,const CartesianVector3<2> & wz)
55  { return Eigen::Vector3d(w1[0],w1[1],w1[2]+wz.w); }
56  } // namespace revolute
57 
58 
59  template<typename _Scalar, int _Options, int axis>
60  struct traits< MotionRevoluteTpl<_Scalar,_Options,axis> >
61  {
62  typedef _Scalar Scalar;
63  enum { Options = _Options };
64  typedef Eigen::Matrix<Scalar,3,1,Options> Vector3;
65  typedef Eigen::Matrix<Scalar,6,1,Options> Vector6;
66  typedef Eigen::Matrix<Scalar,6,6,Options> Matrix6;
67  typedef typename EIGEN_REF_CONSTTYPE(Vector6) ToVectorConstReturnType;
68  typedef typename EIGEN_REF_TYPE(Vector6) ToVectorReturnType;
69  typedef Vector3 AngularType;
70  typedef Vector3 LinearType;
71  typedef const Vector3 ConstAngularType;
72  typedef const Vector3 ConstLinearType;
73  typedef Matrix6 ActionMatrixType;
75  enum {
76  LINEAR = 0,
77  ANGULAR = 3
78  };
79  }; // traits MotionRevoluteTpl
80 
81  template<typename _Scalar, int _Options, int axis>
82  struct MotionRevoluteTpl : MotionBase< MotionRevoluteTpl<_Scalar,_Options,axis> >
83  {
84  MOTION_TYPEDEF_TPL(MotionRevoluteTpl);
85  typedef SpatialAxis<axis+ANGULAR> Axis;
86 
87  MotionRevoluteTpl() : w(NAN) {}
88 
89  template<typename OtherScalar>
90  MotionRevoluteTpl(const OtherScalar & w) : w(w) {}
91 
92  operator MotionPlain() const { return Axis() * w; }
93 
94  template<typename MotionDerived>
95  void addTo(MotionDense<MotionDerived> & v) const
96  {
97  typedef typename MotionDense<MotionDerived>::Scalar OtherScalar;
98  v.angular()[axis] += (OtherScalar)w;
99  }
100 
101  // data
102  Scalar w;
103  }; // struct MotionRevoluteTpl
104 
105  template<typename S1, int O1, int axis, typename MotionDerived>
106  typename MotionDerived::MotionPlain
107  operator+(const MotionRevoluteTpl<S1,O1,axis> & m1,
108  const MotionDense<MotionDerived> & m2)
109  {
110  typename MotionDerived::MotionPlain res(m2);
111  res += m1;
112  return res;
113  }
114 
115  template<typename Scalar, int Options, int axis> struct ConstraintRevoluteTpl;
116 
117  namespace internal
118  {
119  template<typename Scalar, int Options, int axis>
120  struct SE3GroupAction< ConstraintRevoluteTpl<Scalar,Options,axis> >
121  { typedef Eigen::Matrix<Scalar,6,1,Options> ReturnType; };
122 
123  template<typename Scalar, int Options, int axis, typename MotionDerived>
124  struct MotionAlgebraAction< ConstraintRevoluteTpl<Scalar,Options,axis>, MotionDerived >
125  { typedef Eigen::Matrix<Scalar,6,1,Options> ReturnType; };
126  }
127 
128  template<typename _Scalar, int _Options, int axis>
129  struct traits< ConstraintRevoluteTpl<_Scalar,_Options,axis> >
130  {
131  typedef _Scalar Scalar;
132  enum { Options = _Options };
133  typedef Eigen::Matrix<Scalar,3,1,Options> Vector3;
134  typedef Eigen::Matrix<Scalar,4,1,Options> Vector4;
135  typedef Eigen::Matrix<Scalar,6,1,Options> Vector6;
136  typedef Eigen::Matrix<Scalar,3,3,Options> Matrix3;
137  typedef Eigen::Matrix<Scalar,4,4,Options> Matrix4;
138  typedef Eigen::Matrix<Scalar,6,6,Options> Matrix6;
139  typedef Matrix3 Angular_t;
140  typedef Vector3 Linear_t;
141  typedef const Matrix3 ConstAngular_t;
142  typedef const Vector3 ConstLinear_t;
143  typedef Matrix6 ActionMatrix_t;
144  typedef Eigen::Quaternion<Scalar,0> Quaternion_t;
145  typedef SE3Tpl<Scalar,Options> SE3;
149  enum {
150  LINEAR = 0,
151  ANGULAR = 3
152  };
153  typedef Eigen::Matrix<Scalar,1,1,Options> JointMotion;
154  typedef Eigen::Matrix<Scalar,1,1,Options> JointForce;
155  typedef Eigen::Matrix<Scalar,6,1,Options> DenseBase;
156  typedef DenseBase MatrixReturnType;
157  typedef const DenseBase ConstMatrixReturnType;
158  }; // traits ConstraintRevoluteTpl
159 
160  template<typename _Scalar, int _Options, int axis>
161  struct ConstraintRevoluteTpl : ConstraintBase< ConstraintRevoluteTpl<_Scalar,_Options,axis> >
162  {
163  SPATIAL_TYPEDEF_TEMPLATE(ConstraintRevoluteTpl);
164  enum { NV = 1, Options = 0 };
165  typedef typename traits<ConstraintRevoluteTpl>::JointMotion JointMotion;
166  typedef typename traits<ConstraintRevoluteTpl>::JointForce JointForce;
167  typedef typename traits<ConstraintRevoluteTpl>::DenseBase DenseBase;
168  typedef SpatialAxis<ANGULAR+axis> Axis;
169 
170  template<typename Vector1Like>
172  operator*(const Eigen::MatrixBase<Vector1Like> & v) const
174 
175  template<typename S1, int O1>
176  Eigen::Matrix<Scalar,6,1,Options>
177  se3Action(const SE3Tpl<S1,O1> & m) const
178  {
179  Eigen::Matrix<Scalar,6,1,Options> res;
180  res.template head<3>() = m.translation().cross(m.rotation().col(axis));
181  res.template tail<3>() = m.rotation().col(axis);
182  return res;
183  }
184 
185  int nv_impl() const { return NV; }
186 
188  {
189  const ConstraintRevoluteTpl & ref;
190  TransposeConst(const ConstraintRevoluteTpl & ref) : ref(ref) {}
191 
192  template<typename Derived>
193  typename ForceDense<Derived>::ConstAngularType::template ConstFixedSegmentReturnType<1>::Type
194  operator* (const ForceDense<Derived> & f) const
195  { return f.angular().template segment<1>(axis); }
196 
198  template<typename D>
199  typename Eigen::MatrixBase<D>::ConstRowXpr
200  operator*(const Eigen::MatrixBase<D> & F) const
201  {
202  assert(F.rows()==6);
203  return F.row(ANGULAR + axis);
204  }
205  }; // struct TransposeConst
206 
207  TransposeConst transpose() const { return TransposeConst(*this); }
208 
209  /* CRBA joint operators
210  * - ForceSet::Block = ForceSet
211  * - ForceSet operator* (Inertia Y,Constraint S)
212  * - MatrixBase operator* (Constraint::Transpose S, ForceSet::Block)
213  * - SE3::act(ForceSet::Block)
214  */
215  DenseBase matrix_impl() const
216  {
217  DenseBase S;
219  v << Axis();
220  return S;
221  }
222 
223  template<typename MotionDerived>
224  DenseBase motionAction(const MotionDense<MotionDerived> & m) const
225  {
226  DenseBase res;
227  MotionRef<DenseBase> v(res);
228  v = m.cross(Axis());
229  return res;
230  }
231  }; // struct ConstraintRevoluteTpl
232 
233  template<typename MotionDerived, typename S2, int O2>
234  inline typename MotionDerived::MotionPlain
235  operator^(const MotionDense<MotionDerived> & m1, const MotionRevoluteTpl<S2,O2,0>& m2)
236  {
237  /* nu1^nu2 = ( v1^w2+w1^v2, w1^w2 )
238  * nu1^(0,w2) = ( v1^w2 , w1^w2 )
239  * (x,y,z)^(w,0,0) = ( 0,zw,-yw )
240  * nu1^(0,wx) = ( 0,vz1 wx,-vy1 wx, 0,wz1 wx,-wy1 wx)
241  */
242  typedef typename MotionDerived::MotionPlain ReturnType;
243  const typename MotionDerived::ConstLinearType & v = m1.linear();
244  const typename MotionDerived::ConstAngularType & w = m1.angular();
245  const S2 & wx = m2.w;
246  return ReturnType(typename ReturnType::Vector3(0,v[2]*wx,-v[1]*wx),
247  typename ReturnType::Vector3(0,w[2]*wx,-w[1]*wx)
248  );
249  }
250 
251  template<typename MotionDerived, typename S2, int O2>
252  inline typename MotionDerived::MotionPlain
253  operator^(const MotionDense<MotionDerived> & m1, const MotionRevoluteTpl<S2,O2,1>& m2)
254  {
255  /* nu1^nu2 = ( v1^w2+w1^v2, w1^w2 )
256  * nu1^(0,w2) = ( v1^w2 , w1^w2 )
257  * (x,y,z)^(0,w,0) = ( -z,0,x )
258  * nu1^(0,wx) = ( -vz1 wx,0,vx1 wx, -wz1 wx,0,wx1 wx)
259  */
260  typedef typename MotionDerived::MotionPlain ReturnType;
261  const typename MotionDerived::ConstLinearType & v = m1.linear();
262  const typename MotionDerived::ConstAngularType & w = m1.angular();
263  const S2 & wx = m2.w;
264  return ReturnType(typename ReturnType::Vector3(-v[2]*wx,0, v[0]*wx),
265  typename ReturnType::Vector3(-w[2]*wx,0, w[0]*wx)
266  );
267  }
268 
269  template<typename MotionDerived, typename S2, int O2>
270  inline typename MotionDerived::MotionPlain
271  operator^(const MotionDense<MotionDerived> & m1, const MotionRevoluteTpl<S2,O2,2>& m2)
272  {
273  /* nu1^nu2 = ( v1^w2+w1^v2, w1^w2 )
274  * nu1^(0,w2) = ( v1^w2 , w1^w2 )
275  * (x,y,z)^(0,0,w) = ( y,-x,0 )
276  * nu1^(0,wx) = ( vy1 wx,-vx1 wx,0, wy1 wx,-wx1 wx,0 )
277  */
278  typedef typename MotionDerived::MotionPlain ReturnType;
279  const typename MotionDerived::ConstLinearType & v = m1.linear();
280  const typename MotionDerived::ConstAngularType & w = m1.angular();
281  const S2 & wx = m2.w;
282  return ReturnType(typename ReturnType::Vector3(v[1]*wx,-v[0]*wx,0),
283  typename ReturnType::Vector3(w[1]*wx,-w[0]*wx,0)
284  );
285  }
286 
287  template<typename Scalar, int Options, int axis>
289  {
290  template<typename S1, typename S2, typename Matrix3Like>
291  static void cartesianRotation(const S1 & ca, const S2 & sa,
292  const Eigen::MatrixBase<Matrix3Like> & res);
293  };
294 
295  template<typename Scalar, int Options>
296  struct JointRevoluteTpl<Scalar,Options,0>
297  {
298  template<typename S1, typename S2, typename Matrix3Like>
299  static void cartesianRotation(const S1 & ca, const S2 & sa,
300  const Eigen::MatrixBase<Matrix3Like> & res)
301  {
302  Matrix3Like & res_ = const_cast<Matrix3Like &>(res.derived());
303  typedef typename Matrix3Like::Scalar OtherScalar;
304  res_ <<
305  OtherScalar(1), OtherScalar(0), OtherScalar(0),
306  OtherScalar(0), ca, -sa,
307  OtherScalar(0), sa, ca;
308  }
309  };
310 
311  template<typename Scalar, int Options>
312  struct JointRevoluteTpl<Scalar,Options,1>
313  {
314  template<typename S1, typename S2, typename Matrix3Like>
315  static void cartesianRotation(const S1 & ca, const S2 & sa,
316  const Eigen::MatrixBase<Matrix3Like> & res)
317  {
318  Matrix3Like & res_ = const_cast<Matrix3Like &>(res.derived());
319  typedef typename Matrix3Like::Scalar OtherScalar;
320  res_ <<
321  ca, OtherScalar(0), sa,
322  OtherScalar(0), OtherScalar(1), OtherScalar(0),
323  -sa, OtherScalar(0), ca;
324  }
325  };
326 
327  template<typename Scalar, int Options>
328  struct JointRevoluteTpl<Scalar,Options,2>
329  {
330  template<typename S1, typename S2, typename Matrix3Like>
331  static void cartesianRotation(const S1 & ca, const S2 & sa,
332  const Eigen::MatrixBase<Matrix3Like> & res)
333  {
334  Matrix3Like & res_ = const_cast<Matrix3Like &>(res.derived());
335  typedef typename Matrix3Like::Scalar OtherScalar;
336  res_ <<
337  ca, -sa, OtherScalar(0),
338  sa, ca, OtherScalar(0),
339  OtherScalar(0), OtherScalar(0), OtherScalar(1);
340  }
341  };
342 
343  /* [CRBA] ForceSet operator* (Inertia Y,Constraint S) */
344  template<typename S1, int O1, typename S2, int O2>
345  inline Eigen::Matrix<S2,6,1,O2>
346  operator*(const InertiaTpl<S1,O1> & Y,const ConstraintRevoluteTpl<S2,O2,0> &)
347  {
348  typedef InertiaTpl<S1,O1> Inertia;
349  /* Y(:,3) = ( 0,-z, y, I00+yy+zz, I01-xy , I02-xz ) */
350  const S1
351  &m = Y.mass(),
352  &x = Y.lever()[0],
353  &y = Y.lever()[1],
354  &z = Y.lever()[2];
355  const typename Inertia::Symmetric3 & I = Y.inertia();
356 
357  Eigen::Matrix<S2,6,1,O2> res;
358  res << 0.0,-m*z,m*y,
359  I(0,0)+m*(y*y+z*z),
360  I(0,1)-m*x*y,
361  I(0,2)-m*x*z ;
362  return res;
363  }
364  /* [CRBA] ForceSet operator* (Inertia Y,Constraint S) */
365  template<typename S1, int O1, typename S2, int O2>
366  inline Eigen::Matrix<S2,6,1,O2>
367  operator*(const InertiaTpl<S1,O1> & Y,const ConstraintRevoluteTpl<S2,O2,1> &)
368  {
369  typedef InertiaTpl<S1,O1> Inertia;
370  /* Y(:,4) = ( z, 0,-x, I10-xy , I11+xx+zz, I12-yz ) */
371  const S1
372  &m = Y.mass(),
373  &x = Y.lever()[0],
374  &y = Y.lever()[1],
375  &z = Y.lever()[2];
376  const typename Inertia::Symmetric3 & I = Y.inertia();
377  Eigen::Matrix<S2,6,1,O2> res;
378  res << m*z,0,-m*x,
379  I(1,0)-m*x*y,
380  I(1,1)+m*(x*x+z*z),
381  I(1,2)-m*y*z ;
382  return res;
383  }
384  /* [CRBA] ForceSet operator* (Inertia Y,Constraint S) */
385  template<typename S1, int O1, typename S2, int O2>
386  inline Eigen::Matrix<S2,6,1,O2>
387  operator*(const InertiaTpl<S1,O1> & Y,const ConstraintRevoluteTpl<S2,O2,2> &)
388  {
389  typedef InertiaTpl<S1,O1> Inertia;
390  /* Y(:,5) = (-y, x, 0, I20-xz , I21-yz , I22+xx+yy) */
391  const S1
392  &m = Y.mass(),
393  &x = Y.lever()[0],
394  &y = Y.lever()[1],
395  &z = Y.lever()[2];
396  const typename Inertia::Symmetric3 & I = Y.inertia();
397  Eigen::Matrix<S2,6,1,O2> res; res << -m*y,m*x,0,
398  I(2,0)-m*x*z,
399  I(2,1)-m*y*z,
400  I(2,2)+m*(x*x+y*y) ;
401  return res;
402  }
403 
404  /* [ABA] I*S operator (Inertia Y,Constraint S) */
405  template<typename M6Like, typename S2, int O2,int axis>
406  inline const typename M6Like::ConstColXpr
407  operator*(const Eigen::MatrixBase<M6Like> & Y, const ConstraintRevoluteTpl<S2,O2,axis> &)
408  {
409  EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(M6Like,6,6);
410  return Y.col(Inertia::ANGULAR + axis);
411  }
412 
413  template<typename _Scalar, int _Options, int axis>
414  struct traits< JointRevoluteTpl<_Scalar,_Options,axis> >
415  {
416  enum {
417  NQ = 1,
418  NV = 1
419  };
420  typedef _Scalar Scalar;
421  enum { Options = _Options };
427  typedef BiasZero Bias_t;
428  typedef Eigen::Matrix<Scalar,6,NV,Options> F_t;
429 
430  // [ABA]
431  typedef Eigen::Matrix<Scalar,6,NV,Options> U_t;
432  typedef Eigen::Matrix<Scalar,NV,NV,Options> D_t;
433  typedef Eigen::Matrix<Scalar,6,NV,Options> UD_t;
434 
435  typedef Eigen::Matrix<Scalar,NQ,1,Options> ConfigVector_t;
436  typedef Eigen::Matrix<Scalar,NV,1,Options> TangentVector_t;
437  };
438 
439  template<typename Scalar, int Options, int axis>
440  struct traits< JointDataRevoluteTpl<Scalar,Options,axis> >
442 
443  template<typename Scalar, int Options, int axis>
444  struct traits< JointModelRevoluteTpl<Scalar,Options,axis> >
446 
447  template<typename _Scalar, int _Options, int axis>
448  struct JointDataRevoluteTpl : public JointDataBase< JointDataRevoluteTpl<_Scalar,_Options,axis> >
449  {
451  SE3_JOINT_TYPEDEF_TEMPLATE;
452 
453  Constraint_t S;
454  Transformation_t M;
455  Motion_t v;
456  Bias_t c;
457  F_t F;
458 
459  // [ABA] specific data
460  U_t U;
461  D_t Dinv;
462  UD_t UDinv;
463 
464  JointDataRevoluteTpl() : M(1), U(), Dinv(), UDinv()
465  {}
466 
467  }; // struct JointDataRevoluteTpl
468 
469  template<typename _Scalar, int _Options, int axis>
470  struct JointModelRevoluteTpl : public JointModelBase< JointModelRevoluteTpl<_Scalar,_Options,axis> >
471  {
473  SE3_JOINT_TYPEDEF_TEMPLATE;
474 
479 
480  JointDataDerived createData() const { return JointDataDerived(); }
481 
482  template<typename ConfigVector>
483  void calc(JointDataDerived & data,
484  const typename Eigen::MatrixBase<ConfigVector> & qs) const
485  {
486  EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(ConfigVector_t,ConfigVector);
487  typedef typename ConfigVector::Scalar OtherScalar;
488 
489  const OtherScalar & q = qs[idx_q()];
490  OtherScalar ca,sa; SINCOS(q,&sa,&ca);
491  JointDerived::cartesianRotation(ca,sa,data.M.rotation());
492  }
493 
494  template<typename ConfigVector, typename TangentVector>
495  void calc(JointDataDerived & data,
496  const typename Eigen::MatrixBase<ConfigVector> & qs,
497  const typename Eigen::MatrixBase<TangentVector> & vs) const
498  {
499  EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(TangentVector_t,TangentVector);
500  calc(data,qs.derived());
501 
502  data.v.w = (Scalar)vs[idx_v()];;
503  }
504 
505  template<typename S2, int O2>
506  void calc_aba(JointDataDerived & data, Eigen::Matrix<S2,6,6,O2> & I, const bool update_I) const
507  {
508  data.U = I.col(Inertia::ANGULAR + axis);
509  data.Dinv[0] = Scalar(1)/I(Inertia::ANGULAR + axis,Inertia::ANGULAR + axis);
510  data.UDinv.noalias() = data.U * data.Dinv[0];
511 
512  if (update_I)
513  I -= data.UDinv * data.U.transpose();
514  }
515 
516  Scalar finiteDifferenceIncrement() const
517  {
518  using std::sqrt;
519  return 2.*sqrt(sqrt(Eigen::NumTraits<Scalar>::epsilon()));
520  }
521 
522  static std::string classname()
523  {
524  return std::string("JointModelR") + axisLabel<axis>();
525  }
526  std::string shortname() const { return classname(); }
527 
528  }; // struct JointModelRevoluteTpl
529 
533 
537 
541 
542 } //namespace se3
543 
544 #endif // ifndef __se3_joint_revolute_hpp__
JointDataVariant createData(const JointModelVariant &jmodel)
Visit a JointModelVariant through CreateData visitor to create a JointDataVariant.
Eigen::MatrixBase< D >::ConstRowXpr operator*(const Eigen::MatrixBase< D > &F) const
[CRBA] MatrixBase operator* (Constraint::Transpose S, ForceSet::Block)
ConstAngularType angular() const
Return the angular part of the force vector.
Definition: force-base.hpp:53
void calc_aba(const JointModelVariant &jmodel, JointDataVariant &jdata, Inertia::Matrix6 &I, const bool update_I)
Visit a JointDataVariant and the corresponding JointModelVariant through JointCalcAbaVisitor to...
std::string shortname(const JointModelVariant &jmodel)
Visit a JointModelVariant through JointShortnameVisitor to get the shortname of the derived joint mod...
int idx_q(const JointModelVariant &jmodel)
Visit a JointModelVariant through JointIdxQVisitor to get the index in the full model configuration s...
Eigen::VectorXd finiteDifferenceIncrement(const Model &model)
Computes the finite difference increments for each degree of freedom according to the current joint c...
int idx_v(const JointModelVariant &jmodel)
Visit a JointModelVariant through JointIdxVVisitor to get the index in the full model tangent space c...