- 3.0.2 rigid body dynamics module.
ProjectedDynamics.h
Go to the documentation of this file.
1 /**********************************************************************************************************************
2 This file is part of the Control Toolbox (https://github.com/ethz-adrl/control-toolbox), copyright by ETH Zurich
3 Licensed under the BSD-2 license (see LICENSE file in main directory)
4 **********************************************************************************************************************/
5 
6 #pragma once
7 
13 #include <ct/rbd/state/RBDState.h>
17 
18 namespace ct {
19 namespace rbd {
20 
21 template <class RBD, size_t NEE>
23 {
24 public:
25  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
26 
27  typedef typename RBD::SCALAR Scalar;
28 
29  static const size_t NJOINTS = RBD::NJOINTS;
30  static const size_t CONTROL_DIM = RBD::NJOINTS; //this is very big assumption!
31  static const size_t NDOF = RBDState<NJOINTS, Scalar>::NDOF;
32  static const size_t MAX_JAC_SIZE = 3 * NEE;
33 
34  // this typedefs should live somewhere else
35  typedef Eigen::Matrix<Scalar, NDOF, 1> g_coordinate_vector_t;
36  typedef Eigen::Matrix<Scalar, CONTROL_DIM, 1> control_vector_t;
37  typedef Eigen::Matrix<Scalar, NJOINTS, 1> joint_vector_t;
38  typedef Eigen::Matrix<Scalar, NDOF, NDOF> inertia_matrix_t;
39  typedef Eigen::Matrix<Scalar, 6, 1> ForceVector_t;
40  typedef Eigen::Matrix<Scalar, CONTROL_DIM, NDOF> selection_matrix_t;
41 
44 
49 
50  typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> MatrixXs;
51  typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 1> VectorXs;
52 
58  ProjectedDynamics(const std::shared_ptr<Kinematics<RBD, NEE>> kyn,
59  const EE_in_contact_t ee_inc = EE_in_contact_t(false));
60 
62 
67  void setContactConfiguration(const EE_in_contact_t& eeinc)
68  {
69  ee_in_contact_ = eeinc;
70  ResetJacobianStructure();
71  setSizes();
72  }
73 
78  void getContactConfiguration(EE_in_contact_t& eeinc) { eeinc = ee_in_contact_; }
86  void ProjectedForwardDynamics(const RBDState_t& x, const control_vector_t& u, RBDAcceleration_t& qdd)
87  {
88  ProjectedForwardDynamicsCommon(x, u);
89  qdd.base().fromVector6d(qddlambda_.template segment<6>(0));
90  qdd.joints().setAcceleration(qddlambda_.template segment<NJOINTS>(6));
91  }
92 
94  void getContactForcesInBase(EE_contact_forces_t& lambda)
95  {
96  int rowCounter = 0;
97  for (int eeinc_i = 0; eeinc_i < NEE; eeinc_i++)
98  {
99  if (ee_in_contact_[eeinc_i])
100  {
101  lambda[eeinc_i] = qddlambda_.template segment<3>(NDOF + rowCounter);
102  rowCounter += 3;
103  }
104  else
105  {
106  lambda[eeinc_i].setZero();
107  }
108  }
109  };
110 
112  void getContactForcesInBase(const RBDState_t& x, const control_vector_t& u, EE_contact_forces_t& lambda)
113  {
114  ProjectedForwardDynamicsCommon(x, u);
115  getContactForcesInBase(lambda);
116  }
117 
125  void ProjectedInverseDynamics(const RBDState_t& x, const RBDAcceleration_t& qdd, control_vector_t& u)
126  {
127  updateDynamicsTerms(x, u);
128  ProjectedInverseDynamicsCommon(x, qdd, u);
129  }
130 
131  void ProjectedInverseDynamicsNoGravity(const RBDState_t& x, const RBDAcceleration_t& qdd, control_vector_t& u)
132  {
133  updateDynamicsTermsNoGravity(x, u);
134  ProjectedInverseDynamicsCommon(x, qdd, u);
135  }
136 
137 private:
139  void updateDynamicsTerms(const RBDState_t& x, const control_vector_t& u);
140 
142  void updateDynamicsTermsNoGravity(const RBDState_t& x, const control_vector_t& u);
143 
150  void ProjectedInverseDynamicsCommon(const RBDState_t& x, const RBDAcceleration_t& qdd, control_vector_t& u);
151 
157  void ProjectedForwardDynamicsCommon(const RBDState_t& x, const control_vector_t& u);
158 
159  void ResetJacobianStructure();
160 
161  void setSizes();
162 
163  std::shared_ptr<Kinematics<RBD, NEE>> kinematics_;
165  EE_in_contact_t ee_in_contact_;
167  size_t neec_ = 0;
169  inertia_matrix_t M_;
170  selection_matrix_t S_;
171  g_coordinate_vector_t f_;
172  g_coordinate_vector_t h_;
174  Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> MJTJ0_;
175  Eigen::Matrix<Scalar, Eigen::Dynamic, 1> qddlambda_, b_;
176  Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> Jc_reduced_;
177  Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> dJcdt_reduced_;
178  Eigen::Matrix<Scalar, Eigen::Dynamic, 1> feet_crossproduct_;
179 
181  Jc_;
183  inertia_matrix_t P_;
184  Eigen::JacobiSVD<MatrixXs> svd_;
185 };
186 
187 template <class RBD, size_t NEE>
189  const EE_in_contact_t ee_inc /*= EE_in_Contact_t(false)*/)
190  : kinematics_(kyn), ee_in_contact_(ee_inc)
191 {
192  setContactConfiguration(ee_inc);
193 }
194 
195 template <class RBD, size_t NEE>
196 void ProjectedDynamics<RBD, NEE>::updateDynamicsTermsNoGravity(const RBDState_t& x, const control_vector_t& u)
197 {
198  joint_vector_t jForces;
199  ForceVector_t base_w;
200 
201  kinematics_->robcogen().inverseDynamics().C_terms_fully_actuated(
202  base_w, jForces, x.baseVelocities().getVector(), x.joints().getPositions(), x.joints().getVelocities());
203 
204  M_ = kinematics_->robcogen().jSim().update(x.joints().getPositions());
205 
206  h_ << base_w, jForces;
207  f_ << Eigen::Matrix<Scalar, 6, 1>::Zero(), u;
208 }
209 
210 template <class RBD, size_t NEE>
211 void ProjectedDynamics<RBD, NEE>::updateDynamicsTerms(const RBDState_t& x, const control_vector_t& u)
212 {
213  joint_vector_t jForces_gravity;
214  ForceVector_t base_w_gravity;
215 
216  kinematics_->robcogen().inverseDynamics().G_terms_fully_actuated(
217  base_w_gravity, jForces_gravity, x.basePose().computeGravityB6D(), x.joints().getPositions());
218 
219  updateDynamicsTermsNoGravity(x, u);
220  h_.template segment<6>(0) += base_w_gravity;
221  h_.template segment<NJOINTS>(6) += jForces_gravity;
222 }
223 
224 template <class RBD, size_t NEE>
226  const RBDAcceleration_t& qdd,
227  control_vector_t& u)
228 {
229  Jc_.updateState(x);
230  P_ = Jc_.P();
231 
232  Eigen::Matrix<Scalar, NDOF, CONTROL_DIM> PSt = P_ * S_.transpose();
233 
234  svd_.compute(PSt, Eigen::ComputeThinU | Eigen::ComputeThinV);
235 
236  VectorXs sing_values(svd_.matrixV().cols(), 1); // size of E has same size as columns of V
237  sing_values = (svd_.singularValues().array() > 1e-9).select(svd_.singularValues().array().inverse(), 0);
238  selection_matrix_t Pstinv = svd_.matrixV() * sing_values.asDiagonal() * svd_.matrixU().transpose();
239 
240  selection_matrix_t PStP = Pstinv * P_;
241 
242  g_coordinate_vector_t Mqdd = M_ * qdd.toCoordinateAcceleration();
243 
244  u = PStP * (Mqdd + h_);
245 }
246 
247 template <class RBD, size_t NEE>
248 void ProjectedDynamics<RBD, NEE>::ProjectedForwardDynamicsCommon(const RBDState_t& x, const control_vector_t& u)
249 {
250  // Set Kinematics
251  Jc_.updateState(x);
252  int rowCount = 0;
253  for (size_t eeinc_i = 0; eeinc_i < NEE; eeinc_i++)
254  {
255  if (ee_in_contact_[eeinc_i])
256  {
257  Jc_reduced_.template block<3, NDOF>(rowCount, 0) = Jc_.J().template block<3, NDOF>(3 * eeinc_i, 0);
258  dJcdt_reduced_.template block<3, NDOF>(rowCount, 0) = Jc_.dJdt().template block<3, NDOF>(3 * eeinc_i, 0);
259  feet_crossproduct_.template segment<3>(rowCount) =
260  x.baseLocalAngularVelocity().toImplementation().template cross(
261  kinematics_->getEEVelocityInBase(eeinc_i, x).toImplementation());
262  rowCount += 3;
263  }
264  }
265 
266  // Set Dynamics
267  updateDynamicsTerms(x, u);
268  MJTJ0_.template block<NDOF, NDOF>(0, 0) = M_;
269  MJTJ0_.template block(NDOF, 0, 3 * neec_, NDOF) = -Jc_reduced_;
270  MJTJ0_.template block(0, NDOF, NDOF, 3 * neec_) = -Jc_reduced_.transpose();
271 
272  b_.template segment<NDOF>(0) = f_ - h_;
273  b_.template segment(NDOF, 3 * neec_) = dJcdt_reduced_ * x.toCoordinateVelocity() + feet_crossproduct_;
274 
275  qddlambda_ = core::LDLTsolve<Scalar>(MJTJ0_, b_);
276 }
277 
278 template <class RBD, size_t NEE>
280 {
281  Jc_.ee_indices_.clear();
282  Jc_.c_size_ = 0;
283  neec_ = 0;
284 
285  for (size_t eeinc = 0; eeinc < NEE; eeinc++)
286  {
287  if (ee_in_contact_[eeinc])
288  {
289  neec_++;
290  Jc_.c_size_ += 3;
291  Jc_.ee_indices_.push_back(eeinc);
292 
293  Jc_.eeInContact_[eeinc] = ee_in_contact_[eeinc];
294  }
295  }
296 }
297 
298 template <class RBD, size_t NEE>
300 {
301  Jc_reduced_.resize(3 * neec_, NDOF);
302  dJcdt_reduced_.resize(3 * neec_, NDOF);
303  feet_crossproduct_.resize(3 * neec_);
304 
305  MJTJ0_.resize(NDOF + 3 * neec_, NDOF + 3 * neec_);
306  MJTJ0_.setZero();
307  b_.resize(NDOF + 3 * neec_);
308  qddlambda_.resize(NDOF + 3 * neec_);
309 
310  S_.template block<CONTROL_DIM, 6>(0, 0).setZero();
311  S_.template block<CONTROL_DIM, NJOINTS>(0, 6).setIdentity();
312 }
313 
314 } /* namespace rbd */
315 } /* namespace ct */
RBDState< NJOINTS, Scalar > RBDState_t
Definition: ProjectedDynamics.h:45
static const size_t NDOF
Definition: ProjectedDynamics.h:31
~ProjectedDynamics()
Definition: ProjectedDynamics.h:61
Eigen::Matrix< SCALAR, 6, 1 > computeGravityB6D(const Vector3Tpl &gravityW=gravity3DW()) const
This methods returns the 6D gravity vector expressed in the Base frame.
Definition: RigidBodyPose.h:380
RigidBodyPose_t & basePose()
get base pose
Definition: RBDState.h:67
Definition: ConstraintJacobian.h:21
RBDAcceleration< NJOINTS, Scalar > RBDAcceleration_t
Definition: ProjectedDynamics.h:46
ct::core::ControlVector< control_dim > u
coordinate_vector_t toCoordinateAcceleration() const
Definition: RBDAcceleration.h:87
void getContactConfiguration(EE_in_contact_t &eeinc)
get the End Effector contact configuration
Definition: ProjectedDynamics.h:78
JointAcceleration< NJOINTS, SCALAR > & joints()
get joint acceleration
Definition: RBDAcceleration.h:52
void getContactForcesInBase(const RBDState_t &x, const control_vector_t &u, EE_contact_forces_t &lambda)
compute contact forces at current state and control input
Definition: ProjectedDynamics.h:112
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > MatrixXs
Definition: ProjectedDynamics.h:50
joint states and base states
Definition: RBDState.h:27
JointAcceleration< NJOINTS, Scalar > JointAcceleration_t
Definition: ProjectedDynamics.h:48
JointState< NJOINTS, Scalar > JointState_t
Definition: ProjectedDynamics.h:47
A very simple container to associate N generic data item T.
Definition: RBDDataMap.h:23
void setContactConfiguration(const EE_in_contact_t &eeinc)
set the End Effector contact configuration
Definition: ProjectedDynamics.h:67
static const size_t NJOINTS
Definition: ProjectedDynamics.h:29
void ProjectedInverseDynamicsNoGravity(const RBDState_t &x, const RBDAcceleration_t &qdd, control_vector_t &u)
Definition: ProjectedDynamics.h:131
joint acceleration
Definition: JointAcceleration.h:17
RBDDataMap< bool, NEE > EE_in_contact_t
Definition: ProjectedDynamics.h:43
static const size_t CONTROL_DIM
Definition: ProjectedDynamics.h:30
JointPositionBlock getVelocities()
get joint velocity
Definition: JointState.h:131
Eigen::Matrix< Scalar, 6, 1 > ForceVector_t
Definition: ProjectedDynamics.h:39
EIGEN_MAKE_ALIGNED_OPERATOR_NEW typedef RBD::SCALAR Scalar
Definition: ProjectedDynamics.h:27
ct::core::StateVector< state_dim > x
Eigen::Matrix< Scalar, NDOF, 1 > g_coordinate_vector_t
Definition: ProjectedDynamics.h:35
joint acceleration and base acceleration
Definition: RBDAcceleration.h:23
kindr::LocalAngularVelocity< SCALAR > & baseLocalAngularVelocity()
get base local angular velocity
Definition: RBDState.h:75
void ProjectedInverseDynamics(const RBDState_t &x, const RBDAcceleration_t &qdd, control_vector_t &u)
Computes the Inverse Dynamics in the constraint consistent subspace of the current contact configurat...
Definition: ProjectedDynamics.h:125
void getContactForcesInBase(EE_contact_forces_t &lambda)
compute contact forces from last dynamics call
Definition: ProjectedDynamics.h:94
Vector6 getVector() const
Definition: RigidBodyVelocities.h:31
Eigen::Matrix< Scalar, NDOF, NDOF > inertia_matrix_t
Definition: ProjectedDynamics.h:38
tpl::RigidBodyVelocities< SCALAR > & baseVelocities()
get base velocities
Definition: RBDState.h:71
Eigen::Matrix< Scalar, CONTROL_DIM, 1 > control_vector_t
Definition: ProjectedDynamics.h:36
RBDDataMap< Eigen::Vector3d, NEE > EE_contact_forces_t
Definition: ProjectedDynamics.h:42
Eigen::Matrix< Scalar, CONTROL_DIM, NDOF > selection_matrix_t
Definition: ProjectedDynamics.h:40
Definition: ProjectedDynamics.h:22
ProjectedDynamics(const std::shared_ptr< Kinematics< RBD, NEE >> kyn, const EE_in_contact_t ee_inc=EE_in_contact_t(false))
The Constructor.
Definition: ProjectedDynamics.h:188
static const size_t MAX_JAC_SIZE
Definition: ProjectedDynamics.h:32
JointState< NJOINTS, SCALAR > & joints()
get joint states
Definition: RBDState.h:94
JointPositionBlock getPositions()
get joint state
Definition: JointState.h:76
void ProjectedForwardDynamics(const RBDState_t &x, const control_vector_t &u, RBDAcceleration_t &qdd)
Computes the forward dynamics in the constraint consistent subspace of the current contact configurat...
Definition: ProjectedDynamics.h:86
RigidBodyAcceleration_t & base()
get base acceleration
Definition: RBDAcceleration.h:48
coordinate_vector_t toCoordinateVelocity() const
Definition: RBDState.h:144
void fromVector6d(const Eigen::Matrix< SCALAR, 6, 1 > &in)
Definition: RigidBodyAcceleration.h:35
Eigen::Matrix< Scalar, NJOINTS, 1 > joint_vector_t
Definition: ProjectedDynamics.h:37
Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > VectorXs
Definition: ProjectedDynamics.h:51