pinocchio  2.1.3
joint-revolute-unaligned.hpp
1 //
2 // Copyright (c) 2015-2018 CNRS
3 // Copyright (c) 2015-2016 Wandercraft, 86 rue de Paris 91400 Orsay, France.
4 //
5 
6 #ifndef __pinocchio_joint_revolute_unaligned_hpp__
7 #define __pinocchio_joint_revolute_unaligned_hpp__
8 
9 #include "pinocchio/fwd.hpp"
10 #include "pinocchio/multibody/joint/joint-base.hpp"
11 #include "pinocchio/multibody/constraint.hpp"
12 #include "pinocchio/spatial/inertia.hpp"
13 
14 namespace pinocchio
15 {
16 
17  template<typename Scalar, int Options=0> struct MotionRevoluteUnalignedTpl;
19 
20  namespace internal
21  {
22  template<typename Scalar, int Options>
23  struct SE3GroupAction< MotionRevoluteUnalignedTpl<Scalar,Options> >
24  {
25  typedef MotionTpl<Scalar,Options> ReturnType;
26  };
27 
28  template<typename Scalar, int Options, typename MotionDerived>
29  struct MotionAlgebraAction< MotionRevoluteUnalignedTpl<Scalar,Options>, MotionDerived>
30  {
31  typedef MotionTpl<Scalar,Options> ReturnType;
32  };
33  }
34 
35  template<typename _Scalar, int _Options>
36  struct traits< MotionRevoluteUnalignedTpl<_Scalar,_Options> >
37  {
38  typedef _Scalar Scalar;
39  enum { Options = _Options };
40  typedef Eigen::Matrix<Scalar,3,1,Options> Vector3;
41  typedef Eigen::Matrix<Scalar,6,1,Options> Vector6;
42  typedef Eigen::Matrix<Scalar,6,6,Options> Matrix6;
43  typedef typename PINOCCHIO_EIGEN_REF_CONST_TYPE(Vector6) ToVectorConstReturnType;
44  typedef typename PINOCCHIO_EIGEN_REF_TYPE(Vector6) ToVectorReturnType;
45  typedef Vector3 AngularType;
46  typedef Vector3 LinearType;
47  typedef const Vector3 ConstAngularType;
48  typedef const Vector3 ConstLinearType;
49  typedef Matrix6 ActionMatrixType;
51  enum {
52  LINEAR = 0,
53  ANGULAR = 3
54  };
55  }; // traits MotionRevoluteUnalignedTpl
56 
57  template<typename _Scalar, int _Options>
58  struct MotionRevoluteUnalignedTpl : MotionBase< MotionRevoluteUnalignedTpl<_Scalar,_Options> >
59  {
60  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
61  MOTION_TYPEDEF_TPL(MotionRevoluteUnalignedTpl);
62 
64 
65  template<typename Vector3Like, typename OtherScalar>
66  MotionRevoluteUnalignedTpl(const Eigen::MatrixBase<Vector3Like> & axis,
67  const OtherScalar & w)
68  : axis(axis)
69  , w(w)
70  {}
71 
72 // operator MotionPlain() const
73 // {
74 // return MotionPlain(MotionPlain::Vector3::Zero(),
75 // axis*w);
76 // }
77 
78  template<typename MotionDerived>
79  void addTo(MotionDense<MotionDerived> & v) const
80  {
81  v.angular() += axis*w;
82  }
83 
84  template<typename Derived>
85  void setTo(MotionDense<Derived> & other) const
86  {
87  other.linear().setZero();
88  other.angular().noalias() = axis*w;
89  }
90 
91  template<typename S2, int O2, typename D2>
92  void se3Action_impl(const SE3Tpl<S2,O2> & m, MotionDense<D2> & v) const
93  {
94  // Angular
95  v.angular().noalias() = w * m.rotation() * axis;
96 
97  // Linear
98  v.linear().noalias() = m.translation().cross(v.angular());
99  }
100 
101  template<typename S2, int O2>
102  MotionPlain se3Action_impl(const SE3Tpl<S2,O2> & m) const
103  {
104  MotionPlain res;
105  se3Action_impl(m,res);
106  return res;
107  }
108 
109  template<typename S2, int O2, typename D2>
110  void se3ActionInverse_impl(const SE3Tpl<S2,O2> & m, MotionDense<D2> & v) const
111  {
112  // Linear
113  // TODO: use v.angular() as temporary variable
114  Vector3 v3_tmp;
115  v3_tmp.noalias() = axis.cross(m.translation());
116  v3_tmp *= w;
117  v.linear().noalias() = m.rotation().transpose() * v3_tmp;
118 
119  // Angular
120  v.angular().noalias() = m.rotation().transpose() * axis;
121  v.angular() *= w;
122  }
123 
124  template<typename S2, int O2>
125  MotionPlain se3ActionInverse_impl(const SE3Tpl<S2,O2> & m) const
126  {
127  MotionPlain res;
128  se3ActionInverse_impl(m,res);
129  return res;
130  }
131 
132  template<typename M1, typename M2>
133  void motionAction(const MotionDense<M1> & v, MotionDense<M2> & mout) const
134  {
135  // Linear
136  mout.linear().noalias() = v.linear().cross(axis);
137  mout.linear() *= w;
138 
139  // Angular
140  mout.angular().noalias() = v.angular().cross(axis);
141  mout.angular() *= w;
142  }
143 
144  template<typename M1>
145  MotionPlain motionAction(const MotionDense<M1> & v) const
146  {
147  MotionPlain res;
148  motionAction(v,res);
149  return res;
150  }
151 
152  // data
153  Vector3 axis;
154  Scalar w;
155 
156  }; // struct MotionRevoluteUnalignedTpl
157 
158  template<typename S1, int O1, typename MotionDerived>
159  inline typename MotionDerived::MotionPlain
160  operator+(const MotionRevoluteUnalignedTpl<S1,O1> & m1, const MotionDense<MotionDerived> & m2)
161  {
162  typename MotionDerived::MotionPlain res(m2);
163  res += m1;
164  return res;
165  }
166 
167  template<typename Scalar, int Options> struct ConstraintRevoluteUnalignedTpl;
168 
169  template<typename _Scalar, int _Options>
170  struct traits< ConstraintRevoluteUnalignedTpl<_Scalar,_Options> >
171  {
172  typedef _Scalar Scalar;
173  enum { Options = _Options };
174  typedef Eigen::Matrix<Scalar,3,1,Options> Vector3;
175  typedef Eigen::Matrix<Scalar,4,1,Options> Vector4;
176  typedef Eigen::Matrix<Scalar,6,1,Options> Vector6;
177  typedef Eigen::Matrix<Scalar,3,3,Options> Matrix3;
178  typedef Eigen::Matrix<Scalar,4,4,Options> Matrix4;
179  typedef Eigen::Matrix<Scalar,6,6,Options> Matrix6;
180  typedef Matrix3 Angular_t;
181  typedef Vector3 Linear_t;
182  typedef const Matrix3 ConstAngular_t;
183  typedef const Vector3 ConstLinear_t;
184  typedef Matrix6 ActionMatrix_t;
185  typedef Eigen::Quaternion<Scalar,Options> Quaternion_t;
186  typedef SE3Tpl<Scalar,Options> SE3;
190  enum {
191  LINEAR = 0,
192  ANGULAR = 3
193  };
195  typedef Eigen::Matrix<Scalar,1,1,Options> JointForce;
196  typedef Eigen::Matrix<Scalar,6,1,Options> DenseBase;
197  typedef DenseBase MatrixReturnType;
198  typedef const DenseBase ConstMatrixReturnType;
199  }; // traits ConstraintRevoluteUnalignedTpl
200 
201  template<typename _Scalar, int _Options>
203  : ConstraintBase< ConstraintRevoluteUnalignedTpl<_Scalar,_Options> >
204  {
205  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
206  SPATIAL_TYPEDEF_TEMPLATE(ConstraintRevoluteUnalignedTpl);
207  enum { NV = 1, Options = _Options };
208 
210  typedef typename traits<ConstraintRevoluteUnalignedTpl>::JointForce JointForce;
211  typedef typename traits<ConstraintRevoluteUnalignedTpl>::DenseBase DenseBase;
212 
214 
215  template<typename Vector3Like>
216  ConstraintRevoluteUnalignedTpl(const Eigen::MatrixBase<Vector3Like> & axis)
217  : axis(axis)
218  {}
219 
220  template<typename Vector1Like>
221  JointMotion __mult__(const Eigen::MatrixBase<Vector1Like> & v) const
222  {
223  EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Vector1Like,1);
224  return JointMotion(axis,v[0]);
225  }
226 
227  template<typename S1, int O1>
228  Eigen::Matrix<Scalar,6,1,Options> se3Action(const SE3Tpl<S1,O1> & m) const
229  {
230  /* X*S = [ R pxR ; 0 R ] [ 0 ; a ] = [ px(Ra) ; Ra ] */
231  Eigen::Matrix<Scalar,6,1,Options> res;
232  res.template segment<3>(ANGULAR).noalias() = m.rotation() * axis;
233  res.template segment<3>(LINEAR).noalias() = m.translation().cross(res.template segment<3>(ANGULAR));
234  return res;
235  }
236 
237  int nv_impl() const { return NV; }
238 
240  {
241  const ConstraintRevoluteUnalignedTpl & ref;
242  TransposeConst(const ConstraintRevoluteUnalignedTpl & ref) : ref(ref) {}
243 
244  template<typename Derived>
245  Eigen::Matrix<
246  typename PINOCCHIO_EIGEN_DOT_PRODUCT_RETURN_TYPE(Vector3,typename ForceDense<Derived>::ConstAngularType),
247  1,1>
248  operator*(const ForceDense<Derived> & f) const
249  {
250  typedef Eigen::Matrix<
251  typename PINOCCHIO_EIGEN_DOT_PRODUCT_RETURN_TYPE(Vector3,typename ForceDense<Derived>::ConstAngularType),
252  1,1> ReturnType;
253 
254  ReturnType res; res[0] = ref.axis.dot(f.angular());
255  return res;
256  }
257 
258  /* [CRBA] MatrixBase operator* (Constraint::Transpose S, ForceSet::Block) */
259  template<typename D>
260 #if EIGEN_VERSION_AT_LEAST(3,2,90)
261  const Eigen::Product<
262  Eigen::Transpose<const Vector3>,
263  typename Eigen::MatrixBase<const D>::template NRowsBlockXpr<3>::Type
264  >
265 #else
266  const typename Eigen::ProductReturnType<
267  Eigen::Transpose<const Vector3>,
268  typename Eigen::MatrixBase<const D>::template NRowsBlockXpr<3>::Type
269  >::Type
270 #endif
271  operator*(const Eigen::MatrixBase<D> & F)
272  {
273  EIGEN_STATIC_ASSERT(D::RowsAtCompileTime==6,THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE)
274  /* Return ax.T * F[3:end,:] */
275  return ref.axis.transpose() * F.template middleRows<3>(ANGULAR);
276  }
277 
278  };
279 
280  TransposeConst transpose() const { return TransposeConst(*this); }
281 
282  /* CRBA joint operators
283  * - ForceSet::Block = ForceSet
284  * - ForceSet operator* (Inertia Y,Constraint S)
285  * - MatrixBase operator* (Constraint::Transpose S, ForceSet::Block)
286  * - SE3::act(ForceSet::Block)
287  */
288  DenseBase matrix_impl() const
289  {
290  DenseBase S;
291  S << Vector3::Zero(), axis;
292  return S;
293  }
294 
295  template<typename MotionDerived>
296  DenseBase motionAction(const MotionDense<MotionDerived> & m) const
297  {
298  const typename MotionDerived::ConstLinearType v = m.linear();
299  const typename MotionDerived::ConstAngularType w = m.angular();
300 
301  DenseBase res;
302  res << v.cross(axis), w.cross(axis);
303 
304  return res;
305  }
306 
307  // data
308  Vector3 axis;
309 
310  }; // struct ConstraintRevoluteUnalignedTpl
311 
312  template<typename MotionDerived, typename S2, int O2>
313  inline typename MotionDerived::MotionPlain
314  operator^(const MotionDense<MotionDerived> & m1, const MotionRevoluteUnalignedTpl<S2,O2> & m2)
315  {
316  /* m1xm2 = [ v1xw2 + w1xv2; w1xw2 ] = [ v1xw2; w1xw2 ] */
317  return m2.motionAction(m1);
318  }
319 
320  /* [CRBA] ForceSet operator* (Inertia Y,Constraint S) */
321  template<typename S1, int O1, typename S2, int O2>
322  inline Eigen::Matrix<S2,6,1,O2>
323  operator*(const InertiaTpl<S1,O1> & Y, const ConstraintRevoluteUnalignedTpl<S2,O2> & cru)
324  {
325  typedef InertiaTpl<S1,O1> Inertia;
326  /* YS = [ m -mcx ; mcx I-mcxcx ] [ 0 ; w ] = [ mcxw ; Iw -mcxcxw ] */
327  const typename Inertia::Scalar & m = Y.mass();
328  const typename Inertia::Vector3 & c = Y.lever();
329  const typename Inertia::Symmetric3 & I = Y.inertia();
330 
331  Eigen::Matrix<S2,6,1,O2>res;
332  res.template segment<3>(Inertia::LINEAR) = -m*c.cross(cru.axis);
333  res.template segment<3>(Inertia::ANGULAR).noalias() = I*cru.axis;
334  res.template segment<3>(Inertia::ANGULAR) += c.cross(res.template segment<3>(Inertia::LINEAR));
335  return res;
336  }
337 
338  /* [ABA] Y*S operator (Inertia Y,Constraint S) */
339 
340  template<typename M6Like, typename S2, int O2>
341  inline
342 #if EIGEN_VERSION_AT_LEAST(3,2,90)
343  const typename Eigen::Product<
344  typename Eigen::internal::remove_const<typename SizeDepType<3>::ColsReturn<M6Like>::ConstType>::type,
346  >
347 #else
348  const typename Eigen::ProductReturnType<
349  typename Eigen::internal::remove_const<typename SizeDepType<3>::ColsReturn<M6Like>::ConstType>::type,
351  >::Type
352 #endif
353  operator*(const Eigen::MatrixBase<M6Like> & Y, const ConstraintRevoluteUnalignedTpl<S2,O2> & cru)
354  {
355  typedef ConstraintRevoluteUnalignedTpl<S2,O2> Constraint;
356  return Y.derived().template middleCols<3>(Constraint::ANGULAR) * cru.axis;
357  }
358 
359  namespace internal
360  {
361  template<typename Scalar, int Options>
362  struct SE3GroupAction< ConstraintRevoluteUnalignedTpl<Scalar,Options> >
363  { typedef Eigen::Matrix<Scalar,6,1,Options> ReturnType; };
364 
365  template<typename Scalar, int Options, typename MotionDerived>
366  struct MotionAlgebraAction< ConstraintRevoluteUnalignedTpl<Scalar,Options>,MotionDerived >
367  { typedef Eigen::Matrix<Scalar,6,1,Options> ReturnType; };
368  }
369 
370  template<typename Scalar, int Options> struct JointRevoluteUnalignedTpl;
371 
372  template<typename _Scalar, int _Options>
373  struct traits< JointRevoluteUnalignedTpl<_Scalar,_Options> >
374  {
375  enum {
376  NQ = 1,
377  NV = 1
378  };
379  typedef _Scalar Scalar;
380  enum { Options = _Options };
387  typedef Eigen::Matrix<Scalar,6,NV,Options> F_t;
388 
389  // [ABA]
390  typedef Eigen::Matrix<Scalar,6,NV,Options> U_t;
391  typedef Eigen::Matrix<Scalar,NV,NV,Options> D_t;
392  typedef Eigen::Matrix<Scalar,6,NV,Options> UD_t;
393 
394  PINOCCHIO_JOINT_DATA_BASE_ACCESSOR_DEFAULT_RETURN_TYPE
395 
396  typedef Eigen::Matrix<Scalar,NQ,1,Options> ConfigVector_t;
397  typedef Eigen::Matrix<Scalar,NV,1,Options> TangentVector_t;
398 
399  };
400 
401  template<typename Scalar, int Options>
402  struct traits< JointDataRevoluteUnalignedTpl<Scalar,Options> >
404 
405  template<typename Scalar, int Options>
406  struct traits <JointModelRevoluteUnalignedTpl<Scalar,Options> >
408 
409  template<typename _Scalar, int _Options>
411  : public JointDataBase< JointDataRevoluteUnalignedTpl<_Scalar,_Options> >
412  {
413  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
415  PINOCCHIO_JOINT_DATA_TYPEDEF_TEMPLATE;
416  PINOCCHIO_JOINT_DATA_BASE_DEFAULT_ACCESSOR
417 
418  Transformation_t M;
419  Constraint_t S;
420  Motion_t v;
421  Bias_t c;
422 
423  F_t F;
424 
425  // [ABA] specific data
426  U_t U;
427  D_t Dinv;
428  UD_t UDinv;
429 
431 
432  template<typename Vector3Like>
433  JointDataRevoluteUnalignedTpl(const Eigen::MatrixBase<Vector3Like> & axis)
434  : M(1)
435  , S(axis)
436  , v(axis,(Scalar)NAN)
437  , U(), Dinv(), UDinv()
438  {}
439 
440  static std::string classname() { return std::string("JointDataRevoluteUnaligned"); }
441  std::string shortname() const { return classname(); }
442 
443  }; // struct JointDataRevoluteUnalignedTpl
444 
445  PINOCCHIO_JOINT_CAST_TYPE_SPECIALIZATION(JointModelRevoluteUnalignedTpl);
446  template<typename _Scalar, int _Options>
448  : public JointModelBase< JointModelRevoluteUnalignedTpl<_Scalar,_Options> >
449  {
450  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
452  PINOCCHIO_JOINT_TYPEDEF_TEMPLATE;
453  typedef Eigen::Matrix<Scalar,3,1,_Options> Vector3;
454 
456  using Base::id;
457  using Base::idx_q;
458  using Base::idx_v;
459  using Base::setIndexes;
460 
462 
463  JointModelRevoluteUnalignedTpl(const Scalar & x, const Scalar & y, const Scalar & z)
464  : axis(x,y,z)
465  {
466  axis.normalize();
467  assert(axis.isUnitary() && "Rotation axis is not unitary");
468  }
469 
470  template<typename Vector3Like>
471  JointModelRevoluteUnalignedTpl(const Eigen::MatrixBase<Vector3Like> & axis)
472  : axis(axis)
473  {
474  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Vector3Like);
475  assert(axis.isUnitary() && "Rotation axis is not unitary");
476  }
477 
478  JointDataDerived createData() const { return JointDataDerived(axis); }
479 
480  using Base::isEqual;
481  bool isEqual(const JointModelRevoluteUnalignedTpl & other) const
482  {
483  return Base::isEqual(other) && axis == other.axis;
484  }
485 
486  template<typename ConfigVector>
487  void calc(JointDataDerived & data,
488  const typename Eigen::MatrixBase<ConfigVector> & qs) const
489  {
490  typedef typename ConfigVector::Scalar OtherScalar;
491  typedef Eigen::AngleAxis<Scalar> AngleAxis;
492 
493  const OtherScalar & q = qs[idx_q()];
494 
495  data.M.rotation(AngleAxis(q,axis).toRotationMatrix());
496  }
497 
498  template<typename ConfigVector, typename TangentVector>
499  void calc(JointDataDerived & data,
500  const typename Eigen::MatrixBase<ConfigVector> & qs,
501  const typename Eigen::MatrixBase<TangentVector> & vs) const
502  {
503  calc(data,qs.derived());
504 
505  data.v.w = (Scalar)vs[idx_v()];
506  }
507 
508  template<typename Matrix6Like>
509  void calc_aba(JointDataDerived & data, const Eigen::MatrixBase<Matrix6Like> & I, const bool update_I) const
510  {
511  data.U.noalias() = I.template middleCols<3>(Motion::ANGULAR) * axis;
512  data.Dinv[0] = (Scalar)(1)/axis.dot(data.U.template segment<3>(Motion::ANGULAR));
513  data.UDinv.noalias() = data.U * data.Dinv;
514 
515  if (update_I)
516  PINOCCHIO_EIGEN_CONST_CAST(Matrix6Like,I) -= data.UDinv * data.U.transpose();
517  }
518 
519  Scalar finiteDifferenceIncrement() const
520  {
521  using math::sqrt;
522  return 2.*sqrt(sqrt(Eigen::NumTraits<Scalar>::epsilon()));
523  }
524 
525  static std::string classname() { return std::string("JointModelRevoluteUnaligned"); }
526  std::string shortname() const { return classname(); }
527 
529  template<typename NewScalar>
531  {
533  ReturnType res(axis.template cast<NewScalar>());
534  res.setIndexes(id(),idx_q(),idx_v());
535  return res;
536  }
537 
538  // data
539 
543  Vector3 axis;
544  }; // struct JointModelRevoluteUnalignedTpl
545 
546 } //namespace pinocchio
547 
548 #include <boost/type_traits.hpp>
549 
550 namespace boost
551 {
552  template<typename Scalar, int Options>
553  struct has_nothrow_constructor< ::pinocchio::JointModelRevoluteUnalignedTpl<Scalar,Options> >
554  : public integral_constant<bool,true> {};
555 
556  template<typename Scalar, int Options>
557  struct has_nothrow_copy< ::pinocchio::JointModelRevoluteUnalignedTpl<Scalar,Options> >
558  : public integral_constant<bool,true> {};
559 
560  template<typename Scalar, int Options>
561  struct has_nothrow_constructor< ::pinocchio::JointDataRevoluteUnalignedTpl<Scalar,Options> >
562  : public integral_constant<bool,true> {};
563 
564  template<typename Scalar, int Options>
565  struct has_nothrow_copy< ::pinocchio::JointDataRevoluteUnalignedTpl<Scalar,Options> >
566  : public integral_constant<bool,true> {};
567 }
568 
569 
570 #endif // ifndef __pinocchio_joint_revolute_unaligned_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...
std::string shortname(const JointModelTpl< Scalar, Options, JointCollectionTpl > &jmodel)
Visit a JointModelTpl through JointShortnameVisitor to get the shortname of the derived joint model...
JointModelRevoluteUnalignedTpl< NewScalar, Options > cast() const
ConstAngularType angular() const
Return the angular part of the force vector.
Definition: force-base.hpp:40
Main pinocchio namespace.
Definition: treeview.dox:24
Common traits structure to fully define base classes for CRTP.
Definition: spatial/fwd.hpp:29
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...