Robot Dynamics Library
Body.hpp
Go to the documentation of this file.
1 // Copyright (c) 2017 Jordan Lack <jlack1987@gmail.com>
2 // Copyright (c) 2011-2016 Martin Felis <martin.felis@iwr.uni-heidelberg.de>
3 // RDL - Robot Dynamics Library
4 // Licensed under the zlib license. See LICENSE for more details.
5 
6 #ifndef RDL_BODY_HPP
7 #define RDL_BODY_HPP
8 
11 #include <assert.h>
12 #include <iostream>
14 
15 namespace RobotDynamics
16 {
20 struct DragData
21 {
22  DragData(const std::vector<double>& linear_drag, const std::vector<double>& quadratic_drag)
23  {
24  assert(linear_drag.size() == 6 && quadratic_drag.size() == 6);
25  for (unsigned int i = 0; i < 6; i++)
26  {
27  this->linearDrag[i] = linear_drag[i];
28  this->quadraticDrag[i] = quadratic_drag[i];
29  }
30  }
31 
32  DragData(const Math::SpatialVector& linear_drag, const Math::SpatialVector& quadratic_drag)
33  {
34  this->linearDrag = linear_drag;
35  this->quadraticDrag = quadratic_drag;
36  }
37 
39  {
40  zero();
41  }
42 
43  DragData(const DragData& dragData)
44  {
45  this->linearDrag = dragData.linearDrag;
46  this->quadraticDrag = dragData.quadraticDrag;
47  }
48 
49  void zero()
50  {
51  linearDrag.setZero();
52  quadraticDrag.setZero();
53  }
54 
55  DragData& operator=(const DragData& dragData)
56  {
57  this->linearDrag = dragData.linearDrag;
58  this->quadraticDrag = dragData.quadraticDrag;
59  return *this;
60  }
61 
62  void operator+=(const DragData& dragData)
63  {
64  linearDrag += dragData.linearDrag;
65  quadraticDrag += dragData.quadraticDrag;
66  }
67 
70 };
71 
72 inline DragData operator+(DragData dragData1, const DragData& dragData2)
73 {
74  dragData1 += dragData2;
75  return dragData1;
76 }
77 
87 struct Body
88 {
89  Body()
90  : mMass(0.)
91  , mCenterOfMass(0., 0., 0.)
92  , mInertia(Math::Matrix3d::Zero(3, 3))
93  , volume(0.)
94  , mCenterOfBuoyancy(0., 0., 0.)
96  , mIsVirtual(false)
97  {
98  dragData.zero();
99  };
100 
101  Body(const Body& body)
102  : mMass(body.mMass)
104  , mInertia(body.mInertia)
105  , volume(body.volume)
108  , dragData(body.dragData)
109  , mIsVirtual(body.mIsVirtual){};
110 
111  Body& operator=(const Body& body)
112  {
113  if (this != &body)
114  {
115  mMass = body.mMass;
116  mInertia = body.mInertia;
118  mIsVirtual = body.mIsVirtual;
120  volume = body.volume;
122  dragData = body.dragData;
123  }
124 
125  return *this;
126  }
127 
144  Body(const double& mass, const Math::Vector3d& com, const Math::Vector3d& gyration_radii, const Math::Vector3d& centerOfBuoyancy, const double volume,
147  {
148  mInertia = Math::Matrix3d(gyration_radii[0], 0., 0., 0., gyration_radii[1], 0., 0., 0., gyration_radii[2]);
149  }
150 
166  Body(const double& mass, const Math::Vector3d& com, const Math::Vector3d& gyration_radii, const Math::Vector3d& centerOfBuoyancy, const double volume,
168  : mMass(mass), mCenterOfMass(com), volume(volume), mCenterOfBuoyancy(centerOfBuoyancy), addedMassMatrix(addedMassMatrix), mIsVirtual(false)
169  {
170  dragData.zero();
171  mInertia = Math::Matrix3d(gyration_radii[0], 0., 0., 0., gyration_radii[1], 0., 0., 0., gyration_radii[2]);
172  }
173 
186  Body(const double& mass, const Math::Vector3d& com, const Math::Vector3d& gyration_radii)
187  : mMass(mass), mCenterOfMass(com), volume(0.), mCenterOfBuoyancy(Math::Vector3dZero), mIsVirtual(false)
188  {
189  mInertia = Math::Matrix3d(gyration_radii[0], 0., 0., 0., gyration_radii[1], 0., 0., 0., gyration_radii[2]);
190  dragData.zero();
191  addedMassMatrix.setZero();
192  }
193 
210  Body(const double& mass, const Math::Vector3d& com, const Math::Matrix3d& inertia_C, const Math::Vector3d& centerOfBuoyancy, const double volume,
212  : mMass(mass)
213  , mCenterOfMass(com)
214  , mInertia(inertia_C)
215  , volume(volume)
216  , mCenterOfBuoyancy(centerOfBuoyancy)
218  , dragData(dragData)
219  , mIsVirtual(false)
220  {
221  }
222 
238  Body(const double& mass, const Math::Vector3d& com, const Math::Matrix3d& inertia_C, const Math::Vector3d& centerOfBuoyancy, const double volume,
240  : mMass(mass), mCenterOfMass(com), mInertia(inertia_C), volume(volume), mCenterOfBuoyancy(centerOfBuoyancy), addedMassMatrix(addedMassMatrix), mIsVirtual(false)
241  {
242  dragData.zero();
243  }
244 
257  Body(const double& mass, const Math::Vector3d& com, const Math::Matrix3d& inertia_C)
258  : mMass(mass), mCenterOfMass(com), mInertia(inertia_C), volume(0.), mCenterOfBuoyancy(Math::Vector3dZero), mIsVirtual(false)
259  {
260  addedMassMatrix.setZero();
261  dragData.zero();
262  }
263 
278  void join(const Math::SpatialTransform& transform, const Body& other_body)
279  {
280  // nothing to do if we join a massles body to the current.
281  if (other_body.mMass == 0. && other_body.mInertia == Math::Matrix3d::Zero())
282  {
283  return;
284  }
285 
286  double other_mass = other_body.mMass;
287  double new_mass = mMass + other_mass;
288 
289  double other_volume = other_body.volume;
290  double new_volume = volume + other_volume;
291 
292  if (new_mass == 0.)
293  {
294  throw RdlException("Error: cannot join bodies as both have zero mass!");
295  }
296 
297  Math::Vector3d other_com = transform.E.transpose() * other_body.mCenterOfMass + transform.r;
298  Math::Vector3d new_com = (1. / new_mass) * (mMass * mCenterOfMass + other_mass * other_com);
300  if (new_volume != 0.)
301  {
302  Math::Vector3d other_cob = transform.E.transpose() * other_body.mCenterOfBuoyancy + transform.r;
303  new_cob = (1. / new_volume) * (volume * mCenterOfBuoyancy + other_volume * other_cob);
304  }
305 
306  // We have to transform the inertia of other_body to the new COM. This
307  // is done in 4 steps:
308  //
309  // 1. Transform the inertia from other origin to other COM
310  // 2. Rotate the inertia that it is aligned to the frame of this body
311  // 3. Transform inertia of other_body to the origin of the frame of
312  // this body
313  // 4. Sum the two inertias
314  // 5. Transform the summed inertia to the new COM
315 
316  Math::RigidBodyInertia other_rbi = Math::createFromMassComInertiaC(other_body.mMass, other_body.mCenterOfMass, other_body.mInertia);
318 
319  Math::Matrix3d inertia_other = other_rbi.toMatrix().block<3, 3>(0, 0);
320 
321  // 1. Transform the inertia from other origin to other COM
322  Math::Matrix3d other_com_cross = other_body.mCenterOfMass.toTildeForm();
323  Math::Matrix3d inertia_other_com = inertia_other - other_mass * other_com_cross * other_com_cross.transpose();
324 
325  // 2. Rotate the inertia that it is aligned to the frame of this body
326  Math::Matrix3d inertia_other_com_rotated = transform.E.transpose() * inertia_other_com * transform.E;
327 
328  // 3. Transform inertia of other_body to the origin of the frame of this body
329  Math::Matrix3d inertia_other_com_rotated_this_origin = Math::parallel_axis(inertia_other_com_rotated, other_mass, other_com);
330 
331  // 4. Sum the two inertias
332  Math::Matrix3d inertia_summed = Math::Matrix3d(this_rbi.toMatrix().block<3, 3>(0, 0)) + inertia_other_com_rotated_this_origin;
333 
334  // 5. Transform the summed inertia to the new COM
335  Math::Matrix3d new_inertia = inertia_summed - new_mass * new_com.toTildeForm() * new_com.toTildeForm().transpose();
336 
337  Math::SpatialMatrix new_added_mass_matrix = this->addedMassMatrix + other_body.addedMassMatrix;
338  DragData new_drag_data = this->dragData + other_body.dragData;
339 
340  *this = Body(new_mass, new_com, new_inertia, new_cob, new_volume, new_added_mass_matrix, new_drag_data);
341  }
342 
343  ~Body(){};
344 
346  double mMass;
351 
352  double volume;
357 };
358 
365 struct FixedBody
366 {
368  double mMass;
373  double volume;
379  unsigned int mMovableParent;
381  // fixed body.
384 
385  static FixedBody CreateFromBody(const Body& body)
386  {
387  FixedBody fbody;
388 
389  fbody.mMass = body.mMass;
390  fbody.mCenterOfMass = body.mCenterOfMass;
391  fbody.mInertia = body.mInertia;
393  fbody.volume = body.volume;
394  fbody.addedMassMatrix = body.addedMassMatrix;
395  fbody.dragData = body.dragData;
396 
397  return fbody;
398  }
399 };
400 } // namespace RobotDynamics
401 
402 #endif
See V. Duindum p39-40 & Featherstone p32-33.
Definition: rdl_eigenmath.hpp:104
This class stores a bodies mass, center of mass, and inertia information. The inertia elements are st...
Definition: RigidBodyInertia.hpp:42
SpatialMatrix toMatrix() const
Definition: RigidBodyInertia.cpp:99
Definition: rdl_eigenmath.hpp:354
Definition: rdl_eigenmath.hpp:187
Definition: rdl_eigenmath.hpp:54
Matrix3d toTildeForm() const
Definition: rdl_eigenmath.cpp:118
A custom exception.
Definition: RdlExceptions.hpp:18
static RigidBodyInertia createFromMassComInertiaC(double mass, const Vector3d &com, const Matrix3d &inertia_C)
Definition: RigidBodyInertia.hpp:269
Vector3d Vector3dZero(0., 0., 0.)
Definition: rdl_mathutils.hpp:38
SpatialMatrix SpatialMatrixZero(0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.)
Definition: rdl_mathutils.hpp:45
Matrix3d parallel_axis(const Matrix3d &inertia, double mass, const Vector3d &com)
Translates the inertia matrix to a new center.
Definition: rdl_mathutils.cpp:122
Namespace for all structures of the RobotDynamics library.
Definition: examples.hpp:19
DragData operator+(DragData dragData1, const DragData &dragData2)
Definition: Body.hpp:72
Describes all properties of a single body.
Definition: Body.hpp:88
Body(const double &mass, const Math::Vector3d &com, const Math::Vector3d &gyration_radii, const Math::Vector3d &centerOfBuoyancy, const double volume, const Math::SpatialMatrix &addedMassMatrix, const DragData &dragData)
Constructs a body from mass, center of mass, radii of gyration, the center of buoyancy,...
Definition: Body.hpp:144
Math::Vector3d mCenterOfBuoyancy
Definition: Body.hpp:353
Body(const Body &body)
Definition: Body.hpp:101
Body(const double &mass, const Math::Vector3d &com, const Math::Matrix3d &inertia_C)
Constructs a body from mass, center of mass, a 3x3 inertia matrix. Hydrodynamic terms are set such th...
Definition: Body.hpp:257
double volume
Definition: Body.hpp:352
Body()
Definition: Body.hpp:89
Math::SpatialMatrix addedMassMatrix
Definition: Body.hpp:354
Body(const double &mass, const Math::Vector3d &com, const Math::Vector3d &gyration_radii)
Constructs a body from mass, center of mass, radii of gyration. Hydrodynamic terms are set such that ...
Definition: Body.hpp:186
Body & operator=(const Body &body)
Definition: Body.hpp:111
Body(const double &mass, const Math::Vector3d &com, const Math::Vector3d &gyration_radii, const Math::Vector3d &centerOfBuoyancy, const double volume, const Math::SpatialMatrix &addedMassMatrix)
Constructs a body from mass, center of mass, radii of gyration, the center of buoyancy,...
Definition: Body.hpp:166
Body(const double &mass, const Math::Vector3d &com, const Math::Matrix3d &inertia_C, const Math::Vector3d &centerOfBuoyancy, const double volume, const Math::SpatialMatrix &addedMassMatrix, const DragData &dragData)
Constructs a body from mass, center of mass, a 3x3 inertia matrix, the center of buoyancy,...
Definition: Body.hpp:210
Math::Matrix3d mInertia
Inertia matrix at the center of mass.
Definition: Body.hpp:350
double mMass
The mass of the body.
Definition: Body.hpp:343
bool mIsVirtual
Definition: Body.hpp:356
void join(const Math::SpatialTransform &transform, const Body &other_body)
Joins inertial parameters of two bodies to create a composite body.
Definition: Body.hpp:278
Body(const double &mass, const Math::Vector3d &com, const Math::Matrix3d &inertia_C, const Math::Vector3d &centerOfBuoyancy, const double volume, const Math::SpatialMatrix addedMassMatrix)
Constructs a body from mass, center of mass, a 3x3 inertia matrix, the center of buoyancy,...
Definition: Body.hpp:238
~Body()
Definition: Body.hpp:343
DragData dragData
Definition: Body.hpp:355
Math::Vector3d mCenterOfMass
The position of the center of mass in body coordinates.
Definition: Body.hpp:348
Definition: Body.hpp:21
void operator+=(const DragData &dragData)
Definition: Body.hpp:62
DragData()
Definition: Body.hpp:38
void zero()
Definition: Body.hpp:49
DragData(const DragData &dragData)
Definition: Body.hpp:43
Math::SpatialVector linearDrag
Definition: Body.hpp:68
DragData(const std::vector< double > &linear_drag, const std::vector< double > &quadratic_drag)
Definition: Body.hpp:22
DragData & operator=(const DragData &dragData)
Definition: Body.hpp:55
Math::SpatialVector quadraticDrag
Definition: Body.hpp:69
DragData(const Math::SpatialVector &linear_drag, const Math::SpatialVector &quadratic_drag)
Definition: Body.hpp:32
Keeps the information of a body and how it is attached to another body.
Definition: Body.hpp:366
Math::Matrix3d mInertia
The spatial inertia that contains both mass and inertia information.
Definition: Body.hpp:372
double mMass
The mass of the body.
Definition: Body.hpp:368
Math::Vector3d mCenterOfBuoyancy
Definition: Body.hpp:374
Math::SpatialTransform mBaseTransform
Definition: Body.hpp:383
Math::Vector3d mCenterOfMass
The position of the center of mass in body coordinates.
Definition: Body.hpp:370
double volume
Definition: Body.hpp:373
Math::SpatialTransform mParentTransform
Transforms spatial quantities expressed for the parent to the.
Definition: Body.hpp:382
unsigned int mMovableParent
Id of the movable body that this fixed body is attached to.
Definition: Body.hpp:379
static FixedBody CreateFromBody(const Body &body)
Definition: Body.hpp:385
Math::SpatialMatrix addedMassMatrix
Definition: Body.hpp:375
DragData dragData
Definition: Body.hpp:376
Compact representation of spatial transformations.
Definition: rdl_eigenmath.hpp:412
Matrix3d E
Definition: rdl_eigenmath.hpp:595
Vector3d r
Definition: rdl_eigenmath.hpp:596