pinocchio  3.3.1
A fast and flexible implementation of Rigid Body Dynamics algorithms and their analytical derivatives
joint-composite.hpp
1 //
2 // Copyright (c) 2016-2021 CNRS INRIA
3 //
4 
5 #ifndef __pinocchio_multibody_joint_composite_hpp__
6 #define __pinocchio_multibody_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  {
29  Options = _Options,
30  NQ = Eigen::Dynamic,
31  NV = Eigen::Dynamic
32  };
33 
34  typedef JointCollectionTpl<Scalar, Options> JointCollection;
41 
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  typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 1, Options> ConfigVector_t;
48  typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 1, Options> TangentVector_t;
49 
50  PINOCCHIO_JOINT_DATA_BASE_ACCESSOR_DEFAULT_RETURN_TYPE
51  };
52 
53  template<typename _Scalar, int _Options, template<typename S, int O> class JointCollectionTpl>
54  struct traits<JointModelCompositeTpl<_Scalar, _Options, JointCollectionTpl>>
55  {
57  typedef _Scalar Scalar;
58  };
59 
60  template<typename _Scalar, int _Options, template<typename S, int O> class JointCollectionTpl>
61  struct traits<JointDataCompositeTpl<_Scalar, _Options, JointCollectionTpl>>
62  {
64  typedef _Scalar Scalar;
65  };
66 
67  template<typename _Scalar, int _Options, template<typename S, int O> class JointCollectionTpl>
69  : public JointDataBase<JointDataCompositeTpl<_Scalar, _Options, JointCollectionTpl>>
70  {
71  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
72 
75  PINOCCHIO_JOINT_DATA_TYPEDEF_TEMPLATE(JointDerived);
76  PINOCCHIO_JOINT_DATA_BASE_DEFAULT_ACCESSOR
77 
78  typedef JointCollectionTpl<Scalar, Options> JointCollection;
80 
81  typedef PINOCCHIO_ALIGNED_STD_VECTOR(JointDataVariant) JointDataVector;
82 
83  // JointDataComposite() {} // can become necessary if we want a vector of JointDataComposite ?
84 
86  : joints()
87  , iMlast(0)
88  , pjMi(0)
89  , joint_q(ConfigVector_t::Zero(0))
90  , joint_v(TangentVector_t::Zero(0))
91  , S(0)
92  , M(Transformation_t::Identity())
93  , v(Motion_t::Zero())
94  , c(Motion_t::Zero())
95  , U(6, 0)
96  , Dinv(0, 0)
97  , UDinv(6, 0)
98  , StU(0, 0)
99  {
100  }
101 
102  JointDataCompositeTpl(const JointDataVector & joint_data, const int nq, const int nv)
103  : joints(joint_data)
104  , iMlast(joint_data.size())
105  , pjMi(joint_data.size())
106  , joint_q(ConfigVector_t::Zero(nq))
107  , joint_v(TangentVector_t::Zero(nv))
108  , S(Constraint_t::Zero(nv))
109  , M(Transformation_t::Identity())
110  , v(Motion_t::Zero())
111  , c(Motion_t::Zero())
112  , U(U_t::Zero(6, nv))
113  , Dinv(D_t::Zero(nv, nv))
114  , UDinv(UD_t::Zero(6, nv))
115  , StU(D_t::Zero(nv, nv))
116  {
117  }
118 
120  JointDataVector joints;
121 
123  PINOCCHIO_ALIGNED_STD_VECTOR(Transformation_t) iMlast;
124 
126  PINOCCHIO_ALIGNED_STD_VECTOR(Transformation_t) pjMi;
127 
128  ConfigVector_t joint_q;
129  TangentVector_t joint_v;
130 
131  Constraint_t S;
132  Transformation_t M;
133  Motion_t v;
134  Bias_t c;
135 
136  // // [ABA] specific data
137  U_t U;
138  D_t Dinv;
139  UD_t UDinv;
140  D_t StU;
141 
142  static std::string classname()
143  {
144  return std::string("JointDataComposite");
145  }
146  std::string shortname() const
147  {
148  return classname();
149  }
150  };
151 
152  template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl>
153  inline std::ostream & operator<<(
154  std::ostream & os, const JointDataCompositeTpl<Scalar, Options, JointCollectionTpl> & jdata)
155  {
156  typedef typename JointDataCompositeTpl<Scalar, Options, JointCollectionTpl>::JointDataVector
157  JointDataVector;
158 
159  os << "JointDataComposite containing following models:\n";
160  for (typename JointDataVector::const_iterator it = jdata.joints.begin();
161  it != jdata.joints.end(); ++it)
162  os << " " << shortname(*it) << std::endl;
163  return os;
164  }
165 
166  template<
167  typename NewScalar,
168  typename Scalar,
169  int Options,
170  template<typename S, int O> class JointCollectionTpl>
171  struct CastType<NewScalar, JointModelCompositeTpl<Scalar, Options, JointCollectionTpl>>
172  {
174  };
175 
176  template<typename _Scalar, int _Options, template<typename S, int O> class JointCollectionTpl>
178  : public JointModelBase<JointModelCompositeTpl<_Scalar, _Options, JointCollectionTpl>>
179  {
180  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
181 
184  PINOCCHIO_JOINT_TYPEDEF_TEMPLATE(JointDerived);
185 
186  typedef JointCollectionTpl<Scalar, Options> JointCollection;
188 
192 
193  typedef PINOCCHIO_ALIGNED_STD_VECTOR(JointModelVariant) JointModelVector;
194 
195  using Base::id;
196  using Base::idx_q;
197  using Base::idx_v;
198  using Base::nq;
199  using Base::nv;
200  using Base::setIndexes;
201 
204  : joints()
205  , jointPlacements()
206  , m_nq(0)
207  , m_nv(0)
208  , njoints(0)
209  {
210  }
211 
213  JointModelCompositeTpl(const size_t size)
214  : joints()
215  , jointPlacements()
216  , m_nq(0)
217  , m_nv(0)
218  , njoints(0)
219  {
220  joints.reserve(size);
221  jointPlacements.reserve(size);
222  m_idx_q.reserve(size);
223  m_idx_v.reserve(size);
224  m_nqs.reserve(size);
225  m_nvs.reserve(size);
226  }
227 
234  template<typename JointModel>
236  const JointModelBase<JointModel> & jmodel, const SE3 & placement = SE3::Identity())
237  : joints(1, (JointModelVariant)jmodel.derived())
238  , jointPlacements(1, placement)
239  , m_nq(jmodel.nq())
240  , m_nv(jmodel.nv())
241  , m_idx_q(1, 0)
242  , m_nqs(1, jmodel.nq())
243  , m_idx_v(1, 0)
244  , m_nvs(1, jmodel.nv())
245  , njoints(1)
246  {
247  }
248 
255  : Base(other)
256  , joints(other.joints)
257  , jointPlacements(other.jointPlacements)
258  , m_nq(other.m_nq)
259  , m_nv(other.m_nv)
260  , m_idx_q(other.m_idx_q)
261  , m_nqs(other.m_nqs)
262  , m_idx_v(other.m_idx_v)
263  , m_nvs(other.m_nvs)
264  , njoints(other.njoints)
265  {
266  }
267 
276  template<typename JointModel>
277  JointModelDerived &
278  addJoint(const JointModelBase<JointModel> & jmodel, const SE3 & placement = SE3::Identity())
279  {
280  joints.push_back((JointModelVariant)jmodel.derived());
281  jointPlacements.push_back(placement);
282 
283  m_nq += jmodel.nq();
284  m_nv += jmodel.nv();
285 
287  njoints++;
288 
289  return *this;
290  }
291 
292  JointDataDerived createData() const
293  {
294  typename JointDataDerived::JointDataVector jdata(joints.size());
295  for (int i = 0; i < (int)joints.size(); ++i)
296  jdata[(size_t)i] =
297  ::pinocchio::createData<Scalar, Options, JointCollectionTpl>(joints[(size_t)i]);
298  return JointDataDerived(jdata, nq(), nv());
299  }
300 
301  const std::vector<bool> hasConfigurationLimit() const
302  {
303  std::vector<bool> vec;
304  for (size_t i = 0; i < joints.size(); ++i)
305  {
306  const std::vector<bool> & joint_cf_limit = joints[i].hasConfigurationLimit();
307  vec.insert(vec.end(), joint_cf_limit.begin(), joint_cf_limit.end());
308  }
309  return vec;
310  }
311 
312  const std::vector<bool> hasConfigurationLimitInTangent() const
313  {
314  std::vector<bool> vec;
315  for (size_t i = 0; i < joints.size(); ++i)
316  {
317  const std::vector<bool> & joint_cf_limit = joints[i].hasConfigurationLimitInTangent();
318  vec.insert(vec.end(), joint_cf_limit.begin(), joint_cf_limit.end());
319  }
320  return vec;
321  }
322 
323  template<typename, int, template<typename S, int O> class, typename>
324  friend struct JointCompositeCalcZeroOrderStep;
325 
326  template<typename ConfigVectorType>
327  void calc(JointDataDerived & data, const Eigen::MatrixBase<ConfigVectorType> & qs) const;
328 
329  template<typename, int, template<typename S, int O> class, typename, typename>
330  friend struct JointCompositeCalcFirstOrderStep;
331 
332  template<typename ConfigVectorType, typename TangentVectorType>
333  void calc(
334  JointDataDerived & data,
335  const Eigen::MatrixBase<ConfigVectorType> & qs,
336  const Eigen::MatrixBase<TangentVectorType> & vs) const;
337 
338  template<typename TangentVectorType>
339  void calc(
340  JointDataDerived & data,
341  const Blank blank,
342  const Eigen::MatrixBase<TangentVectorType> & vs) const;
343 
344  template<typename VectorLike, typename Matrix6Like>
345  void calc_aba(
346  JointDataDerived & data,
347  const Eigen::MatrixBase<VectorLike> & armature,
348  const Eigen::MatrixBase<Matrix6Like> & I,
349  const bool update_I) const
350  {
351  data.U.noalias() = I * data.S.matrix();
352  data.StU.noalias() = data.S.matrix().transpose() * data.U;
353  data.StU.diagonal() += armature;
354 
355  internal::PerformStYSInversion<Scalar>::run(data.StU, data.Dinv);
356  data.UDinv.noalias() = data.U * data.Dinv;
357 
358  if (update_I)
359  PINOCCHIO_EIGEN_CONST_CAST(Matrix6Like, I).noalias() -= data.UDinv * data.U.transpose();
360  }
361 
362  int nv_impl() const
363  {
364  return m_nv;
365  }
366  int nq_impl() const
367  {
368  return m_nq;
369  }
370 
374  void setIndexes_impl(JointIndex id, int q, int v)
375  {
376  Base::setIndexes_impl(id, q, v);
378  }
379 
380  static std::string classname()
381  {
382  return std::string("JointModelComposite");
383  }
384  std::string shortname() const
385  {
386  return classname();
387  }
388 
389  JointModelCompositeTpl & operator=(const JointModelCompositeTpl & other)
390  {
391  Base::operator=(other);
392  m_nq = other.m_nq;
393  m_nv = other.m_nv;
394  m_idx_q = other.m_idx_q;
395  m_idx_v = other.m_idx_v;
396  m_nqs = other.m_nqs;
397  m_nvs = other.m_nvs;
398  joints = other.joints;
399  jointPlacements = other.jointPlacements;
400  njoints = other.njoints;
401 
402  return *this;
403  }
404 
405  using Base::isEqual;
406  bool isEqual(const JointModelCompositeTpl & other) const
407  {
408  return Base::isEqual(other) && internal::comparison_eq(nq(), other.nq())
409  && internal::comparison_eq(nv(), other.nv())
410  && internal::comparison_eq(m_idx_q, other.m_idx_q)
411  && internal::comparison_eq(m_idx_v, other.m_idx_v)
412  && internal::comparison_eq(m_nqs, other.m_nqs)
413  && internal::comparison_eq(m_nvs, other.m_nvs)
414  && internal::comparison_eq(joints, other.joints)
415  && internal::comparison_eq(jointPlacements, other.jointPlacements)
416  && internal::comparison_eq(njoints, other.njoints);
417  }
418 
420  template<typename NewScalar>
422  {
424  ReturnType res((size_t)njoints);
425  res.setIndexes(id(), idx_q(), idx_v());
426  res.m_nq = m_nq;
427  res.m_nv = m_nv;
428  res.m_idx_q = m_idx_q;
429  res.m_idx_v = m_idx_v;
430  res.m_nqs = m_nqs;
431  res.m_nvs = m_nvs;
432  res.njoints = njoints;
433 
434  res.joints.resize(joints.size());
435  res.jointPlacements.resize(jointPlacements.size());
436  for (size_t k = 0; k < jointPlacements.size(); ++k)
437  {
438  res.joints[k] = joints[k].template cast<NewScalar>();
439  res.jointPlacements[k] = jointPlacements[k].template cast<NewScalar>();
440  }
441 
442  return res;
443  }
444 
446  JointModelVector joints;
450 
451  template<typename D>
452  typename SizeDepType<NQ>::template SegmentReturn<D>::ConstType
453  jointConfigSelector(const Eigen::MatrixBase<D> & a) const
454  {
455  return a.segment(Base::i_q, nq());
456  }
457  template<typename D>
458  typename SizeDepType<NQ>::template SegmentReturn<D>::Type
459  jointConfigSelector(Eigen::MatrixBase<D> & a) const
460  {
461  return a.segment(Base::i_q, nq());
462  }
463 
464  template<typename D>
465  typename SizeDepType<NV>::template SegmentReturn<D>::ConstType
466  jointVelocitySelector(const Eigen::MatrixBase<D> & a) const
467  {
468  return a.segment(Base::i_v, nv());
469  }
470  template<typename D>
471  typename SizeDepType<NV>::template SegmentReturn<D>::Type
472  jointVelocitySelector(Eigen::MatrixBase<D> & a) const
473  {
474  return a.segment(Base::i_v, nv());
475  }
476 
477  template<typename D>
478  typename SizeDepType<NV>::template ColsReturn<D>::ConstType
479  jointCols(const Eigen::MatrixBase<D> & A) const
480  {
481  return A.middleCols(Base::i_v, nv());
482  }
483  template<typename D>
484  typename SizeDepType<NV>::template ColsReturn<D>::Type jointCols(Eigen::MatrixBase<D> & A) const
485  {
486  return A.middleCols(Base::i_v, nv());
487  }
488 
489  template<typename D>
490  typename SizeDepType<Eigen::Dynamic>::template SegmentReturn<D>::ConstType
491  jointConfigSelector_impl(const Eigen::MatrixBase<D> & a) const
492  {
493  return a.segment(Base::i_q, nq());
494  }
495  template<typename D>
496  typename SizeDepType<Eigen::Dynamic>::template SegmentReturn<D>::Type
497  jointConfigSelector_impl(Eigen::MatrixBase<D> & a) const
498  {
499  return a.segment(Base::i_q, nq());
500  }
501  template<typename D>
502  typename SizeDepType<Eigen::Dynamic>::template SegmentReturn<D>::ConstType
503  jointVelocitySelector_impl(const Eigen::MatrixBase<D> & a) const
504  {
505  return a.segment(Base::i_v, nv());
506  }
507  template<typename D>
508  typename SizeDepType<Eigen::Dynamic>::template SegmentReturn<D>::Type
509  jointVelocitySelector_impl(Eigen::MatrixBase<D> & a) const
510  {
511  return a.segment(Base::i_v, nv());
512  }
513 
514  template<typename D>
515  typename SizeDepType<Eigen::Dynamic>::template ColsReturn<D>::ConstType
516  jointCols_impl(const Eigen::MatrixBase<D> & A) const
517  {
518  return A.middleCols(Base::i_v, nv());
519  }
520  template<typename D>
521  typename SizeDepType<Eigen::Dynamic>::template ColsReturn<D>::Type
522  jointCols_impl(Eigen::MatrixBase<D> & A) const
523  {
524  return A.middleCols(Base::i_v, nv());
525  }
526 
527  protected:
528  friend struct Serialize<JointModelCompositeTpl>;
529 
530  template<typename, int, template<typename, int> class>
531  friend struct JointModelCompositeTpl;
532 
536  {
537  int idx_q = this->idx_q();
538  int idx_v = this->idx_v();
539 
540  m_idx_q.resize(joints.size());
541  m_idx_v.resize(joints.size());
542  m_nqs.resize(joints.size());
543  m_nvs.resize(joints.size());
544 
545  for (size_t i = 0; i < joints.size(); ++i)
546  {
547  JointModelVariant & joint = joints[i];
548 
549  m_idx_q[i] = idx_q;
550  m_idx_v[i] = idx_v;
551  ::pinocchio::setIndexes(joint, i, idx_q, idx_v);
552  m_nqs[i] = ::pinocchio::nq(joint);
553  m_nvs[i] = ::pinocchio::nv(joint);
554  idx_q += m_nqs[i];
555  idx_v += m_nvs[i];
556  }
557  }
558 
560  int m_nq, m_nv;
561 
563 
565  std::vector<int> m_idx_q;
567  std::vector<int> m_nqs;
569  std::vector<int> m_idx_v;
571  std::vector<int> m_nvs;
572 
573  public:
575  int njoints;
576  };
577 
578  template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl>
579  inline std::ostream & operator<<(
580  std::ostream & os, const JointModelCompositeTpl<Scalar, Options, JointCollectionTpl> & jmodel)
581  {
583  JointModelVector;
584 
585  os << "JointModelComposite containing following models:\n";
586  for (typename JointModelVector::const_iterator it = jmodel.joints.begin();
587  it != jmodel.joints.end(); ++it)
588  os << " " << shortname(*it) << std::endl;
589 
590  return os;
591  }
592 
593 } // namespace pinocchio
594 
595 #include <boost/type_traits.hpp>
596 
597 namespace boost
598 {
599  template<typename Scalar, int Options, template<typename S, int O> class JointCollectionTpl>
600  struct has_nothrow_constructor<
601  ::pinocchio::JointModelCompositeTpl<Scalar, Options, JointCollectionTpl>>
602  : public integral_constant<bool, true>
603  {
604  };
605 
606  template<typename Scalar, int Options, template<typename S, int O> class JointCollectionTpl>
607  struct has_nothrow_copy<::pinocchio::JointModelCompositeTpl<Scalar, Options, JointCollectionTpl>>
608  : public integral_constant<bool, true>
609  {
610  };
611 
612  template<typename Scalar, int Options, template<typename S, int O> class JointCollectionTpl>
613  struct has_nothrow_constructor<
614  ::pinocchio::JointDataCompositeTpl<Scalar, Options, JointCollectionTpl>>
615  : public integral_constant<bool, true>
616  {
617  };
618 
619  template<typename Scalar, int Options, template<typename S, int O> class JointCollectionTpl>
620  struct has_nothrow_copy<::pinocchio::JointDataCompositeTpl<Scalar, Options, JointCollectionTpl>>
621  : public integral_constant<bool, true>
622  {
623  };
624 } // namespace boost
625 
626 /* --- Details -------------------------------------------------------------- */
627 /* --- Details -------------------------------------------------------------- */
628 /* --- Details -------------------------------------------------------------- */
629 #include "pinocchio/multibody/joint/joint-composite.hxx"
630 
631 #endif // ifndef __pinocchio_multibody_joint_composite_hpp__
Main pinocchio namespace.
Definition: treeview.dox:11
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 nv(const JointModelTpl< Scalar, Options, JointCollectionTpl > &jmodel)
Visit a JointModelTpl through JointNvVisitor to get the dimension of the joint tangent space.
int nq(const JointModelTpl< Scalar, Options, JointCollectionTpl > &jmodel)
Visit a JointModelTpl through JointNqVisitor to get the dimension of the joint configuration space.
std::string shortname(const JointModelTpl< Scalar, Options, JointCollectionTpl > &jmodel)
Visit a JointModelTpl through JointShortnameVisitor to get the shortname of the derived joint model.
int idx_q(const JointModelTpl< Scalar, Options, JointCollectionTpl > &jmodel)
Visit a JointModelTpl through JointIdxQVisitor to get the index in the full model configuration space...
Type of the cast of a class C templated by Scalar and Options, to a new NewScalar type....
Definition: fwd.hpp:99
JointDataVector joints
Vector of joints.
PINOCCHIO_ALIGNED_STD_VECTOR(Transformation_t) pjMi
Transforms from previous joint to joint i.
PINOCCHIO_ALIGNED_STD_VECTOR(Transformation_t) iMlast
Transforms from previous joint to last joint.
JointModelBase & operator=(const JointModelBase &clone)
JointModelCompositeTpl(const size_t size)
Default contructor with a defined size.
JointModelDerived & addJoint(const JointModelBase< JointModel > &jmodel, const SE3 &placement=SE3::Identity())
Add a joint to the vector of joints.
JointModelCompositeTpl()
Default contructor.
JointModelCompositeTpl(const JointModelCompositeTpl &other)
Copy constructor.
PINOCCHIO_ALIGNED_STD_VECTOR(SE3) jointPlacements
Vector of joint placements. Those placements correspond to the origin of the joint relatively to thei...
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.
std::vector< int > m_nvs
Dimension of the segment in the tangent vector.
JointModelVector joints
Vector of joints contained in the joint composite.
void setIndexes_impl(JointIndex id, int q, int v)
Update the indexes of subjoints in the stack.
std::vector< int > m_nqs
Dimension of the segment in the config vector.
JointModelCompositeTpl< NewScalar, Options, JointCollectionTpl > cast() const
std::vector< int > m_idx_v
Index in the tangent vector.
int njoints
Number of joints contained in the JointModelComposite.
void updateJointIndexes()
Update the indexes of the joints contained in the composition according to the position of the joint ...
int m_nq
Dimensions of the config and tangent space of the composite joint.
Common traits structure to fully define base classes for CRTP.
Definition: fwd.hpp:72