pinocchio  3.3.1
A fast and flexible implementation of Rigid Body Dynamics algorithms and their analytical derivatives
joint-spherical-ZYX.hpp
1 //
2 // Copyright (c) 2015-2020 CNRS INRIA
3 // Copyright (c) 2015-2016 Wandercraft, 86 rue de Paris 91400 Orsay, France.
4 //
5 
6 #ifndef __pinocchio_multibody_joint_spherical_ZYX_hpp__
7 #define __pinocchio_multibody_joint_spherical_ZYX_hpp__
8 
9 #include "pinocchio/macros.hpp"
10 #include "pinocchio/multibody/joint/joint-base.hpp"
11 #include "pinocchio/multibody/joint/joint-spherical.hpp"
12 #include "pinocchio/multibody/joint-motion-subspace.hpp"
13 #include "pinocchio/math/sincos.hpp"
14 #include "pinocchio/math/matrix.hpp"
15 #include "pinocchio/spatial/inertia.hpp"
16 #include "pinocchio/spatial/skew.hpp"
17 
18 namespace pinocchio
19 {
20  template<typename Scalar, int Options>
21  struct JointMotionSubspaceSphericalZYXTpl;
22 
23  template<typename _Scalar, int _Options>
24  struct traits<JointMotionSubspaceSphericalZYXTpl<_Scalar, _Options>>
25  {
26  typedef _Scalar Scalar;
27  enum
28  {
29  Options = _Options
30  };
31 
32  enum
33  {
34  LINEAR = 0,
35  ANGULAR = 3
36  };
37 
39  typedef Eigen::Matrix<Scalar, 3, 1, Options> JointForce;
40  typedef Eigen::Matrix<Scalar, 6, 3, Options> DenseBase;
41  typedef Eigen::Matrix<Scalar, 3, 3, Options> ReducedSquaredMatrix;
42 
43  typedef DenseBase MatrixReturnType;
44  typedef const DenseBase ConstMatrixReturnType;
45 
46  typedef ReducedSquaredMatrix StDiagonalMatrixSOperationReturnType;
47  }; // struct traits struct ConstraintRotationalSubspace
48 
49  template<typename _Scalar, int _Options>
51  : public JointMotionSubspaceBase<JointMotionSubspaceSphericalZYXTpl<_Scalar, _Options>>
52  {
53  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
54 
55  PINOCCHIO_CONSTRAINT_TYPEDEF_TPL(JointMotionSubspaceSphericalZYXTpl)
56 
57  enum
58  {
59  NV = 3
60  };
61  typedef Eigen::Matrix<Scalar, 3, 3, Options> Matrix3;
62 
64  {
65  }
66 
67  template<typename Matrix3Like>
68  JointMotionSubspaceSphericalZYXTpl(const Eigen::MatrixBase<Matrix3Like> & subspace)
69  : m_S(subspace)
70  {
71  EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Matrix3Like, 3, 3);
72  }
73 
74  template<typename Vector3Like>
75  JointMotion __mult__(const Eigen::MatrixBase<Vector3Like> & v) const
76  {
77  EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Vector3Like, 3);
78  return JointMotion(m_S * v);
79  }
80 
81  Matrix3 & operator()()
82  {
83  return m_S;
84  }
85  const Matrix3 & operator()() const
86  {
87  return m_S;
88  }
89 
90  int nv_impl() const
91  {
92  return NV;
93  }
94 
96  : JointMotionSubspaceTransposeBase<JointMotionSubspaceSphericalZYXTpl>
97  {
100  : ref(ref)
101  {
102  }
103 
104  template<typename Derived>
105  const typename MatrixMatrixProduct<
106  Eigen::Transpose<const Matrix3>,
107  Eigen::Block<const typename ForceDense<Derived>::Vector6, 3, 1>>::type
108  operator*(const ForceDense<Derived> & phi) const
109  {
110  return ref.m_S.transpose() * phi.angular();
111  }
112 
113  /* [CRBA] MatrixBase operator* (Constraint::Transpose S, ForceSet::Block) */
114  template<typename D>
115  const typename MatrixMatrixProduct<
116  typename Eigen::Transpose<const Matrix3>,
117  typename Eigen::MatrixBase<const D>::template NRowsBlockXpr<3>::Type>::type
118  operator*(const Eigen::MatrixBase<D> & F) const
119  {
120  EIGEN_STATIC_ASSERT(
121  D::RowsAtCompileTime == 6, THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE)
122  return ref.m_S.transpose() * F.template middleRows<3>(ANGULAR);
123  }
124  }; // struct ConstraintTranspose
125 
126  ConstraintTranspose transpose() const
127  {
128  return ConstraintTranspose(*this);
129  }
130 
131  DenseBase matrix_impl() const
132  {
133  DenseBase S;
134  S.template middleRows<3>(LINEAR).setZero();
135  S.template middleRows<3>(ANGULAR) = m_S;
136  return S;
137  }
138 
139  // const typename Eigen::ProductReturnType<
140  // const ConstraintDense,
141  // const Matrix3
142  // >::Type
143  template<typename S1, int O1>
144  Eigen::Matrix<Scalar, 6, 3, Options> se3Action(const SE3Tpl<S1, O1> & m) const
145  {
146  // Eigen::Matrix <Scalar,6,3,Options> X_subspace;
147  // X_subspace.template block <3,3> (Motion::LINEAR, 0) = skew (m.translation ()) *
148  // m.rotation (); X_subspace.template block <3,3> (Motion::ANGULAR, 0) = m.rotation ();
149  //
150  // return (X_subspace * m_S).eval();
151 
152  Eigen::Matrix<Scalar, 6, 3, Options> result;
153 
154  // ANGULAR
155  result.template middleRows<3>(ANGULAR).noalias() = m.rotation() * m_S;
156 
157  // LINEAR
158  cross(
159  m.translation(), result.template middleRows<3>(Motion::ANGULAR),
160  result.template middleRows<3>(LINEAR));
161 
162  return result;
163  }
164 
165  template<typename S1, int O1>
166  Eigen::Matrix<Scalar, 6, 3, Options> se3ActionInverse(const SE3Tpl<S1, O1> & m) const
167  {
168  Eigen::Matrix<Scalar, 6, 3, Options> result;
169 
170  // LINEAR
171  cross(m.translation(), m_S, result.template middleRows<3>(ANGULAR));
172  result.template middleRows<3>(LINEAR).noalias() =
173  -m.rotation().transpose() * result.template middleRows<3>(ANGULAR);
174 
175  // ANGULAR
176  result.template middleRows<3>(ANGULAR).noalias() = m.rotation().transpose() * m_S;
177 
178  return result;
179  }
180 
181  template<typename MotionDerived>
182  DenseBase motionAction(const MotionDense<MotionDerived> & m) const
183  {
184  const typename MotionDerived::ConstLinearType v = m.linear();
185  const typename MotionDerived::ConstAngularType w = m.angular();
186 
187  DenseBase res;
188  cross(v, m_S, res.template middleRows<3>(LINEAR));
189  cross(w, m_S, res.template middleRows<3>(ANGULAR));
190 
191  return res;
192  }
193 
194  Matrix3 & angularSubspace()
195  {
196  return m_S;
197  }
198  const Matrix3 & angularSubspace() const
199  {
200  return m_S;
201  }
202 
203  bool isEqual(const JointMotionSubspaceSphericalZYXTpl & other) const
204  {
205  return internal::comparison_eq(m_S, other.m_S);
206  }
207 
208  protected:
209  Matrix3 m_S;
210 
211  }; // struct JointMotionSubspaceSphericalZYXTpl
212 
213  namespace details
214  {
215  template<typename Scalar, int Options>
217  {
220 
221  static ReturnType run(const JointMotionSubspaceBase<Constraint> & constraint)
222  {
223  return constraint.matrix().transpose() * constraint.matrix();
224  }
225  };
226  } // namespace details
227 
228  /* [CRBA] ForceSet operator* (Inertia Y,Constraint S) */
229  template<typename S1, int O1, typename S2, int O2>
230  Eigen::Matrix<S1, 6, 3, O1>
231  operator*(const InertiaTpl<S1, O1> & Y, const JointMotionSubspaceSphericalZYXTpl<S2, O2> & S)
232  {
235  Eigen::Matrix<S1, 6, 3, O1> M;
236  alphaSkew(-Y.mass(), Y.lever(), M.template middleRows<3>(Constraint::LINEAR));
237  M.template middleRows<3>(Constraint::ANGULAR) =
238  (Y.inertia() - typename Symmetric3::AlphaSkewSquare(Y.mass(), Y.lever())).matrix();
239 
240  return (M * S.angularSubspace()).eval();
241  }
242 
243  /* [ABA] Y*S operator (Inertia Y,Constraint S) */
244  // inline Eigen::Matrix<context::Scalar,6,3>
245  template<typename Matrix6Like, typename S2, int O2>
246  const typename MatrixMatrixProduct<
247  typename Eigen::internal::remove_const<
248  typename SizeDepType<3>::ColsReturn<Matrix6Like>::ConstType>::type,
249  typename JointMotionSubspaceSphericalZYXTpl<S2, O2>::Matrix3>::type
250  operator*(
251  const Eigen::MatrixBase<Matrix6Like> & Y, const JointMotionSubspaceSphericalZYXTpl<S2, O2> & S)
252  {
253  EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Matrix6Like, 6, 6);
254  return Y.derived().template middleCols<3>(Inertia::ANGULAR) * S.angularSubspace();
255  }
256 
257  template<typename S1, int O1>
259  {
260  // typedef const typename Eigen::ProductReturnType<
261  // Eigen::Matrix <context::Scalar,6,3,0>,
262  // Eigen::Matrix <context::Scalar,3,3,0>
263  // >::Type Type;
264  typedef Eigen::Matrix<S1, 6, 3, O1> ReturnType;
265  };
266 
267  template<typename S1, int O1, typename MotionDerived>
269  {
270  typedef Eigen::Matrix<S1, 6, 3, O1> ReturnType;
271  };
272 
273  template<typename Scalar, int Options>
275 
276  template<typename _Scalar, int _Options>
277  struct traits<JointSphericalZYXTpl<_Scalar, _Options>>
278  {
279  enum
280  {
281  NQ = 3,
282  NV = 3
283  };
284  typedef _Scalar Scalar;
285  enum
286  {
287  Options = _Options
288  };
295 
296  // [ABA]
297  typedef Eigen::Matrix<Scalar, 6, NV, Options> U_t;
298  typedef Eigen::Matrix<Scalar, NV, NV, Options> D_t;
299  typedef Eigen::Matrix<Scalar, 6, NV, Options> UD_t;
300 
301  typedef Eigen::Matrix<Scalar, NQ, 1, Options> ConfigVector_t;
302  typedef Eigen::Matrix<Scalar, NV, 1, Options> TangentVector_t;
303 
304  PINOCCHIO_JOINT_DATA_BASE_ACCESSOR_DEFAULT_RETURN_TYPE
305  };
306 
307  template<typename _Scalar, int _Options>
308  struct traits<JointDataSphericalZYXTpl<_Scalar, _Options>>
309  {
311  typedef _Scalar Scalar;
312  };
313 
314  template<typename _Scalar, int _Options>
315  struct traits<JointModelSphericalZYXTpl<_Scalar, _Options>>
316  {
318  typedef _Scalar Scalar;
319  };
320 
321  template<typename _Scalar, int _Options>
323  : public JointDataBase<JointDataSphericalZYXTpl<_Scalar, _Options>>
324  {
325  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
327  PINOCCHIO_JOINT_DATA_TYPEDEF_TEMPLATE(JointDerived);
328  PINOCCHIO_JOINT_DATA_BASE_DEFAULT_ACCESSOR
329 
330  ConfigVector_t joint_q;
331  TangentVector_t joint_v;
332 
333  Constraint_t S;
334  Transformation_t M;
335  Motion_t v;
336  Bias_t c;
337 
338  // [ABA] specific data
339  U_t U;
340  D_t Dinv;
341  UD_t UDinv;
342  D_t StU;
343 
345  : joint_q(ConfigVector_t::Zero())
346  , joint_v(TangentVector_t::Zero())
347  , S(Constraint_t::Matrix3::Zero())
348  , M(Transformation_t::Identity())
349  , v(Motion_t::Vector3::Zero())
350  , c(Bias_t::Vector3::Zero())
351  , U(U_t::Zero())
352  , Dinv(D_t::Zero())
353  , UDinv(UD_t::Zero())
354  , StU(D_t::Zero())
355  {
356  }
357 
358  static std::string classname()
359  {
360  return std::string("JointDataSphericalZYX");
361  }
362  std::string shortname() const
363  {
364  return classname();
365  }
366 
367  }; // strcut JointDataSphericalZYXTpl
368 
369  PINOCCHIO_JOINT_CAST_TYPE_SPECIALIZATION(JointModelSphericalZYXTpl);
370  template<typename _Scalar, int _Options>
372  : public JointModelBase<JointModelSphericalZYXTpl<_Scalar, _Options>>
373  {
374  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
376  PINOCCHIO_JOINT_TYPEDEF_TEMPLATE(JointDerived);
377 
379  using Base::id;
380  using Base::idx_q;
381  using Base::idx_v;
382  using Base::setIndexes;
383 
384  JointDataDerived createData() const
385  {
386  return JointDataDerived();
387  }
388 
389  const std::vector<bool> hasConfigurationLimit() const
390  {
391  return {true, true, true};
392  }
393 
394  const std::vector<bool> hasConfigurationLimitInTangent() const
395  {
396  return {true, true, true};
397  }
398 
399  template<typename ConfigVector>
400  void calc(JointDataDerived & data, const typename Eigen::MatrixBase<ConfigVector> & qs) const
401  {
402  data.joint_q = qs.template segment<NQ>(idx_q());
403 
404  Scalar c0, s0;
405  SINCOS(data.joint_q(0), &s0, &c0);
406  Scalar c1, s1;
407  SINCOS(data.joint_q(1), &s1, &c1);
408  Scalar c2, s2;
409  SINCOS(data.joint_q(2), &s2, &c2);
410 
411  data.M.rotation() << c0 * c1, c0 * s1 * s2 - s0 * c2, c0 * s1 * c2 + s0 * s2, s0 * c1,
412  s0 * s1 * s2 + c0 * c2, s0 * s1 * c2 - c0 * s2, -s1, c1 * s2, c1 * c2;
413 
414  data.S.angularSubspace() << -s1, Scalar(0), Scalar(1), c1 * s2, c2, Scalar(0), c1 * c2, -s2,
415  Scalar(0);
416  }
417 
418  template<typename TangentVector>
419  void
420  calc(JointDataDerived & data, const Blank, const typename Eigen::MatrixBase<TangentVector> & vs)
421  const
422  {
423  data.joint_v = vs.template segment<NV>(idx_v());
424  data.v().noalias() = data.S.angularSubspace() * data.joint_v;
425 
426  // TODO(jcarpent): to be done
427  // #define q_dot data.joint_v
428  // data.c()(0) = -c1 * q_dot(0) * q_dot(1);
429  // data.c()(1) = -s1 * s2 * q_dot(0) * q_dot(1) + c1 * c2 * q_dot(0) * q_dot(2) - s2 *
430  // q_dot(1) * q_dot(2); data.c()(2) = -s1 * c2 * q_dot(0) * q_dot(1) - c1 * s2 *
431  // q_dot(0) * q_dot(2) - c2 * q_dot(1) * q_dot(2);
432  // #undef q_dot
433  }
434 
435  template<typename ConfigVector, typename TangentVector>
436  void calc(
437  JointDataDerived & data,
438  const typename Eigen::MatrixBase<ConfigVector> & qs,
439  const typename Eigen::MatrixBase<TangentVector> & vs) const
440  {
441  data.joint_q = qs.template segment<NQ>(idx_q());
442 
443  Scalar c0, s0;
444  SINCOS(data.joint_q(0), &s0, &c0);
445  Scalar c1, s1;
446  SINCOS(data.joint_q(1), &s1, &c1);
447  Scalar c2, s2;
448  SINCOS(data.joint_q(2), &s2, &c2);
449 
450  data.M.rotation() << c0 * c1, c0 * s1 * s2 - s0 * c2, c0 * s1 * c2 + s0 * s2, s0 * c1,
451  s0 * s1 * s2 + c0 * c2, s0 * s1 * c2 - c0 * s2, -s1, c1 * s2, c1 * c2;
452 
453  data.S.angularSubspace() << -s1, Scalar(0), Scalar(1), c1 * s2, c2, Scalar(0), c1 * c2, -s2,
454  Scalar(0);
455 
456  data.joint_v = vs.template segment<NV>(idx_v());
457  data.v().noalias() = data.S.angularSubspace() * data.joint_v;
458 
459 #define q_dot data.joint_v
460  data.c()(0) = -c1 * q_dot(0) * q_dot(1);
461  data.c()(1) =
462  -s1 * s2 * q_dot(0) * q_dot(1) + c1 * c2 * q_dot(0) * q_dot(2) - s2 * q_dot(1) * q_dot(2);
463  data.c()(2) =
464  -s1 * c2 * q_dot(0) * q_dot(1) - c1 * s2 * q_dot(0) * q_dot(2) - c2 * q_dot(1) * q_dot(2);
465 #undef q_dot
466  }
467 
468  template<typename VectorLike, typename Matrix6Like>
469  void calc_aba(
470  JointDataDerived & data,
471  const Eigen::MatrixBase<VectorLike> & armature,
472  const Eigen::MatrixBase<Matrix6Like> & I,
473  const bool update_I) const
474  {
475  data.U.noalias() = I.template middleCols<3>(Motion::ANGULAR) * data.S.angularSubspace();
476  data.StU.noalias() =
477  data.S.angularSubspace().transpose() * data.U.template middleRows<3>(Motion::ANGULAR);
478  data.StU.diagonal() += armature;
479 
480  internal::PerformStYSInversion<Scalar>::run(data.StU, data.Dinv);
481 
482  data.UDinv.noalias() = data.U * data.Dinv;
483 
484  if (update_I)
485  PINOCCHIO_EIGEN_CONST_CAST(Matrix6Like, I).noalias() -= data.UDinv * data.U.transpose();
486  }
487 
488  static std::string classname()
489  {
490  return std::string("JointModelSphericalZYX");
491  }
492  std::string shortname() const
493  {
494  return classname();
495  }
496 
498  template<typename NewScalar>
500  {
502  ReturnType res;
503  res.setIndexes(id(), idx_q(), idx_v());
504  return res;
505  }
506 
507  }; // struct JointModelSphericalZYXTpl
508 
509 } // namespace pinocchio
510 
511 #include <boost/type_traits.hpp>
512 
513 namespace boost
514 {
515  template<typename Scalar, int Options>
516  struct has_nothrow_constructor<::pinocchio::JointModelSphericalZYXTpl<Scalar, Options>>
517  : public integral_constant<bool, true>
518  {
519  };
520 
521  template<typename Scalar, int Options>
522  struct has_nothrow_copy<::pinocchio::JointModelSphericalZYXTpl<Scalar, Options>>
523  : public integral_constant<bool, true>
524  {
525  };
526 
527  template<typename Scalar, int Options>
528  struct has_nothrow_constructor<::pinocchio::JointDataSphericalZYXTpl<Scalar, Options>>
529  : public integral_constant<bool, true>
530  {
531  };
532 
533  template<typename Scalar, int Options>
534  struct has_nothrow_copy<::pinocchio::JointDataSphericalZYXTpl<Scalar, Options>>
535  : public integral_constant<bool, true>
536  {
537  };
538 } // namespace boost
539 
540 #endif // ifndef __pinocchio_multibody_joint_spherical_ZYX_hpp__
ConstAngularType angular() const
Return the angular part of the force vector.
Definition: force-base.hpp:47
Main pinocchio namespace.
Definition: treeview.dox:11
JointDataTpl< Scalar, Options, JointCollectionTpl >::TangentVector_t joint_v(const JointDataTpl< Scalar, Options, JointCollectionTpl > &jdata)
Visit a JointDataVariant through JointConfigVisitor to get the joint velocity vector.
JointDataTpl< Scalar, Options, JointCollectionTpl >::ConfigVector_t joint_q(const JointDataTpl< Scalar, Options, JointCollectionTpl > &jdata)
Visit a JointDataVariant through JointConfigVisitor to get the joint configuration vector.
void SINCOS(const S1 &a, S2 *sa, S3 *ca)
Computes sin/cos values of a given input scalar.
Definition: sincos.hpp:27
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....
Definition: skew.hpp:134
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:228
Blank type.
Definition: fwd.hpp:77
JointModelSphericalZYXTpl< NewScalar, Options > cast() const
Return type of the ation of a Motion onto an object of type D.
Definition: motion.hpp:46
Common traits structure to fully define base classes for CRTP.
Definition: fwd.hpp:72