pinocchio  UNKNOWN
center-of-mass.hxx
1 //
2 // Copyright (c) 2015-2017 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_center_of_mass_hxx__
19 #define __se3_center_of_mass_hxx__
20 
21 #include "pinocchio/algorithm/check.hpp"
22 
24 
25 namespace se3
26 {
27  inline const SE3::Vector3 &
28  centerOfMass(const Model & model, Data & data,
29  const Eigen::VectorXd & q,
30  const bool computeSubtreeComs)
31  {
32  forwardKinematics(model,data,q);
33 
34  centerOfMass(model,data,computeSubtreeComs);
35  return data.com[0];
36  }
37 
38  inline const SE3::Vector3 &
39  centerOfMass(const Model & model, Data & data,
40  const Eigen::VectorXd & q,
41  const Eigen::VectorXd & v,
42  const bool computeSubtreeComs)
43  {
44  forwardKinematics(model,data,q,v);
45 
46  centerOfMass<true,true,false>(model,data,computeSubtreeComs);
47  return data.com[0];
48  }
49 
50  inline const SE3::Vector3 &
51  centerOfMass(const Model & model, Data & data,
52  const Eigen::VectorXd & q,
53  const Eigen::VectorXd & v,
54  const Eigen::VectorXd & a,
55  const bool computeSubtreeComs)
56  {
57  forwardKinematics(model,data,q,v,a);
58 
59  centerOfMass<true,true,true>(model,data,computeSubtreeComs);
60  return data.com[0];
61  }
62 
63  template<bool do_position, bool do_velocity, bool do_acceleration>
64  inline void centerOfMass(const Model & model, Data & data,
65  const bool computeSubtreeComs)
66  {
67  assert(model.check(data) && "data is not consistent with model.");
68  using namespace se3;
69 
70  data.mass[0] = 0;
71  if(do_position)
72  data.com[0].setZero ();
73  if(do_velocity)
74  data.vcom[0].setZero ();
75  if(do_acceleration)
76  data.acom[0].setZero ();
77 
78  // Forward Step
79  for(Model::JointIndex i=1;i<(Model::JointIndex)(model.njoints);++i)
80  {
81  const double mass = model.inertias[i].mass();
82  const SE3::Vector3 & lever = model.inertias[i].lever();
83 
84  const Motion & v = data.v[i];
85  const Motion & a = data.a[i];
86 
87  data.mass[i] = mass;
88 
89  if(do_position)
90  data.com[i] = mass * lever;
91 
92  if(do_velocity)
93  data.vcom[i] = mass * (v.angular().cross(lever) + v.linear());
94 
95  if(do_acceleration)
96  data.acom[i] = mass * (a.angular().cross(lever) + a.linear())
97  + v.angular().cross(data.vcom[i]); // take into accound the coriolis part of the acceleration
98  }
99 
100  // Backward Step
101  for(Model::JointIndex i=(Model::JointIndex)(model.njoints-1); i>0; --i)
102  {
103  const Model::JointIndex & parent = model.parents[i];
104  const SE3 & liMi = data.liMi[i];
105 
106  data.mass[parent] += data.mass[i];
107 
108  if(do_position)
109  data.com[parent] += (liMi.rotation()*data.com[i]
110  + data.mass[i] * liMi.translation());
111 
112  if(do_velocity)
113  data.vcom[parent] += liMi.rotation()*data.vcom[i];
114  data.acom[parent] += liMi.rotation()*data.acom[i];
115 
116  if(computeSubtreeComs)
117  {
118  if(do_position)
119  data.com[i] /= data.mass[i];
120  if(do_velocity)
121  data.vcom[i] /= data.mass[i];
122  if(do_acceleration)
123  data.acom[i] /= data.mass[i];
124  }
125  }
126 
127  if(do_position)
128  data.com[0] /= data.mass[0];
129  if(do_velocity)
130  data.vcom[0] /= data.mass[0];
131  if(do_acceleration)
132  data.acom[0] /= data.mass[0];
133  }
134 
135  inline const SE3::Vector3 &
136  getComFromCrba(const Model & model, Data & data)
137  {
138 #ifndef NDEBUG
139  assert(model.check(data) && "data is not consistent with model.");
140 #endif
141  return data.com[0] = data.liMi[1].act(data.Ycrb[1].lever());
142  }
143 
144  /* --- JACOBIAN ---------------------------------------------------------- */
145  /* --- JACOBIAN ---------------------------------------------------------- */
146  /* --- JACOBIAN ---------------------------------------------------------- */
147 
149  : public fusion::JointVisitor<JacobianCenterOfMassBackwardStep>
150  {
151  typedef boost::fusion::vector<const se3::Model &,
152  se3::Data &,
153  const bool
154  > ArgsType;
155 
156  JOINT_VISITOR_INIT(JacobianCenterOfMassBackwardStep);
157 
158  template<typename JointModel>
159  static void algo(const se3::JointModelBase<JointModel> & jmodel,
161  const se3::Model& model,
162  se3::Data& data,
163  const bool computeSubtreeComs )
164  {
165  const Model::JointIndex & i = (Model::JointIndex) jmodel.id();
166  const Model::JointIndex & parent = model.parents[i];
167 
168  data.com[parent] += data.com[i];
169  data.mass[parent] += data.mass[i];
170 
171  typedef Data::Matrix6x Matrix6x;
172  typedef typename SizeDepType<JointModel::NV>::template ColsReturn<Matrix6x>::Type ColBlock;
173 
174  ColBlock Jcols = jmodel.jointCols(data.J);
175  Jcols = data.oMi[i].act(jdata.S());
176 
177  if (JointModel::NV == -1)
178  {
179  if( jmodel.nv() ==1 )
180  {
181  data.Jcom.col(jmodel.idx_v())
182  = data.mass[i] * Jcols.template topLeftCorner<3,1>()
183  - data.com[i].cross(Jcols.template bottomLeftCorner<3,1>()) ;
184  }
185  else
186  {
187  jmodel.jointCols(data.Jcom)
188  = data.mass[i] * Jcols.template topRows<3>()
189  - skew(data.com[i]) * Jcols.template bottomRows<3>();
190  }
191  }
192  else
193  {
194  if( JointModel::NV ==1 )
195  {
196  data.Jcom.col(jmodel.idx_v())
197  = data.mass[i] * Jcols.template topLeftCorner<3,1>()
198  - data.com[i].cross(Jcols.template bottomLeftCorner<3,1>()) ;
199  }
200  else
201  {
202  jmodel.jointCols(data.Jcom)
203  = data.mass[i] * Jcols.template topRows<3>()
204  - skew(data.com[i]) * Jcols.template bottomRows<3>();
205  }
206  }
207 
208 
209  if(computeSubtreeComs)
210  data.com[i] /= data.mass[i];
211  }
212 
213  };
214 
215  inline const Data::Matrix3x &
216  jacobianCenterOfMass(const Model & model, Data & data,
217  const Eigen::VectorXd & q,
218  const bool computeSubtreeComs,
219  const bool updateKinematics)
220  {
221  assert(model.check(data) && "data is not consistent with model.");
222  data.com[0].setZero ();
223  data.mass[0] = 0;
224 
225  // Forward step
226  if (updateKinematics)
227  forwardKinematics(model, data, q);
228 
229  for(Model::JointIndex i=1;i<(Model::JointIndex)(model.njoints);++i)
230  {
231  const double mass = model.inertias[i].mass();
232  const SE3::Vector3 & lever = model.inertias[i].lever();
233 
234  data.mass[i] = mass;
235  data.com[i] = mass*data.oMi[i].act(lever);
236  }
237 
238  // Backward step
239  for( Model::JointIndex i= (Model::JointIndex) (model.njoints-1);i>0;--i )
240  {
241  JacobianCenterOfMassBackwardStep
242  ::run(model.joints[i],data.joints[i],
243  JacobianCenterOfMassBackwardStep::ArgsType(model,data,computeSubtreeComs));
244  }
245 
246  data.com[0] /= data.mass[0];
247  data.Jcom /= data.mass[0];
248 
249  return data.Jcom;
250  }
251 
252  inline const Data::Matrix3x &
253  getJacobianComFromCrba(const Model & model, Data & data)
254  {
255  assert(model.check(data) && "data is not consistent with model.");
256  const SE3 & oM1 = data.liMi[1];
257 
258  // Extract the total mass of the system.
259  data.mass[0] = data.M(0,0);
260 
261  // As the 6 first rows of M*a are a wrench, we just need to multiply by the
262  // relative rotation between the first joint and the world
263  const SE3::Matrix3 oR1_over_m (oM1.rotation() / data.M(0,0));
264 
265  // I don't know why, but the colwise multiplication is much more faster
266  // than the direct Eigen multiplication
267  for (long k=0; k<model.nv;++k)
268  data.Jcom.col(k) = oR1_over_m * data.M.topRows<3> ().col(k);
269  return data.Jcom;
270  }
271 
272 } // namespace se3
273 
275 
276 #endif // ifndef __se3_center_of_mass_hxx__
container::aligned_vector< Motion > a
Vector of joint accelerations expressed at the centers of the joints.
Definition: data.hpp:58
Matrix3x Jcom
Jacobien of center of mass.
Definition: data.hpp:260
container::aligned_vector< Eigen::Vector3d > vcom
Vector of subtree center of mass linear velocities expressed in the root joint of the subtree...
Definition: data.hpp:250
int nv
Dimension of the velocity vector space.
Definition: model.hpp:52
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
void skew(const Eigen::MatrixBase< Vector3 > &v, const Eigen::MatrixBase< Matrix3 > &M)
Computes the skew representation of a given 3d vector, i.e. the antisymmetric matrix representation o...
Definition: skew.hpp:34
Matrix6x J
Jacobian of joint placements.
Definition: data.hpp:217
const SE3::Vector3 & getComFromCrba(const Model &model, Data &data)
Extracts the center of mass position from the joint space inertia matrix (also called the mass matrix...
container::aligned_vector< Eigen::Vector3d > acom
Vector of subtree center of mass linear accelerations expressed in the root joint of the subtree...
Definition: data.hpp:253
const Data::Matrix3x & getJacobianComFromCrba(const Model &model, Data &data)
Extracts both the jacobian of the center of mass (CoM), the total mass of the system and the CoM posi...
std::vector< JointIndex > parents
Joint parent of joint i, denoted li (li==parents[i]).
Definition: model.hpp:73
const Data::Matrix3x & jacobianCenterOfMass(const Model &model, Data &data, const Eigen::VectorXd &q, const bool computeSubtreeComs=true, const bool updateKinematics=true)
Computes both the jacobian and the the center of mass position of a given model according to a partic...
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
JointDataVector joints
Vector of se3::JointData associated to the se3::JointModel stored in model, encapsulated in JointData...
Definition: data.hpp:55
void forwardKinematics(const Model &model, Data &data, const Eigen::VectorXd &q)
Update the joint placements according to the current joint configuration.
Definition: kinematics.hxx:106
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
const SE3::Vector3 & centerOfMass(const Model &model, Data &data, const Eigen::VectorXd &q, const bool computeSubtreeComs=true)
Computes the center of mass position of a given model according to a particular joint configuration...
container::aligned_vector< SE3 > oMi
Vector of absolute joint placements (wrt the world).
Definition: data.hpp:87
Eigen::Matrix< double, 3, Eigen::Dynamic > Matrix3x
The 3d jacobian type (temporary)
Definition: data.hpp:47
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
container::aligned_vector< Motion > v
Vector of joint velocities expressed at the centers of the joints.
Definition: data.hpp:67
int njoints
Number of joints.
Definition: model.hpp:55
std::vector< double > mass
Vector of subtree mass. In other words, mass[j] is the mass of the subtree supported by joint ...
Definition: data.hpp:256