pinocchio  2.1.3
joint-composite.hpp
1 //
2 // Copyright (c) 2016-2019 CNRS INRIA
3 //
4 
5 #ifndef __pinocchio_joint_composite_hpp__
6 #define __pinocchio_joint_composite_hpp__
7 
8 #include "pinocchio/multibody/joint/fwd.hpp"
9 #include "pinocchio/multibody/joint/joint-collection.hpp"
10 #include "pinocchio/multibody/joint/joint-basic-visitors.hpp"
11 #include "pinocchio/container/aligned-vector.hpp"
12 #include "pinocchio/spatial/act-on-set.hpp"
13 
14 #include "pinocchio/serialization/fwd.hpp"
15 
16 namespace pinocchio
17 {
18 
19  template<typename Scalar, int Options, template<typename S, int O> class JointCollectionTpl>
21 
22  template<typename _Scalar, int _Options, template<typename S, int O> class JointCollectionTpl>
23  struct traits< JointCompositeTpl<_Scalar,_Options,JointCollectionTpl> >
24  {
25  typedef _Scalar Scalar;
26 
27  enum {
28  Options = _Options,
29  NQ = Eigen::Dynamic,
30  NV = Eigen::Dynamic
31  };
32 
33  typedef JointCollectionTpl<Scalar,Options> JointCollection;
40 
41  typedef Eigen::Matrix<Scalar,6,Eigen::Dynamic,Options> F_t;
42  // [ABA]
43  typedef Eigen::Matrix<Scalar,6,Eigen::Dynamic,Options> U_t;
44  typedef Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic,Options> D_t;
45  typedef Eigen::Matrix<Scalar,6,Eigen::Dynamic,Options> UD_t;
46 
47  PINOCCHIO_JOINT_DATA_BASE_ACCESSOR_DEFAULT_RETURN_TYPE
48 
49  typedef Eigen::Matrix<Scalar,Eigen::Dynamic,1,Options> ConfigVector_t;
50  typedef Eigen::Matrix<Scalar,Eigen::Dynamic,1,Options> TangentVector_t;
51  };
52 
53  template<typename Scalar, int Options, template<typename S, int O> class JointCollectionTpl>
54  struct traits< JointModelCompositeTpl<Scalar,Options,JointCollectionTpl> >
56 
57  template<typename Scalar, int Options, template<typename S, int O> class JointCollectionTpl>
58  struct traits< JointDataCompositeTpl<Scalar,Options,JointCollectionTpl> >
60 
61  template<typename _Scalar, int _Options, template<typename S, int O> class JointCollectionTpl>
63  : public JointDataBase< JointDataCompositeTpl<_Scalar,_Options,JointCollectionTpl> >
64  {
65  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
66 
69  PINOCCHIO_JOINT_DATA_TYPEDEF_TEMPLATE;
70  PINOCCHIO_JOINT_DATA_BASE_DEFAULT_ACCESSOR
71 
72  typedef JointCollectionTpl<Scalar,Options> JointCollection;
73  typedef JointDataTpl<Scalar,Options,JointCollectionTpl> JointDataVariant;
74 
76 
77  // JointDataComposite() {} // can become necessary if we want a vector of JointDataComposite ?
78 
80  : joints()
81  , iMlast(0), pjMi(0)
82  , S(0)
83  , M(),v(),c()
84  , U(6,0), Dinv(0,0), UDinv(6,0)
85  , StU(0,0)
86  {}
87 
88 
89  JointDataCompositeTpl(const JointDataVector & joint_data, const int /*nq*/, const int nv)
90  : joints(joint_data), iMlast(joint_data.size()), pjMi(joint_data.size())
91  , S(nv)
92  , M(), v(), c()
93  , U(6,nv), Dinv(nv,nv), UDinv(6,nv)
94  , StU(nv,nv)
95  {}
96 
98  JointDataVector joints;
99 
102 
105 
106  Constraint_t S;
107  Transformation_t M;
108  Motion_t v;
109  Bias_t c;
110 
111  // // [ABA] specific data
112  U_t U;
113  D_t Dinv;
114  UD_t UDinv;
115 
116  D_t StU;
117 
118  static std::string classname() { return std::string("JointDataComposite"); }
119  std::string shortname() const { return classname(); }
120 
121  };
122 
123  template<typename Scalar, int Options, template<typename,int> class JointCollectionTpl>
124  inline std::ostream & operator <<(std::ostream & os, const JointDataCompositeTpl<Scalar,Options,JointCollectionTpl> & jdata)
125  {
127 
128  os << "JointDataComposite containing following models:\n" ;
129  for (typename JointDataVector::const_iterator it = jdata.joints.begin();
130  it != jdata.joints.end(); ++it)
131  os << " " << shortname(*it) << std::endl;
132  return os;
133  }
134 
135 
136  template<typename NewScalar, typename Scalar, int Options, template<typename S, int O> class JointCollectionTpl>
137  struct CastType< NewScalar, JointModelCompositeTpl<Scalar,Options,JointCollectionTpl> >
138  {
140  };
141 
142  template<typename _Scalar, int _Options, template<typename S, int O> class JointCollectionTpl>
144  : public JointModelBase< JointModelCompositeTpl<_Scalar,_Options,JointCollectionTpl> >
145  {
146  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
147 
150  PINOCCHIO_JOINT_TYPEDEF_TEMPLATE;
151 
152  typedef JointCollectionTpl<Scalar,Options> JointCollection;
153  typedef JointModelTpl<Scalar,Options,JointCollectionTpl> JointModelVariant;
154 
155  typedef SE3Tpl<Scalar,Options> SE3;
158 
160 
161  using Base::id;
162  using Base::idx_q;
163  using Base::idx_v;
164  using Base::setIndexes;
165  using Base::nq;
166  using Base::nv;
167 
170  : joints()
171  , jointPlacements()
172  , m_nq(0)
173  , m_nv(0)
174  , njoints(0)
175  {}
176 
178  JointModelCompositeTpl(const size_t size)
179  : joints()
180  , jointPlacements()
181  , m_nq(0)
182  , m_nv(0)
183  , njoints(0)
184  {
185  joints.reserve(size); jointPlacements.reserve(size);
186  m_idx_q.reserve(size); m_idx_v.reserve(size);
187  m_nqs.reserve(size); m_nvs.reserve(size);
188  }
189 
196  template<typename JointModel>
198  const SE3 & placement = SE3::Identity())
199  : joints(1,(JointModelVariant)jmodel.derived())
200  , jointPlacements(1,placement)
201  , m_nq(jmodel.nq())
202  , m_nv(jmodel.nv())
203  , m_idx_q(1,0), m_nqs(1,jmodel.nq())
204  , m_idx_v(1,0), m_nvs(1,jmodel.nv())
205  , njoints(1)
206  {}
207 
214  : Base(other)
215  , joints(other.joints)
216  , jointPlacements(other.jointPlacements)
217  , m_nq(other.m_nq)
218  , m_nv(other.m_nv)
219  , m_idx_q(other.m_idx_q), m_nqs(other.m_nqs)
220  , m_idx_v(other.m_idx_v), m_nvs(other.m_nvs)
221  , njoints(other.njoints)
222  {}
223 
224 
233  template<typename JointModel>
234  JointModelDerived & addJoint(const JointModelBase<JointModel> & jmodel,
235  const SE3 & placement = SE3::Identity())
236  {
237  joints.push_back((JointModelVariant)jmodel.derived());
238  jointPlacements.push_back(placement);
239 
240  m_nq += jmodel.nq(); m_nv += jmodel.nv();
241 
242  updateJointIndexes();
243  njoints++;
244 
245  return *this;
246  }
247 
248  JointDataDerived createData() const
249  {
250  typename JointDataDerived::JointDataVector jdata(joints.size());
251  for (int i = 0; i < (int)joints.size(); ++i)
252  jdata[(size_t)i] = ::pinocchio::createData<Scalar,Options,JointCollectionTpl>(joints[(size_t)i]);
253  return JointDataDerived(jdata,nq(),nv());
254  }
255 
256  template<typename, int, template<typename S, int O> class, typename>
257  friend struct JointCompositeCalcZeroOrderStep;
258 
259  template<typename ConfigVectorType>
260  void calc(JointDataDerived & data, const Eigen::MatrixBase<ConfigVectorType> & qs) const;
261 
262  template<typename, int, template<typename S, int O> class, typename, typename>
263  friend struct JointCompositeCalcFirstOrderStep;
264 
265  template<typename ConfigVectorType, typename TangentVectorType>
266  void calc(JointDataDerived & data,
267  const Eigen::MatrixBase<ConfigVectorType> & qs,
268  const Eigen::MatrixBase<TangentVectorType> & vs) const;
269 
270  template<typename Matrix6Like>
271  void calc_aba(JointDataDerived & data, const Eigen::MatrixBase<Matrix6Like> & I, const bool update_I) const
272  {
273  data.U.noalias() = I * data.S.matrix();
274  data.StU.noalias() = data.S.matrix().transpose() * data.U;
275 
276  // compute inverse
277  data.Dinv.setIdentity();
278  data.StU.llt().solveInPlace(data.Dinv);
279  data.UDinv.noalias() = data.U * data.Dinv;
280 
281  if (update_I)
282  PINOCCHIO_EIGEN_CONST_CAST(Matrix6Like,I) -= data.UDinv * data.U.transpose();
283  }
284 
285  Scalar finiteDifferenceIncrement() const
286  {
287  using std::max;
288  Scalar eps = 0;
289  for(typename JointModelVector::const_iterator it = joints.begin();
290  it != joints.end(); ++it)
291  eps = max((Scalar)::pinocchio::finiteDifferenceIncrement(*it),eps);
292 
293  return eps;
294  }
295 
296  int nv_impl() const { return m_nv; }
297  int nq_impl() const { return m_nq; }
298 
302  void setIndexes_impl(JointIndex id, int q, int v)
303  {
304  Base::setIndexes_impl(id, q, v);
305  updateJointIndexes();
306  }
307 
308  static std::string classname() { return std::string("JointModelComposite"); }
309  std::string shortname() const { return classname(); }
310 
311  JointModelCompositeTpl & operator=(const JointModelCompositeTpl & other)
312  {
313  Base::operator=(other);
314  m_nq = other.m_nq;
315  m_nv = other.m_nv;
316  m_idx_q = other.m_idx_q;
317  m_idx_v = other.m_idx_v;
318  m_nqs = other.m_nqs;
319  m_nvs = other.m_nvs;
320  joints = other.joints;
321  jointPlacements = other.jointPlacements;
322  njoints = other.njoints;
323 
324  return *this;
325  }
326 
327  using Base::isEqual;
328  bool isEqual(const JointModelCompositeTpl & other) const
329  {
330  return Base::isEqual(other)
331  && nq() == other.nq()
332  && nv() == other.nv()
333  && m_idx_q == other.m_idx_q
334  && m_idx_v == other.m_idx_v
335  && m_nqs == other.m_nqs
336  && m_nvs == other.m_nvs
337  && joints == other.joints
338  && jointPlacements == other.jointPlacements
339  && njoints == other.njoints;
340  }
341 
343  template<typename NewScalar>
345  {
347  ReturnType res((size_t)njoints);
348  res.setIndexes(id(),idx_q(),idx_v());
349  res.m_nq = m_nq;
350  res.m_nv = m_nv;
351  res.m_idx_q = m_idx_q;
352  res.m_idx_v = m_idx_v;
353  res.m_nqs = m_nqs;
354  res.m_nvs = m_nvs;
355  res.njoints = njoints;
356 
357  res.joints.resize(joints.size());
358  res.jointPlacements.resize(jointPlacements.size());
359  for(size_t k = 0; k < jointPlacements.size(); ++k)
360  {
361  res.joints[k] = joints[k].template cast<NewScalar>();
362  res.jointPlacements[k] = jointPlacements[k].template cast<NewScalar>();
363  }
364 
365  return res;
366  }
367 
369  JointModelVector joints;
372 
373  template<typename D>
374  typename SizeDepType<NQ>::template SegmentReturn<D>::ConstType
375  jointConfigSelector(const Eigen::MatrixBase<D>& a) const { return a.segment(Base::i_q,nq()); }
376  template<typename D>
377  typename SizeDepType<NQ>::template SegmentReturn<D>::Type
378  jointConfigSelector( Eigen::MatrixBase<D>& a) const { return a.segment(Base::i_q,nq()); }
379 
380  template<typename D>
381  typename SizeDepType<NV>::template SegmentReturn<D>::ConstType
382  jointVelocitySelector(const Eigen::MatrixBase<D>& a) const { return a.segment(Base::i_v,nv()); }
383  template<typename D>
384  typename SizeDepType<NV>::template SegmentReturn<D>::Type
385  jointVelocitySelector( Eigen::MatrixBase<D>& a) const { return a.segment(Base::i_v,nv()); }
386 
387  template<typename D>
388  typename SizeDepType<NV>::template ColsReturn<D>::ConstType
389  jointCols(const Eigen::MatrixBase<D>& A) const { return A.middleCols(Base::i_v,nv()); }
390  template<typename D>
391  typename SizeDepType<NV>::template ColsReturn<D>::Type
392  jointCols(Eigen::MatrixBase<D>& A) const { return A.middleCols(Base::i_v,nv()); }
393 
394  template<typename D>
395  typename SizeDepType<Eigen::Dynamic>::template SegmentReturn<D>::ConstType
396  jointConfigSelector_impl(const Eigen::MatrixBase<D>& a) const { return a.segment(Base::i_q,nq()); }
397  template<typename D>
398  typename SizeDepType<Eigen::Dynamic>::template SegmentReturn<D>::Type
399  jointConfigSelector_impl(Eigen::MatrixBase<D>& a) const { return a.segment(Base::i_q,nq()); }
400  template<typename D>
401  typename SizeDepType<Eigen::Dynamic>::template SegmentReturn<D>::ConstType
402  jointVelocitySelector_impl(const Eigen::MatrixBase<D>& a) const { return a.segment(Base::i_v,nv()); }
403  template<typename D>
404  typename SizeDepType<Eigen::Dynamic>::template SegmentReturn<D>::Type
405  jointVelocitySelector_impl(Eigen::MatrixBase<D>& a) const { return a.segment(Base::i_v,nv()); }
406 
407  template<typename D>
408  typename SizeDepType<Eigen::Dynamic>::template ColsReturn<D>::ConstType
409  jointCols_impl(const Eigen::MatrixBase<D>& A) const { return A.middleCols(Base::i_v,nv()); }
410  template<typename D>
411  typename SizeDepType<Eigen::Dynamic>::template ColsReturn<D>::Type
412  jointCols_impl(Eigen::MatrixBase<D>& A) const { return A.middleCols(Base::i_v,nv()); }
413 
414 
415  protected:
416 
417  friend struct Serialize<JointModelCompositeTpl>;
418 
419  template<typename, int, template<typename,int> class>
420  friend struct JointModelCompositeTpl;
421 
425  {
426  int idx_q = this->idx_q();
427  int idx_v = this->idx_v();
428 
429  m_idx_q.resize(joints.size());
430  m_idx_v.resize(joints.size());
431  m_nqs.resize(joints.size());
432  m_nvs.resize(joints.size());
433 
434  for(size_t i = 0; i < joints.size(); ++i)
435  {
436  JointModelVariant & joint = joints[i];
437 
438  m_idx_q[i] = idx_q; m_idx_v[i] = idx_v;
439  ::pinocchio::setIndexes(joint,i,idx_q,idx_v);
440  m_nqs[i] = ::pinocchio::nq(joint);
441  m_nvs[i] = ::pinocchio::nv(joint);
442  idx_q += m_nqs[i]; idx_v += m_nvs[i];
443  }
444  }
445 
446 
448  int m_nq, m_nv;
449 
451 
453  std::vector<int> m_idx_q;
455  std::vector<int> m_nqs;
457  std::vector<int> m_idx_v;
459  std::vector<int> m_nvs;
460 
461  public:
463  int njoints;
464  };
465 
466 
467  template<typename Scalar, int Options, template<typename,int> class JointCollectionTpl>
468  inline std::ostream & operator <<(std::ostream & os, const JointModelCompositeTpl<Scalar,Options,JointCollectionTpl> & jmodel)
469  {
471 
472  os << "JointModelComposite containing following models:\n" ;
473  for (typename JointModelVector::const_iterator it = jmodel.joints.begin();
474  it != jmodel.joints.end(); ++it)
475  os << " " << shortname(*it) << std::endl;
476 
477  return os;
478  }
479 
480 } // namespace pinocchio
481 
482 #include <boost/type_traits.hpp>
483 
484 namespace boost
485 {
486  template<typename Scalar, int Options, template<typename S, int O> class JointCollectionTpl>
487  struct has_nothrow_constructor< ::pinocchio::JointModelCompositeTpl<Scalar,Options,JointCollectionTpl> >
488  : public integral_constant<bool,true> {};
489 
490  template<typename Scalar, int Options, template<typename S, int O> class JointCollectionTpl>
491  struct has_nothrow_copy< ::pinocchio::JointModelCompositeTpl<Scalar,Options,JointCollectionTpl> >
492  : public integral_constant<bool,true> {};
493 
494  template<typename Scalar, int Options, template<typename S, int O> class JointCollectionTpl>
495  struct has_nothrow_constructor< ::pinocchio::JointDataCompositeTpl<Scalar,Options,JointCollectionTpl> >
496  : public integral_constant<bool,true> {};
497 
498  template<typename Scalar, int Options, template<typename S, int O> class JointCollectionTpl>
499  struct has_nothrow_copy< ::pinocchio::JointDataCompositeTpl<Scalar,Options,JointCollectionTpl> >
500  : public integral_constant<bool,true> {};
501 }
502 
503 /* --- Details -------------------------------------------------------------- */
504 /* --- Details -------------------------------------------------------------- */
505 /* --- Details -------------------------------------------------------------- */
506 #include "pinocchio/multibody/joint/joint-composite.hxx"
507 
508 #endif // ifndef __pinocchio_joint_composite_hpp__
int nv(const JointModelTpl< Scalar, Options, JointCollectionTpl > &jmodel)
Visit a JointModelTpl through JointNvVisitor to get the dimension of the joint tangent space...
std::vector< int > m_nvs
Dimension of the segment in the tangent vector.
int idx_q(const JointModelTpl< Scalar, Options, JointCollectionTpl > &jmodel)
Visit a JointModelTpl through JointIdxQVisitor to get the index in the full model configuration space...
std::vector< int > m_idx_v
Index in the tangent vector.
void updateJointIndexes()
Update the indexes of the joints contained in the composition according to the position of the joint ...
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...
int nq(const JointModelTpl< Scalar, Options, JointCollectionTpl > &jmodel)
Visit a JointModelTpl through JointNqVisitor to get the dimension of the joint configuration space...
JointModelCompositeTpl< NewScalar, Options, JointCollectionTpl > cast() const
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::vector< int > m_idx_q
Keep information of both the dimension and the position of the joints in the composition.
JointModelCompositeTpl(const JointModelBase< JointModel > &jmodel, const SE3 &placement=SE3::Identity())
Constructor with one joint.
JointModelCompositeTpl()
Default contructor.
JointDataVector joints
Vector of joints.
std::string shortname(const JointModelTpl< Scalar, Options, JointCollectionTpl > &jmodel)
Visit a JointModelTpl through JointShortnameVisitor to get the shortname of the derived joint model...
void setIndexes_impl(JointIndex id, int q, int v)
Update the indexes of subjoints in the stack.
JointModelDerived & addJoint(const JointModelBase< JointModel > &jmodel, const SE3 &placement=SE3::Identity())
Add a joint to the vector of joints.
JointModelCompositeTpl(const JointModelCompositeTpl &other)
Copy constructor.
container::aligned_vector< Transformation_t > pjMi
Transforms from previous joint to joint i.
container::aligned_vector< Transformation_t > iMlast
Transforms from previous joint to last joint.
std::vector< int > m_nqs
Dimension of the segment in the config vector.
JointModelCompositeTpl(const size_t size)
Default contructor with a defined size.
Main pinocchio namespace.
Definition: treeview.dox:24
JointModelVector joints
Vector of joints contained in the joint composite.
container::aligned_vector< SE3 > jointPlacements
Vector of joint placements. Those placements correspond to the origin of the joint relatively to thei...
Common traits structure to fully define base classes for CRTP.
Definition: spatial/fwd.hpp:29
int m_nq
Dimensions of the config and tangent space of the composite joint.
Type of the cast of a class C templated by Scalar and Options, to a new NewScalar type...
Definition: spatial/fwd.hpp:35
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...
int njoints
Number of joints contained in the JointModelComposite.