pinocchio  UNKNOWN
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 // 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_unaligned_hpp__
20 #define __se3_joint_revolute_unaligned_hpp__
21 
22 #include "pinocchio/macros.hpp"
23 #include "pinocchio/multibody/joint/joint-base.hpp"
24 #include "pinocchio/multibody/constraint.hpp"
25 #include "pinocchio/spatial/inertia.hpp"
26 
27 namespace se3
28 {
29 
30  template<typename Scalar, int Options> struct MotionRevoluteUnalignedTpl;
31 
32  template<typename _Scalar, int _Options>
33  struct traits< MotionRevoluteUnalignedTpl<_Scalar,_Options> >
34  {
35  typedef _Scalar Scalar;
36  enum { Options = _Options };
37  typedef Eigen::Matrix<Scalar,3,1,Options> Vector3;
38  typedef Eigen::Matrix<Scalar,6,1,Options> Vector6;
39  typedef Eigen::Matrix<Scalar,6,6,Options> Matrix6;
40  typedef typename EIGEN_REF_CONSTTYPE(Vector6) ToVectorConstReturnType;
41  typedef typename EIGEN_REF_TYPE(Vector6) ToVectorReturnType;
42  typedef Vector3 AngularType;
43  typedef Vector3 LinearType;
44  typedef const Vector3 ConstAngularType;
45  typedef const Vector3 ConstLinearType;
46  typedef Matrix6 ActionMatrixType;
48  enum {
49  LINEAR = 0,
50  ANGULAR = 3
51  };
52  }; // traits MotionRevoluteUnalignedTpl
53 
54  template<typename _Scalar, int _Options>
55  struct MotionRevoluteUnalignedTpl : MotionBase< MotionRevoluteUnalignedTpl<_Scalar,_Options> >
56  {
57  MOTION_TYPEDEF_TPL(MotionRevoluteUnalignedTpl);
58 
59  MotionRevoluteUnalignedTpl() : axis(Vector3::Constant(NAN)), w(NAN) {}
60 
61  template<typename Vector3Like, typename OtherScalar>
62  MotionRevoluteUnalignedTpl(const Eigen::MatrixBase<Vector3Like> & axis,
63  const OtherScalar & w)
64  : axis(axis), w(w)
65  {}
66 
67  operator MotionPlain() const
68  {
69  return MotionPlain(MotionPlain::Vector3::Zero(),
70  axis*w);
71  }
72 
73  template<typename MotionDerived>
74  void addTo(MotionDense<MotionDerived> & v) const
75  {
76  v.angular() += axis*w;
77  }
78 
79  // data
80  Vector3 axis;
81  double w;
82 
83  }; // struct MotionRevoluteUnalignedTpl
84 
85  template<typename S1, int O1, typename MotionDerived>
86  inline typename MotionDerived::MotionPlain
87  operator+(const MotionRevoluteUnalignedTpl<S1,O1> & m1, const MotionDense<MotionDerived> & m2)
88  {
89  typename MotionDerived::MotionPlain res(m2);
90  res += m1;
91  return res;
92  }
93 
94  template<typename Scalar, int Options> struct ConstraintRevoluteUnalignedTpl;
95 
96  template<typename _Scalar, int _Options>
97  struct traits< ConstraintRevoluteUnalignedTpl<_Scalar,_Options> >
98  {
99  typedef _Scalar Scalar;
100  enum { Options = _Options };
101  typedef Eigen::Matrix<Scalar,3,1,Options> Vector3;
102  typedef Eigen::Matrix<Scalar,4,1,Options> Vector4;
103  typedef Eigen::Matrix<Scalar,6,1,Options> Vector6;
104  typedef Eigen::Matrix<Scalar,3,3,Options> Matrix3;
105  typedef Eigen::Matrix<Scalar,4,4,Options> Matrix4;
106  typedef Eigen::Matrix<Scalar,6,6,Options> Matrix6;
107  typedef Matrix3 Angular_t;
108  typedef Vector3 Linear_t;
109  typedef const Matrix3 ConstAngular_t;
110  typedef const Vector3 ConstLinear_t;
111  typedef Matrix6 ActionMatrix_t;
112  typedef Eigen::Quaternion<Scalar,Options> Quaternion_t;
113  typedef SE3Tpl<Scalar,Options> SE3;
117  enum {
118  LINEAR = 0,
119  ANGULAR = 3
120  };
121  typedef Eigen::Matrix<Scalar,1,1,Options> JointMotion;
122  typedef Eigen::Matrix<Scalar,1,1,Options> JointForce;
123  typedef Eigen::Matrix<Scalar,6,1,Options> DenseBase;
124  typedef DenseBase MatrixReturnType;
125  typedef const DenseBase ConstMatrixReturnType;
126  }; // traits ConstraintRevoluteUnalignedTpl
127 
128  template<typename _Scalar, int _Options>
129  struct ConstraintRevoluteUnalignedTpl : ConstraintBase< ConstraintRevoluteUnalignedTpl<_Scalar,_Options> >
130  {
131  SPATIAL_TYPEDEF_TEMPLATE(ConstraintRevoluteUnalignedTpl);
132  enum { NV = 1, Options = _Options };
133  typedef typename traits<ConstraintRevoluteUnalignedTpl>::JointMotion JointMotion;
134  typedef typename traits<ConstraintRevoluteUnalignedTpl>::JointForce JointForce;
135  typedef typename traits<ConstraintRevoluteUnalignedTpl>::DenseBase DenseBase;
136 
137  ConstraintRevoluteUnalignedTpl() : axis(Vector3::Constant(NAN)) {}
138 
139  template<typename Vector3Like>
140  ConstraintRevoluteUnalignedTpl(const Eigen::MatrixBase<Vector3Like> & axis)
141  : axis(axis)
142  {}
143 
144  template<typename D>
146  operator*(const Eigen::MatrixBase<D> & v) const
147  {
148  EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(D,1);
150  }
151 
152  template<typename S1, int O1>
153  Eigen::Matrix<Scalar,6,1,Options> se3Action(const SE3Tpl<S1,O1> & m) const
154  {
155  /* X*S = [ R pxR ; 0 R ] [ 0 ; a ] = [ px(Ra) ; Ra ] */
156  Eigen::Matrix<Scalar,6,1,Options> res;
157  res.template segment<3>(ANGULAR).noalias() = m.rotation() * axis;
158  res.template segment<3>(LINEAR).noalias() = m.translation().cross(res.template segment<3>(ANGULAR));
159  return res;
160  }
161 
162  int nv_impl() const { return NV; }
163 
165  {
166  const ConstraintRevoluteUnalignedTpl & ref;
167  TransposeConst(const ConstraintRevoluteUnalignedTpl & ref) : ref(ref) {}
168 
169  template<typename Derived>
170  Eigen::Matrix<
171  typename EIGEN_DOT_PRODUCT_RETURN_TYPE(Vector3,typename ForceDense<Derived>::ConstAngularType),
172  1,1>
173  operator*(const ForceDense<Derived> & f) const
174  {
175  typedef Eigen::Matrix<
176  typename EIGEN_DOT_PRODUCT_RETURN_TYPE(Vector3,typename ForceDense<Derived>::ConstAngularType),
177  1,1> ReturnType;
178 
179  ReturnType res; res[0] = ref.axis.dot(f.angular());
180  return res;
181  }
182 
183  /* [CRBA] MatrixBase operator* (Constraint::Transpose S, ForceSet::Block) */
184  template<typename D>
185 #if EIGEN_VERSION_AT_LEAST(3,2,90)
186  const Eigen::Product<
187  Eigen::Transpose<const Vector3>,
188  typename Eigen::MatrixBase<const D>::template NRowsBlockXpr<3>::Type
189  >
190 #else
191  const typename Eigen::ProductReturnType<
192  Eigen::Transpose<const Vector3>,
193  typename Eigen::MatrixBase<const D>::template NRowsBlockXpr<3>::Type
194  >::Type
195 #endif
196  operator*(const Eigen::MatrixBase<D> & F)
197  {
198  EIGEN_STATIC_ASSERT(D::RowsAtCompileTime==6,THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE)
199  /* Return ax.T * F[3:end,:] */
200  return ref.axis.transpose() * F.template middleRows<3>(ANGULAR);
201  }
202 
203  };
204 
205  TransposeConst transpose() const { return TransposeConst(*this); }
206 
207  /* CRBA joint operators
208  * - ForceSet::Block = ForceSet
209  * - ForceSet operator* (Inertia Y,Constraint S)
210  * - MatrixBase operator* (Constraint::Transpose S, ForceSet::Block)
211  * - SE3::act(ForceSet::Block)
212  */
213  DenseBase matrix_impl() const
214  {
215  DenseBase S;
216  S << Vector3::Zero(), axis;
217  return S;
218  }
219 
220  template<typename MotionDerived>
221  DenseBase motionAction(const MotionDense<MotionDerived> & m) const
222  {
223  const typename MotionDerived::ConstLinearType v = m.linear();
224  const typename MotionDerived::ConstAngularType w = m.angular();
225 
226  DenseBase res;
227  res << v.cross(axis), w.cross(axis);
228 
229  return res;
230  }
231 
232  // data
233  Vector3 axis;
234 
235  }; // struct ConstraintRevoluteUnalignedTpl
236 
237  template<typename MotionDerived, typename S2, int O2>
238  inline typename MotionDerived::MotionPlain
239  operator^(const MotionDense<MotionDerived> & m1, const MotionRevoluteUnalignedTpl<S2,O2> & m2)
240  {
241  /* m1xm2 = [ v1xw2 + w1xv2; w1xw2 ] = [ v1xw2; w1xw2 ] */
242  typedef typename MotionDerived::MotionPlain ReturnType;
243  const typename MotionDerived::ConstLinearType v1 = m1.linear();
244  const typename MotionDerived::ConstAngularType w1 = m1.angular();
245  const typename ReturnType::Vector3 w2(m2.axis * m2.w);
246  return ReturnType(v1.cross(w2),w1.cross(w2));
247  }
248 
249  /* [CRBA] ForceSet operator* (Inertia Y,Constraint S) */
250  template<typename S1, int O1, typename S2, int O2>
251  inline Eigen::Matrix<S2,6,1,O2>
252  operator*(const InertiaTpl<S1,O1> & Y, const ConstraintRevoluteUnalignedTpl<S2,O2> & cru)
253  {
254  typedef InertiaTpl<S1,O1> Inertia;
255  /* YS = [ m -mcx ; mcx I-mcxcx ] [ 0 ; w ] = [ mcxw ; Iw -mcxcxw ] */
256  const typename Inertia::Scalar & m = Y.mass();
257  const typename Inertia::Vector3 & c = Y.lever();
258  const typename Inertia::Symmetric3 & I = Y.inertia();
259 
260  Eigen::Matrix<S2,6,1,O2>res;
261  res.template segment<3>(Inertia::LINEAR) = -m*c.cross(cru.axis);
262  res.template segment<3>(Inertia::ANGULAR).noalias() = I*cru.axis;
263  res.template segment<3>(Inertia::ANGULAR) += c.cross(res.template segment<3>(Inertia::LINEAR));
264  return res;
265  }
266 
267  /* [ABA] Y*S operator (Inertia Y,Constraint S) */
268 
269  template<typename M6Like, typename S2, int O2>
270  inline
271 #if EIGEN_VERSION_AT_LEAST(3,2,90)
272  const typename Eigen::Product<
273  typename Eigen::internal::remove_const<typename SizeDepType<3>::ColsReturn<M6Like>::ConstType>::type,
275  >
276 #else
277  const typename Eigen::ProductReturnType<
278  typename Eigen::internal::remove_const<typename SizeDepType<3>::ColsReturn<M6Like>::ConstType>::type,
280  >::Type
281 #endif
282  operator*(const Eigen::MatrixBase<M6Like> & Y, const ConstraintRevoluteUnalignedTpl<S2,O2> & cru)
283  {
284  typedef ConstraintRevoluteUnalignedTpl<S2,O2> Constraint;
285  return Y.derived().template middleCols<3>(Constraint::ANGULAR) * cru.axis;
286  }
287 
288  namespace internal
289  {
290  template<typename Scalar, int Options>
291  struct SE3GroupAction< ConstraintRevoluteUnalignedTpl<Scalar,Options> >
292  { typedef Eigen::Matrix<Scalar,6,1,Options> ReturnType; };
293 
294  template<typename Scalar, int Options, typename MotionDerived>
295  struct MotionAlgebraAction< ConstraintRevoluteUnalignedTpl<Scalar,Options>,MotionDerived >
296  { typedef Eigen::Matrix<Scalar,6,1,Options> ReturnType; };
297  }
298 
299  template<typename Scalar, int Options> struct JointRevoluteUnalignedTpl;
300 
301  template<typename _Scalar, int _Options>
302  struct traits< JointRevoluteUnalignedTpl<_Scalar,_Options> >
303  {
304  enum {
305  NQ = 1,
306  NV = 1
307  };
308  typedef _Scalar Scalar;
309  enum { Options = _Options };
315  typedef BiasZero Bias_t;
316  typedef Eigen::Matrix<Scalar,6,NV,Options> F_t;
317 
318  // [ABA]
319  typedef Eigen::Matrix<Scalar,6,NV,Options> U_t;
320  typedef Eigen::Matrix<Scalar,NV,NV,Options> D_t;
321  typedef Eigen::Matrix<Scalar,6,NV,Options> UD_t;
322 
323  typedef Eigen::Matrix<Scalar,NQ,1,Options> ConfigVector_t;
324  typedef Eigen::Matrix<Scalar,NV,1,Options> TangentVector_t;
325 
326  };
327 
328  template<typename Scalar, int Options>
329  struct traits< JointDataRevoluteUnalignedTpl<Scalar,Options> >
331 
332  template<typename Scalar, int Options>
333  struct traits <JointModelRevoluteUnalignedTpl<Scalar,Options> >
335 
336  template<typename _Scalar, int _Options>
337  struct JointDataRevoluteUnalignedTpl : public JointDataBase< JointDataRevoluteUnalignedTpl<_Scalar,_Options> >
338  {
340  SE3_JOINT_TYPEDEF_TEMPLATE;
341 
342  Transformation_t M;
343  Constraint_t S;
344  Motion_t v;
345  Bias_t c;
346 
347  F_t F;
348 
349  // [ABA] specific data
350  U_t U;
351  D_t Dinv;
352  UD_t UDinv;
353 
355  : M(1),S(Eigen::Vector3d::Constant(NAN)),v(Eigen::Vector3d::Constant(NAN),NAN)
356  , U(), Dinv(), UDinv()
357  {}
358 
359  JointDataRevoluteUnalignedTpl(const Motion::Vector3 & axis)
360  : M(1),S(axis),v(axis,NAN)
361  , U(), Dinv(), UDinv()
362  {}
363 
364  }; // struct JointDataRevoluteUnalignedTpl
365 
366  template<typename _Scalar, int _Options>
367  struct JointModelRevoluteUnalignedTpl : public JointModelBase< JointModelRevoluteUnalignedTpl<_Scalar,_Options> >
368  {
370  SE3_JOINT_TYPEDEF_TEMPLATE;
371  typedef Eigen::Matrix<_Scalar,3,1,_Options> Vector3;
372 
377 
378  JointModelRevoluteUnalignedTpl() : axis(Eigen::Vector3d::Constant(NAN)) {}
379 
380  template<typename OtherScalar>
381  JointModelRevoluteUnalignedTpl(const OtherScalar x, const OtherScalar y, const OtherScalar z)
382  {
383  axis << x, y, z ;
384  axis.normalize();
385  assert(axis.isUnitary() && "Rotation axis is not unitary");
386  }
387 
388  template<typename Vector3Like>
389  JointModelRevoluteUnalignedTpl(const Eigen::MatrixBase<Vector3Like> & axis)
390  : axis(axis)
391  {
392  assert(axis.isUnitary() && "Rotation axis is not unitary");
393  }
394 
395  JointDataDerived createData() const { return JointDataDerived(axis); }
396 
397  template<typename ConfigVector>
398  void calc(JointDataDerived & data,
399  const typename Eigen::MatrixBase<ConfigVector> & qs) const
400  {
401  EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(ConfigVector_t,ConfigVector);
402  typedef typename ConfigVector::Scalar OtherScalar;
403  typedef Eigen::AngleAxis<Scalar> AngleAxis;
404 
405  const OtherScalar & q = qs[idx_q()];
406 
407  data.M.rotation(AngleAxis(q,axis).toRotationMatrix());
408  }
409 
410  template<typename ConfigVector, typename TangentVector>
411  void calc(JointDataDerived & data,
412  const typename Eigen::MatrixBase<ConfigVector> & qs,
413  const typename Eigen::MatrixBase<TangentVector> & vs) const
414  {
415  EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(TangentVector_t,TangentVector);
416  calc(data,qs.derived());
417 
418  data.v.w = (Scalar)vs[idx_v()];
419  }
420 
421  template<typename S2, int O2>
422  void calc_aba(JointDataDerived & data, Eigen::Matrix<S2,6,6,O2> & I, const bool update_I) const
423  {
424  data.U.noalias() = I.template middleCols<3>(Motion::ANGULAR) * axis;
425  data.Dinv[0] = (Scalar)(1)/axis.dot(data.U.template segment<3>(Motion::ANGULAR));
426  data.UDinv.noalias() = data.U * data.Dinv;
427 
428  if (update_I)
429  I -= data.UDinv * data.U.transpose();
430  }
431 
432  Scalar finiteDifferenceIncrement() const
433  {
434  using std::sqrt;
435  return 2.*sqrt(sqrt(Eigen::NumTraits<Scalar>::epsilon()));
436  }
437 
438  static std::string classname() { return std::string("JointModelRevoluteUnaligned"); }
439  std::string shortname() const { return classname(); }
440 
441  Vector3 axis;
442  }; // struct JointModelRevoluteUnalignedTpl
443 
444 } //namespace se3
445 
446 
447 #endif // ifndef __se3_joint_revolute_unaligned_hpp__
JointDataVariant createData(const JointModelVariant &jmodel)
Visit a JointModelVariant through CreateData visitor to create a JointDataVariant.
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...