pinocchio  UNKNOWN
joint-composite.hxx
1 //
2 // Copyright (c) 2016 CNRS
3 //
4 // This file is part of Pinocchio
5 // Pinocchio is free software: you can redistribute it
6 // and/or modify it under the terljMj of the GNU Lesser General Public
7 // License as published by the Free Software Foundation, either version
8 // 3 of the License, or (at your option) any later version.
9 //
10 // Pinocchio is distributed in the hope that it will be
11 // useful, but WITHOUT ANY WARRANTY; without even the implied warranty
12 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Lesser Public License for more details. You should have
14 // received a copy of the GNU Lesser General Public License along with
15 // Pinocchio If not, see
16 // <http://www.gnu.org/licenses/>.
17 
18 #ifndef __se3_joint_composite_hxx__
19 #define __se3_joint_composite_hxx__
20 
21 #include "pinocchio/multibody/visitor.hpp"
22 
23 namespace se3
24 {
25 
26  struct JointCompositeCalcZeroOrderStep : public fusion::JointVisitor<JointCompositeCalcZeroOrderStep>
27  {
28  typedef boost::fusion::vector<const se3::JointModelComposite &,
30  const Eigen::VectorXd &
31  > ArgsType;
32 
33  JOINT_VISITOR_INIT (JointCompositeCalcZeroOrderStep);
34 
35  template<typename JointModel>
36  static void algo(const se3::JointModelBase<JointModel> & jmodel,
38  const se3::JointModelComposite & model,
39  se3::JointDataComposite & data,
40  const Eigen::VectorXd & q)
41  {
42  const JointIndex & i = jmodel.id();
43  const JointIndex succ = i+1; // successor
44 
45  jmodel.calc(jdata.derived(), q);
46 
47  data.pjMi[i] = model.jointPlacements[i] * jdata.M ();
48 
49  if ( succ == model.joints.size() )
50  {
51  data.iMlast[i] = data.pjMi[i];
52  data.S.matrix().rightCols(model.m_nvs[i]) = constraint_xd(jdata.derived()).matrix();
53  }
54  else
55  {
56  const int idx_v = model.m_idx_v[i] - model.m_idx_v[0];
57 
58  data.iMlast[i] = data.pjMi[i] * data.iMlast[succ];
59  data.S.matrix().middleCols(idx_v,model.m_nvs[i]) = data.iMlast[succ].inverse().act(jdata.S()); // TODO: avoid computing inverse
60  }
61 
62  }
63 
64  };
65 
66  inline void JointModelComposite::calc(JointData & data, const Eigen::VectorXd & qs) const
67  {
68  assert(joints.size() > 0);
69  assert(data.joints.size() == joints.size());
70 
71  for (int i=(int)(joints.size()-1); i >= 0; --i)
72  {
73  JointCompositeCalcZeroOrderStep::run(joints[(size_t)i], data.joints[(size_t)i],
74  JointCompositeCalcZeroOrderStep::ArgsType (*this,data,qs)
75  );
76  }
77  data.M = data.iMlast.front();
78  }
79 
80  struct JointCompositeCalcFirstOrderStep : public fusion::JointVisitor<JointCompositeCalcFirstOrderStep>
81  {
82  typedef boost::fusion::vector<const se3::JointModelComposite &,
84  const Eigen::VectorXd &,
85  const Eigen::VectorXd &
86  > ArgsType;
87 
88  JOINT_VISITOR_INIT (JointCompositeCalcFirstOrderStep);
89 
90  template<typename JointModel>
91  static void algo(const se3::JointModelBase<JointModel> & jmodel,
93  const se3::JointModelComposite & model,
94  se3::JointDataComposite & data,
95  const Eigen::VectorXd & q,
96  const Eigen::VectorXd & v)
97  {
98  const JointIndex & i = jmodel.id();
99  const JointIndex succ = i+1; // successor
100 
101  jmodel.calc(jdata.derived(), q, v);
102 
103  data.pjMi[i] = model.jointPlacements[i] * jdata.M ();
104 
105  if ( succ == model.joints.size() )
106  {
107  data.iMlast[i] = data.pjMi[i];
108  data.S.matrix().rightCols(model.m_nvs[i]) = constraint_xd(jdata.derived()).matrix();
109  data.v = jdata.v();
110  data.c = jdata.c();
111  }
112  else
113  {
114  const int idx_v = model.m_idx_v[i] - model.m_idx_v[0];
115 
116  data.iMlast[i] = data.pjMi[i] * data.iMlast[succ];
117  data.S.matrix().middleCols(idx_v,model.m_nvs[i]) = data.iMlast[succ].inverse().act(jdata.S()); // TODO: avoid computing inverse
118 
119  Motion v_tmp = data.iMlast[succ].actInv(motion(jdata.derived())); // TODO: avoid calling motion
120 
121  data.v += v_tmp;
122 
123  data.c -= data.v.cross(v_tmp);
124  data.c += data.iMlast[succ].actInv(bias(jdata.derived())); // TODO: avoid calling bias
125  }
126 
127  }
128 
129  };
130 
131  inline void JointModelComposite::calc(JointData & data, const Eigen::VectorXd & qs, const Eigen::VectorXd & vs) const
132  {
133  assert(joints.size() > 0);
134  assert(data.joints.size() == joints.size());
135 
136  for (int i=(int)(joints.size()-1); i >= 0; --i)
137  {
138  JointCompositeCalcFirstOrderStep::run(joints[(size_t)i], data.joints[(size_t)i],
139  JointCompositeCalcFirstOrderStep::ArgsType (*this,data,qs,vs)
140  );
141  }
142  data.M = data.iMlast.front();
143  }
144 
145 } // namespace se3
146 
147 #endif // ifndef __se3_joint_composite_hxx__
ConstraintXd constraint_xd(const JointDataVariant &jdata)
Visit a JointDataVariant through JointConstraintVisitor to get the joint constraint as a dense constr...
container::aligned_vector< Transformation_t > iMlast
Transforms from previous joint to last joint.
Motion motion(const JointDataVariant &jdata)
Visit a JointDataVariant through JointMotionVisitor to get the joint internal motion as a dense motio...
container::aligned_vector< SE3 > jointPlacements
Vector of joint placements. Those placements correspond to the origin of the joint relatively to thei...
std::vector< int > m_nvs
Dimension of the segment in the tangent vector.
container::aligned_vector< Transformation_t > pjMi
Transforms from previous joint to joint i.
Motion bias(const JointDataVariant &jdata)
Visit a JointDataVariant through JointBiasVisitor to get the joint bias as a dense motion...
std::vector< int > m_idx_v
Index in the tangent vector.
JointModelVector joints
Vector of joints contained in the joint composite.
int idx_v(const JointModelVariant &jmodel)
Visit a JointModelVariant through JointIdxVVisitor to get the index in the full model tangent space c...