- 3.0.2 rigid body dynamics module.
Kinematics.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 
8 #include <unordered_map>
9 
11 #include <ct/rbd/state/RBDState.h>
12 
13 #include "kinematics/EndEffector.h"
16 
17 namespace ct {
18 namespace rbd {
19 
26 template <class RBD, size_t N_EE>
28 {
29 public:
30  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
31 
32  Kinematics(std::shared_ptr<RBD> rbdContainer = std::shared_ptr<RBD>(new RBD()))
33  : rbdContainer_(rbdContainer), floatingBaseTransforms_(rbdContainer_)
34  {
35  initEndeffectors(endEffectors_);
36  }
37 
39  : rbdContainer_(new RBD()), endEffectors_(other.endEffectors_), floatingBaseTransforms_(rbdContainer_)
40  {
41  }
42 
43  virtual ~Kinematics() = default;
44 
45  Kinematics<RBD, N_EE>* clone() const { return new Kinematics<RBD, N_EE>(*this); }
46  static const size_t NUM_EE = N_EE;
47  static const size_t NJOINTS = RBD::NJOINTS;
48  static const size_t NLINKS = RBD::NLINKS;
49 
50  using Ptr_t = std::shared_ptr<Kinematics<RBD, N_EE>>;
51 
52  using ROBCOGEN = RBD;
53  using SCALAR = typename ROBCOGEN::SCALAR;
54 
55  using HomogeneousTransform = typename ROBCOGEN::HomogeneousTransform;
56  using HomogeneousTransforms = typename ROBCOGEN::HomogeneousTransforms;
57  using ForceTransform = typename ROBCOGEN::ForceTransform;
58  using Jacobian = typename ROBCOGEN::Jacobian;
59  using Jacobians = typename ROBCOGEN::Jacobians;
60  using Vector3Tpl = Eigen::Matrix<SCALAR, 3, 1>;
61  using Matrix3Tpl = Eigen::Matrix<SCALAR, 3, 3>;
62  using Position3Tpl = kindr::Position<SCALAR, 3>;
63  using Velocity3Tpl = kindr::Velocity<SCALAR, 3>;
64  using QuaterionTpl = kindr::RotationQuaternion<SCALAR>;
69 
70  void initEndeffectors(std::array<EndEffector<NJOINTS, SCALAR>, NUM_EE>& endeffectors)
71  {
72  for (size_t i = 0; i < NUM_EE; i++)
73  {
74  endeffectors[i].setLinkId(ROBCOGEN::UTILS::eeIdToLinkId(i));
75  }
76  }
77 
83  EndEffector<NJOINTS, SCALAR>& getEndEffector(size_t id) { return endEffectors_[id]; }
89  void setEndEffector(size_t id, const EndEffector<NJOINTS, SCALAR>& ee){};
90 
92  {
93  return robcogen().getJacobianBaseEEbyId(eeId, rbdState.jointPositions());
94  }
95 
97  {
98  throw std::runtime_error("floating base transforms not implemented");
99  return floatingBaseTransforms_;
100  }
101 
103  {
104  throw std::runtime_error("floating base transforms not implemented");
105  return floatingBaseTransforms_;
106  }
107 
108  const HomogeneousTransforms& transforms() const { return robcogen().homogeneousTransforms(); }
109  HomogeneousTransforms& transforms() { return robcogen().homogeneousTransforms(); }
110  const Jacobians& jacobians() const { return robcogen().jacobians(); }
111  Jacobians& jacobians() { return robcogen().jacobians(); }
113  {
114  Velocity3Tpl eeVelocityBase;
115  eeVelocityBase.toImplementation() =
116  (robcogen().getJacobianBaseEEbyId(eeId, rbdState.jointPositions()) * rbdState.jointVelocities())
117  .template bottomRows<3>();
118 
119  // add translational velocity induced by linear base motion
120  eeVelocityBase += rbdState.base().velocities().getTranslationalVelocity();
121 
122  // add translational velocity induced by angular base motion
123  eeVelocityBase += rbdState.base().velocities().getRotationalVelocity().cross(
124  getEEPositionInBase(eeId, rbdState.jointPositions()));
125 
126  return eeVelocityBase;
127  }
128 
130  {
131  Velocity3Tpl eeVelocityBase = getEEVelocityInBase(eeId, rbdState);
132  return rbdState.base().pose().rotateBaseToInertia(eeVelocityBase);
133  }
134 
145  Position3Tpl getEEPositionInBase(size_t eeID, const typename JointState_t::Position& jointPosition)
146  {
147  return robcogen().getEEPositionInBase(eeID, jointPosition);
148  }
149 
157  RigidBodyPoseTpl getEEPoseInBase(size_t eeID, const typename JointState_t::Position& jointPosition)
158  {
159  return robcogen().getEEPoseInBase(eeID, jointPosition);
160  }
161 
165  Matrix3Tpl getEERotInBase(size_t eeID, const typename JointState_t::Position& jointPosition)
166  {
167  return robcogen().getEERotInBase(eeID, jointPosition);
168  }
169 
181  const RigidBodyPoseTpl& basePose,
182  const typename JointState_t::Position& jointPosition)
183  {
184  // vector from base to endeffector expressed in base frame
185  Position3Tpl B_x_EE = getEEPositionInBase(eeID, jointPosition);
186 
187  // vector from base to endeffector expressed in world frame
188  Position3Tpl W_x_EE = basePose.template rotateBaseToInertia(B_x_EE);
189 
190  // vector from origin to endeffector = vector from origin to base + vector from base to endeffector
191  return basePose.position() + W_x_EE;
192  }
193 
196  const RigidBodyPoseTpl& basePose,
197  const typename JointState_t::Position& jointPosition)
198  {
199  // ee pose in base coordinates
200  RigidBodyPoseTpl B_x_EE = getEEPoseInBase(eeID, jointPosition);
201 
202  // position rotated into world frame
203  Position3Tpl W_p_EE = basePose.template rotateBaseToInertia(B_x_EE.position());
204 
205  // orientation rotated into world frame
206  QuaterionTpl B_q_EE = B_x_EE.getRotationQuaternion();
207  QuaterionTpl W_q_EE = basePose.template rotateBaseToInertiaQuaternion(B_q_EE);
208 
209  return RigidBodyPoseTpl(W_q_EE, basePose.position() + W_p_EE);
210  }
211 
214  const RigidBodyPoseTpl& basePose,
215  const typename JointState_t::Position& jointPosition)
216  {
217  // ee rotation matrix in base coordinates
218  Matrix3Tpl B_R_EE = getEERotInBase(eeID, jointPosition);
219 
220  // ee rotation matriix in world
221  return basePose.template rotateBaseToInertiaMat(B_R_EE);
222  }
223 
224  void addIKSolver(const std::shared_ptr<InverseKinematicsBase<NJOINTS, SCALAR>>& solver,
225  size_t eeID,
226  size_t solverID = 0)
227  {
228  if (solverID >= 100)
229  throw std::runtime_error("Solver ID must be less than 100.");
230 
231  size_t hash = eeID * 100 + solverID;
232  if (ikSolvers_.find(hash) != ikSolvers_.end())
233  throw std::runtime_error("Solver with the same eeID and solverID already present.");
234  ikSolvers_[hash] = solver;
235  }
236 
237  std::shared_ptr<InverseKinematicsBase<NJOINTS, SCALAR>> getIKSolver(const size_t eeID,
238  const size_t solverID = 0) const
239  {
240  if (solverID >= 100)
241  throw std::runtime_error("Solver ID must be less than 100.");
242  size_t hash = eeID * 100 + solverID;
243  return ikSolvers_[hash];
244  }
245 
256  const RigidBodyPoseTpl& basePose,
257  const typename JointState_t::Position& jointPosition,
258  size_t eeId)
259  {
260  EEForce eeForce(EEForce::Zero());
261  eeForce.force() = W_force;
262 
263  return mapForceFromWorldToLink(eeForce, basePose, jointPosition, eeId);
264  }
265 
276  const RigidBodyPoseTpl& basePose,
277  const typename JointState_t::Position& jointPosition,
278  size_t eeId)
279  {
280  // get endeffector position in world
281  Position3Tpl B_x_EE = getEEPositionInBase(eeId, jointPosition);
282 
283  return mapForceFromWorldToLink(W_force, basePose, jointPosition, B_x_EE, eeId);
284  }
285 
297  const RigidBodyPoseTpl& basePose,
298  const typename JointState_t::Position& jointPosition,
299  const Position3Tpl& B_x_EE,
300  size_t eeId)
301  {
302  // get the link that the EE is attached to
303  size_t linkId = getEndEffector(eeId).getLinkId();
304 
305  // transform the force/torque to an equivalent force/torque in the base using a lever-arm for the torque
306  EEForce B_force;
307 
308  B_force.force() = basePose.template rotateInertiaToBase<Vector3Tpl>(W_force.force());
309  B_force.torque() = B_x_EE.toImplementation().cross(B_force.force()) +
310  basePose.template rotateInertiaToBase<Vector3Tpl>(W_force.torque());
311 
312  // transform force to link on which endeffector sits on
313  return EEForce(robcogen().getForceTransformLinkBaseById(linkId, jointPosition) * B_force);
314  }
315 
336  const RigidBodyPoseTpl& T_B_EE,
337  const typename JointState_t::Position& jointPosition,
338  size_t eeId)
339  {
340  // get the link that the EE is attached to
341  size_t linkId = getEndEffector(eeId).getLinkId();
342 
343  // transform the force/torque to an equivalent force/torque in the base using a lever-arm for the torque
344  EEForce B_force;
345 
346  // convenience accessors
347  Vector3Tpl B_x_EE = T_B_EE.position().toImplementation();
348 
349  // rotate from the end-effector frame to the inertia frame
350  B_force.force() = T_B_EE.template rotateBaseToInertia<Vector3Tpl>(EE_force.force());
351 
352  // build the cross product and add the torque (which first is rotated from the end-effector to the base)
353  B_force.torque() =
354  B_x_EE.cross(B_force.force()) + T_B_EE.template rotateBaseToInertia<Vector3Tpl>(EE_force.torque());
355 
356  // transform force to link on which endeffector sits on
357  return EEForce(robcogen().getForceTransformLinkBaseById(linkId, jointPosition) * B_force);
358  };
359 
360  RBD& robcogen() { return *rbdContainer_; }
361 private:
362  std::shared_ptr<RBD> rbdContainer_;
363  std::array<EndEffector<NJOINTS, SCALAR>, N_EE> endEffectors_;
364  FloatingBaseTransforms<RBD> floatingBaseTransforms_;
365 
366  std::unordered_map<size_t, std::shared_ptr<InverseKinematicsBase<NJOINTS, SCALAR>>> ikSolvers_;
367 };
368 
369 } /* namespace rbd */
370 } /* namespace ct */
typename ROBCOGEN::ForceTransform ForceTransform
Definition: Kinematics.h:57
typename ROBCOGEN::SCALAR SCALAR
Definition: Kinematics.h:53
EIGEN_MAKE_ALIGNED_OPERATOR_NEW Kinematics(std::shared_ptr< RBD > rbdContainer=std::shared_ptr< RBD >(new RBD()))
Definition: Kinematics.h:32
Jacobian getJacobianBaseEEbyId(size_t eeId, const RBDState< NJOINTS, SCALAR > &rbdState)
Definition: Kinematics.h:91
JointState< NJOINTS, SCALAR >::JointPositionBlock jointPositions()
get joint positions
Definition: RBDState.h:99
size_t eeId
Definition: rbdJITtests.h:24
RigidBodyState_t & base()
get base states
Definition: RBDState.h:63
Pose of a single rigid body.
Definition: RigidBodyPose.h:29
RBD & robcogen()
Definition: Kinematics.h:360
RigidBodyPoseTpl getEEPoseInWorld(size_t eeID, const RigidBodyPoseTpl &basePose, const typename JointState_t::Position &jointPosition)
get the end-effector pose in world coordinates
Definition: Kinematics.h:195
const Position3Tpl & position() const
This method returns the position of the Base frame in the inertia frame.
Definition: RigidBodyPose.h:246
joint state and joint velocity
Definition: JointState.h:21
Jacobians & jacobians()
Definition: Kinematics.h:111
FloatingBaseTransforms< RBD > & floatingBaseTransforms()
Definition: Kinematics.h:96
HomogeneousTransforms & transforms()
Definition: Kinematics.h:109
joint states and base states
Definition: RBDState.h:27
EEForce mapForceFromWorldToLink3d(const Vector3Tpl &W_force, const RigidBodyPoseTpl &basePose, const typename JointState_t::Position &jointPosition, size_t eeId)
Transforms a force applied at an end-effector and expressed in the world into the link frame the EE i...
Definition: Kinematics.h:255
virtual ~Kinematics()=default
const Jacobians & jacobians() const
Definition: Kinematics.h:110
Matrix3Tpl getEERotInBase(size_t eeID, const typename JointState_t::Position &jointPosition)
Definition: Kinematics.h:165
kindr::Position< SCALAR, 3 > Position3Tpl
Definition: Kinematics.h:62
void setEndEffector(size_t id, const EndEffector< NJOINTS, SCALAR > &ee)
Set an end-effector.
Definition: Kinematics.h:89
EndEffector< NJOINTS, SCALAR > & getEndEffector(size_t id)
Get an end-effector.
Definition: Kinematics.h:83
Position3Tpl getEEPositionInWorld(size_t eeID, const RigidBodyPoseTpl &basePose, const typename JointState_t::Position &jointPosition)
Definition: Kinematics.h:180
Position3Tpl getEEPositionInBase(size_t eeID, const typename JointState_t::Position &jointPosition)
Definition: Kinematics.h:145
SpatialForceVector< SCALAR > EEForce
Definition: Kinematics.h:66
typename ROBCOGEN::HomogeneousTransform HomogeneousTransform
Definition: Kinematics.h:55
void initEndeffectors(std::array< EndEffector< NJOINTS, SCALAR >, NUM_EE > &endeffectors)
Definition: Kinematics.h:70
A spatial force vector This vector contains a torque (angular) in the upper three rows and a linear f...
Definition: SpatialForceVector.h:18
Velocity3Tpl getEEVelocityInWorld(size_t eeId, const RBDState< NJOINTS, SCALAR > &rbdState)
Definition: Kinematics.h:129
Eigen::Matrix< SCALAR, NJOINTS, 1 > Position
Definition: JointState.h:32
Vector3Tpl EEForceLinear
Definition: Kinematics.h:67
typename ROBCOGEN::Jacobian Jacobian
Definition: Kinematics.h:58
Definition: InverseKinematicsBase.h:25
kindr::Velocity< SCALAR, 3 > Velocity3Tpl
Definition: Kinematics.h:63
for i
tpl::RigidBodyPose< SCALAR > RigidBodyPoseTpl
Definition: Kinematics.h:65
Eigen::Matrix< SCALAR, 3, 3 > Matrix3Tpl
Definition: Kinematics.h:61
std::shared_ptr< Kinematics< RBD, N_EE > > Ptr_t
Definition: Kinematics.h:50
Velocity3Tpl getEEVelocityInBase(size_t eeId, const RBDState< NJOINTS, SCALAR > &rbdState)
Definition: Kinematics.h:112
const HomogeneousTransforms & transforms() const
Definition: Kinematics.h:108
static const size_t NJOINTS
Definition: Kinematics.h:47
RigidBodyPoseTpl getEEPoseInBase(size_t eeID, const typename JointState_t::Position &jointPosition)
Definition: Kinematics.h:157
Matrix3Tpl getEERotInWorld(size_t eeID, const RigidBodyPoseTpl &basePose, const typename JointState_t::Position &jointPosition)
get the end-effector rotation matrix expressed in world coordinates
Definition: Kinematics.h:213
static const size_t NLINKS
Definition: Kinematics.h:48
kindr::RotationQuaternion< SCALAR > getRotationQuaternion() const
This method returns the quaternion rotation.
Definition: RigidBodyPose.h:134
ForceTorqueBlock torque()
Get the torque block (upper 3D block)
Definition: SpatialForceVector.h:96
Definition: FloatingBaseTransforms.h:14
typename ROBCOGEN::HomogeneousTransforms HomogeneousTransforms
Definition: Kinematics.h:56
kindr::RotationQuaternion< SCALAR > QuaterionTpl
Definition: Kinematics.h:64
Kinematics< RBD, N_EE > * clone() const
Definition: Kinematics.h:45
JointState< NJOINTS, SCALAR >::JointPositionBlock jointVelocities()
get joint velocities
Definition: RBDState.h:108
EEForce mapForceFromEEToLink(const EEForce &EE_force, const RigidBodyPoseTpl &T_B_EE, const typename JointState_t::Position &jointPosition, size_t eeId)
Transforms a force applied at an end-effector expressed in an arbitrary (end-effector) frame into the...
Definition: Kinematics.h:335
FloatingBaseTransforms< RBD > & floatingBaseTransforms() const
Definition: Kinematics.h:102
typename ROBCOGEN::Jacobians Jacobians
Definition: Kinematics.h:59
A general class for computing Kinematic properties.
Definition: Kinematics.h:27
EEForce mapForceFromWorldToLink(const EEForce &W_force, const RigidBodyPoseTpl &basePose, const typename JointState_t::Position &jointPosition, const Position3Tpl &B_x_EE, size_t eeId)
Transforms a force applied at an end-effector and expressed in the world into the link frame the EE i...
Definition: Kinematics.h:296
void addIKSolver(const std::shared_ptr< InverseKinematicsBase< NJOINTS, SCALAR >> &solver, size_t eeID, size_t solverID=0)
Definition: Kinematics.h:224
std::shared_ptr< InverseKinematicsBase< NJOINTS, SCALAR > > getIKSolver(const size_t eeID, const size_t solverID=0) const
Definition: Kinematics.h:237
Definition: EndEffector.h:15
EEForce mapForceFromWorldToLink(const EEForce &W_force, const RigidBodyPoseTpl &basePose, const typename JointState_t::Position &jointPosition, size_t eeId)
Transforms a force applied at an end-effector and expressed in the world into the link frame the EE i...
Definition: Kinematics.h:275
ForceTorqueBlock force()
Get the force block (lower 3D block)
Definition: SpatialForceVector.h:104
Kinematics(const Kinematics< RBD, N_EE > &other)
Definition: Kinematics.h:38
Eigen::Matrix< SCALAR, 3, 1 > Vector3Tpl
Definition: Kinematics.h:60
static const size_t NUM_EE
Definition: Kinematics.h:46
RBD ROBCOGEN
Definition: Kinematics.h:52