pinocchio  UNKNOWN
crba.hxx
1 //
2 // Copyright (c) 2015-2018 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 terms 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_crba_hxx__
19 #define __se3_crba_hxx__
20 
21 #include "pinocchio/multibody/visitor.hpp"
22 #include "pinocchio/spatial/act-on-set.hpp"
23 #include "pinocchio/algorithm/kinematics.hpp"
24 #include "pinocchio/algorithm/check.hpp"
25 
27 
28 namespace se3
29 {
30  struct CrbaForwardStep : public fusion::JointVisitor<CrbaForwardStep>
31  {
32  typedef boost::fusion::vector<const se3::Model&,
33  se3::Data &,
34  const Eigen::VectorXd &
35  > ArgsType;
36 
37  JOINT_VISITOR_INIT(CrbaForwardStep);
38 
39  template<typename JointModel>
40  static void algo(const se3::JointModelBase<JointModel> & jmodel,
42  const se3::Model & model,
43  se3::Data & data,
44  const Eigen::VectorXd & q)
45  {
46  const Model::JointIndex & i = (Model::JointIndex) jmodel.id();
47  jmodel.calc(jdata.derived(),q);
48 
49  data.liMi[i] = model.jointPlacements[i]*jdata.M();
50  data.Ycrb[i] = model.inertias[i];
51  }
52 
53  };
54 
55  struct CrbaBackwardStep : public fusion::JointVisitor<CrbaBackwardStep>
56  {
57  typedef boost::fusion::vector<const Model&,
58  Data&> ArgsType;
59 
60  JOINT_VISITOR_INIT(CrbaBackwardStep);
61 
62  template<typename JointModel>
63  static void algo(const JointModelBase<JointModel> & jmodel,
65  const Model & model,
66  Data & data)
67  {
68  /*
69  * F[1:6,i] = Y*S
70  * M[i,SUBTREE] = S'*F[1:6,SUBTREE]
71  * if li>0
72  * Yli += liXi Yi
73  * F[1:6,SUBTREE] = liXi F[1:6,SUBTREE]
74  */
75  typedef Data::Matrix6x::ColsBlockXpr Block;
76  const Model::JointIndex & i = (Model::JointIndex) jmodel.id();
77 
78  /* F[1:6,i] = Y*S */
79  //data.Fcrb[i].block<6,JointModel::NV>(0,jmodel.idx_v()) = data.Ycrb[i] * jdata.S();
80  jmodel.jointCols(data.Fcrb[i]) = data.Ycrb[i] * jdata.S();
81 
82  /* M[i,SUBTREE] = S'*F[1:6,SUBTREE] */
83  data.M.block(jmodel.idx_v(),jmodel.idx_v(),jmodel.nv(),data.nvSubtree[i])
84  = jdata.S().transpose()*data.Fcrb[i].middleCols(jmodel.idx_v(),data.nvSubtree[i]);
85 
86  const Model::JointIndex & parent = model.parents[i];
87  if(parent>0)
88  {
89  /* Yli += liXi Yi */
90  data.Ycrb[parent] += data.liMi[i].act(data.Ycrb[i]);
91 
92  /* F[1:6,SUBTREE] = liXi F[1:6,SUBTREE] */
93  Block jF
94  = data.Fcrb[parent].middleCols(jmodel.idx_v(),data.nvSubtree[i]);
95  Block iF
96  = data.Fcrb[i].middleCols(jmodel.idx_v(),data.nvSubtree[i]);
97  forceSet::se3Action(data.liMi[i], iF, jF);
98  }
99  }
100  };
101 
102  struct CrbaForwardStepMinimal : public fusion::JointVisitor<CrbaForwardStepMinimal>
103  {
104  typedef boost::fusion::vector<const se3::Model&,
105  se3::Data &,
106  const Eigen::VectorXd &
107  > ArgsType;
108 
109  JOINT_VISITOR_INIT(CrbaForwardStepMinimal);
110 
111  template<typename JointModel>
112  static void algo(const se3::JointModelBase<JointModel> & jmodel,
114  const se3::Model & model,
115  se3::Data & data,
116  const Eigen::VectorXd & q)
117  {
118  const Model::JointIndex & i = (Model::JointIndex) jmodel.id();
119  jmodel.calc(jdata.derived(),q);
120 
121  data.liMi[i] = model.jointPlacements[i]*jdata.M();
122 
123  const Model::JointIndex & parent = model.parents[i];
124  if (parent>0) data.oMi[i] = data.oMi[parent]*data.liMi[i];
125  else data.oMi[i] = data.liMi[i];
126 
127  jmodel.jointCols(data.J) = data.oMi[i].act(jdata.S());
128 
129  data.Ycrb[i] = model.inertias[i];
130  }
131 
132  };
133 
134  struct CrbaBackwardStepMinimal : public fusion::JointVisitor<CrbaBackwardStepMinimal>
135  {
136  typedef boost::fusion::vector<const Model&,
137  Data&> ArgsType;
138 
139  JOINT_VISITOR_INIT(CrbaBackwardStepMinimal);
140 
141  template<typename JointModel>
142  static void algo(const JointModelBase<JointModel> & jmodel,
144  const Model & model,
145  Data & data)
146  {
147  typedef typename SizeDepType<JointModel::NV>::template ColsReturn<Data::Matrix6x>::Type ColsBlock;
148  const Model::JointIndex & i = (Model::JointIndex) jmodel.id();
149 
150  /* F[1:6,i] = Y*S */
151  jdata.U() = data.Ycrb[i] * jdata.S();
152  ColsBlock jF = data.Ag.middleCols<JointModel::NV>(jmodel.idx_v());
153  // = data.Ag.middleCols(jmodel.idx_v(), jmodel.nv());
154 
155  forceSet::se3Action(data.oMi[i],jdata.U(),jF);
156 
157  /* M[i,SUBTREE] = S'*F[1:6,SUBTREE] */
158  data.M.block(jmodel.idx_v(),jmodel.idx_v(),jmodel.nv(),data.nvSubtree[i]).noalias()
159  = jmodel.jointCols(data.J).transpose()*data.Ag.middleCols(jmodel.idx_v(),data.nvSubtree[i]);
160 
161  const Model::JointIndex & parent = model.parents[i];
162  /* Yli += liXi Yi */
163  data.Ycrb[parent] += data.liMi[i].act(data.Ycrb[i]);
164  }
165  };
166 
167  inline const Eigen::MatrixXd&
168  crba(const Model & model, Data& data,
169  const Eigen::VectorXd & q)
170  {
171  assert(model.check(data) && "data is not consistent with model.");
172 
173  for( Model::JointIndex i=1;i<(Model::JointIndex)(model.njoints);++i )
174  {
175  CrbaForwardStep::run(model.joints[i],data.joints[i],
176  CrbaForwardStep::ArgsType(model,data,q));
177  }
178 
179  for( Model::JointIndex i=(Model::JointIndex)(model.njoints-1);i>0;--i )
180  {
181  CrbaBackwardStep::run(model.joints[i],data.joints[i],
182  CrbaBackwardStep::ArgsType(model,data));
183  }
184 
185  return data.M;
186  }
187 
188  inline const Eigen::MatrixXd &
189  crbaMinimal(const Model & model, Data & data,
190  const Eigen::VectorXd & q)
191  {
192  assert(model.check(data) && "data is not consistent with model.");
193 
194  for( Model::JointIndex i=1;i<(Model::JointIndex)(model.njoints);++i )
195  {
196  CrbaForwardStepMinimal::run(model.joints[i],data.joints[i],
197  CrbaForwardStepMinimal::ArgsType(model,data,q));
198  }
199 
200  for( Model::JointIndex i=(Model::JointIndex)(model.njoints-1);i>0;--i )
201  {
202  CrbaBackwardStepMinimal::run(model.joints[i],data.joints[i],
203  CrbaBackwardStepMinimal::ArgsType(model,data));
204  }
205 
206  // Retrieve the Centroidal Momemtum map
207  typedef Eigen::Block<Data::Matrix6x,3,-1> Block3x;
208 
209  data.com[0] = data.Ycrb[0].lever();
210 
211  const Block3x Ag_lin = data.Ag.middleRows<3>(Force::LINEAR);
212  Block3x Ag_ang = data.Ag.middleRows<3>(Force::ANGULAR);
213  for(long i = 0; i<model.nv; ++i)
214  Ag_ang.col(i) += Ag_lin.col(i).cross(data.com[0]);
215 
216  return data.M;
217  }
218 
219  // --- CHECKER ---------------------------------------------------------------
220  // --- CHECKER ---------------------------------------------------------------
221  // --- CHECKER ---------------------------------------------------------------
222 
223  namespace internal
224  {
225  inline bool isDescendant(const Model& model, const JointIndex j, const JointIndex root)
226  {
227  if(int(j)>=model.njoints) return false;
228  if(j==0) return root==0;
229  return (j==root) || isDescendant(model,model.parents[j],root);
230  }
231  }
232 
233  inline bool CRBAChecker::checkModel_impl( const Model& model ) const
234  {
235  // For CRBA, the tree must be "compact", i.e. all descendants of a node i are stored
236  // immediately after i in the "parents" map, i.e. forall joint i, the interval i+1..n-1
237  // can be separated in two intervals [i+1..k] and [k+1..n-1], where any [i+1..k] is a descendant
238  // of i and none of [k+1..n-1] is a descendant of i.
239  for( JointIndex i=1; int(i)<model.njoints-1; ++i ) // no need to check joints 0 and N-1
240  {
241  JointIndex k=i+1;
242  while(internal::isDescendant(model,k,i)) ++k;
243  for( ; int(k)<model.njoints; ++k )
244  if( internal::isDescendant(model,k,i) ) return false;
245  }
246  return true;
247  }
248 
249 
250 } // namespace se3
251 
253 
254 #endif // ifndef __se3_crba_hxx__
Matrix6x Ag
Centroidal Momentum Matrix.
Definition: data.hpp:173
int nv
Dimension of the velocity vector space.
Definition: model.hpp:52
container::aligned_vector< SE3 > jointPlacements
Placement (SE3) of the input of joint i regarding to the parent joint output li.
Definition: model.hpp:67
std::vector< int > nvSubtree
Dimension of the subtree motion space (for CRBA)
Definition: data.hpp:195
EIGEN_MAKE_ALIGNED_OPERATOR_NEW typedef Eigen::Matrix< double, 6, Eigen::Dynamic > Matrix6x
The 6d jacobian type (temporary)
Definition: data.hpp:45
JointModelVector joints
Model of joint i, encapsulated in a JointModelAccessor.
Definition: model.hpp:70
container::aligned_vector< Inertia > Ycrb
Vector of sub-tree composite rigid body inertias, i.e. the apparent inertia of the subtree supported ...
Definition: data.hpp:110
const Eigen::MatrixXd & crba(const Model &model, Data &data, const Eigen::VectorXd &q)
Computes the upper triangular part of the joint space inertia matrix M by using the Composite Rigid B...
Definition: crba.hxx:168
Matrix6x J
Jacobian of joint placements.
Definition: data.hpp:217
std::vector< JointIndex > parents
Joint parent of joint i, denoted li (li==parents[i]).
Definition: model.hpp:73
container::aligned_vector< Matrix6x > Fcrb
Spatial forces set, used in CRBA and CCRBA.
Definition: data.hpp:190
container::aligned_vector< Eigen::Vector3d > com
Vector of subtree center of mass positions expressed in the root joint of the subtree. In other words, com[j] is the CoM position of the subtree supported by joint and expressed in the joint frame . The element com[0] corresponds to the center of mass position of the whole model and expressed in the global frame.
Definition: data.hpp:247
const Eigen::MatrixXd & crbaMinimal(const Model &model, Data &data, const Eigen::VectorXd &q)
Computes the upper triangular part of the joint space inertia matrix M by using the Composite Rigid B...
Definition: crba.hxx:189
JointDataVector joints
Vector of se3::JointData associated to the se3::JointModel stored in model, encapsulated in JointData...
Definition: data.hpp:55
Eigen::MatrixXd M
The joint space inertia matrix (a square matrix of dim model.nv).
Definition: data.hpp:116
container::aligned_vector< SE3 > liMi
Vector of relative joint placements (wrt the body parent).
Definition: data.hpp:90
container::aligned_vector< SE3 > oMi
Vector of absolute joint placements (wrt the world).
Definition: data.hpp:87
bool check(const AlgorithmCheckerBase< D > &checker=AlgorithmCheckerBase< D >()) const
Definition: model.hpp:331
container::aligned_vector< Inertia > inertias
Spatial inertias of the body i expressed in the supporting joint frame i.
Definition: model.hpp:64
int njoints
Number of joints.
Definition: model.hpp:55