Model.h
Go to the documentation of this file.
1 /*
2  * Original Copyright (c) 2011-2016 Martin Felis <martin.felis@iwr.uni-heidelberg.de>
3  *
4  *
5  * RDL - Robot Dynamics Library
6  * Modifications Copyright (c) 2017 Jordan Lack <jlack1987@gmail.com>
7  *
8  * Licensed under the zlib license. See LICENSE for more details.
9  */
10 
11 #ifndef RDL_MODEL_H
12 #define RDL_MODEL_H
13 
18 #include <assert.h>
19 #include <boost/asio/io_service.hpp>
20 #include <boost/function.hpp>
21 #include <boost/thread/thread.hpp>
22 #include <cstring>
23 #include <iostream>
24 #include <list>
25 #include <limits>
26 #include <map>
27 #include <type_traits>
28 
29 #include "rdl_dynamics/Body.h"
30 #include "rdl_dynamics/Joint.h"
40 
41 // std::vectors containing any objects that have Eigen matrices or vectors
42 // as members need to have a special allocater. This can be achieved with
43 // the following macro.
44 
48 
51 namespace RobotDynamics
52 {
121 struct Model
122 {
128  explicit Model(unsigned int* n_threads = nullptr);
129 
131  {
132  work.reset();
133  thread_pool.join_all();
134  }
135 
136  Model(const Model&) = delete;
137  void operator=(const Model&) = delete;
138 
139  // Structural information
140 
143  /* clang-format off */
144 
145  std::vector<ReferenceFramePtr> bodyFrames;
147  // clang for some reason continuously reformats the comment on the above line no matter
148  // how many times you run it.
149  /* clang-format on */
150 
152  std::vector<ReferenceFramePtr> bodyCenteredFrames;
153 
154  std::vector<ReferenceFramePtr> fixedBodyFrames;
155 
156  std::vector<unsigned int> lambda;
157  std::vector<std::vector<unsigned int>> lambda_chain;
159  std::vector<unsigned int> lambda_q;
162  std::vector<std::vector<unsigned int>> mu;
169  unsigned int dof_count;
170 
178  unsigned int q_size;
179 
187  unsigned int qdot_size;
188 
190  double mass;
191 
194 
197 
198  // State information
204  // Joints
206 
208 
209  std::vector<Joint> mJoints;
210 
214  // Joint state variables
215  std::vector<Math::SpatialTransform> X_J;
216 
217  std::vector<Math::SpatialVector> c_J;
221  std::vector<unsigned int> mJointUpdateOrder;
222 
224  // It is expressed in the coordinate frame of the parent.
225  std::vector<Math::SpatialTransform> X_T;
226 
229  std::vector<unsigned int> mFixedJointCount;
230 
232  // Special variables for joints with 3 degrees of freedom
234 
235  std::vector<Math::Matrix63> multdof3_S;
236  std::vector<Math::Matrix63> multdof3_S_o;
237  std::vector<Math::Matrix63> multdof3_U;
238  std::vector<Math::Matrix3d> multdof3_Dinv;
239  std::vector<Math::Vector3d> multdof3_u;
240  std::vector<unsigned int> multdof3_w_index;
241 
242  std::vector<CustomJoint*> mCustomJoints;
243 
245  // Dynamics variables
246 
248  std::vector<Math::SpatialVector> c;
249 
251  std::vector<Math::SpatialMatrix> IA;
252 
255 
257  std::vector<Math::SpatialVector> U;
258 
261 
264 
268 
275  std::vector<Math::Momentum> hc;
276 
287  // Bodies
289 
295  std::vector<Math::SpatialTransform> X_lambda;
296 
298  std::vector<FixedBody> mFixedBodies;
299 
313 
321  std::vector<Body> mBodies;
322 
324  std::map<std::string, unsigned int> mBodyNameMap;
325 
327  std::map<std::string, ReferenceFramePtr> referenceFrameMap;
328  unsigned int num_branch_ends;
329 
332 
333  boost::asio::io_service io_service;
334  std::unique_ptr<boost::asio::io_service::work> work;
335  std::vector<boost::thread*> threads;
336  boost::thread_group thread_pool;
337 
338  bool setThreadParameters(int policy, struct sched_param param)
339  {
340  if (threads.size() > 0)
341  {
342  for (unsigned int i = 0; i < threads.size(); ++i)
343  {
344  int retcode;
345  if ((retcode = pthread_setschedparam(threads[i]->native_handle(), policy, &param)) != 0)
346  {
347  if (retcode == EPERM)
348  {
349  std::cerr << "Model.setThreadParameters: Failed setting thread parameters. Invalid permissions" << std::endl;
350  }
351  else if (retcode == ESRCH)
352  {
353  std::cerr << "Model.setThreadParameters: Failed setting thread parameters. No thread with the ID could be found" << std::endl;
354  }
355  else if (retcode == EINVAL)
356  {
357  std::cerr << "Model.setThreadParameters: Failed setting thread parameters. policy is not a recognized policy, or param does not make sense for "
358  "the policy."
359  << std::endl;
360  }
361  else
362  {
363  std::cerr << "Model.setThreadParameters: Failed setting thread parameters. pthread_setschedparam returned with unknown error code " << retcode
364  << std::endl;
365  }
366 
367  return false;
368  }
369  }
370  }
371 
372  return true;
373  }
374 
406  unsigned int addBody(const unsigned int parent_id, const Math::SpatialTransform& joint_frame, const Joint& joint, const Body& body, std::string body_name = "");
407 
408  unsigned int addBodySphericalJoint(const unsigned int parent_id, const Math::SpatialTransform& joint_frame, const Joint& joint, const Body& body,
409  std::string body_name = "");
410 
417  unsigned int appendBody(const Math::SpatialTransform& joint_frame, const Joint& joint, const Body& body, std::string body_name = "");
418 
419  unsigned int addBodyCustomJoint(const unsigned int parent_id, const Math::SpatialTransform& joint_frame, CustomJoint* custom_joint, const Body& body,
420  std::string body_name = "");
421 
432  unsigned int GetBodyId(const char* body_name) const
433  {
434  if (mBodyNameMap.count(body_name) == 0)
435  {
436  return std::numeric_limits<unsigned int>::max();
437  }
438 
439  return mBodyNameMap.find(body_name)->second;
440  }
441 
448  ReferenceFramePtr getReferenceFrame(const std::string& frameName) const
449  {
450  ReferenceFramePtr frame;
451  try
452  {
453  frame = referenceFrameMap.at(frameName);
454  }
455  catch (const std::out_of_range& e)
456  {
457  frame = nullptr;
458  }
459 
460  return frame;
461  }
462 
464  std::string GetBodyName(unsigned int body_id) const
465  {
466  std::map<std::string, unsigned int>::const_iterator iter = mBodyNameMap.begin();
467 
468  while (iter != mBodyNameMap.end())
469  {
470  if (iter->second == body_id)
471  {
472  return iter->first;
473  }
474 
475  ++iter;
476  }
477 
478  return "";
479  }
480 
483  bool IsFixedBodyId(unsigned int body_id) const
484  {
485  if ((body_id >= fixed_body_discriminator) && (body_id < std::numeric_limits<unsigned int>::max()) && (body_id - fixed_body_discriminator < mFixedBodies.size()))
486  {
487  return true;
488  }
489  return false;
490  }
491 
492  bool IsBodyId(unsigned int id) const
493  {
494  if ((id > 0) && (id < mBodies.size()))
495  {
496  return true;
497  }
498 
499  if ((id >= fixed_body_discriminator) && (id < std::numeric_limits<unsigned int>::max()))
500  {
501  if (id - fixed_body_discriminator < mFixedBodies.size())
502  {
503  return true;
504  }
505  }
506  return false;
507  }
508 
516  unsigned int GetParentBodyId(unsigned int id)
517  {
518  if (id >= fixed_body_discriminator)
519  {
520  return mFixedBodies[id - fixed_body_discriminator].mMovableParent;
521  }
522 
523  unsigned int parent_id = lambda[id];
524 
525  while (mBodies[parent_id].mIsVirtual)
526  {
527  parent_id = lambda[parent_id];
528  }
529 
530  return parent_id;
531  }
532 
538  {
539  if (id >= fixed_body_discriminator)
540  {
541  return mFixedBodies[id - fixed_body_discriminator].mParentTransform;
542  }
543 
544  unsigned int child_id = id;
545  unsigned int parent_id = lambda[id];
546 
547  if (mBodies[parent_id].mIsVirtual)
548  {
549  while (mBodies[parent_id].mIsVirtual)
550  {
551  child_id = parent_id;
552  parent_id = lambda[child_id];
553  }
554  return X_T[child_id];
555  }
556  else
557  {
558  return X_T[id];
559  }
560  }
561 
565  void SetJointFrame(unsigned int id, const Math::SpatialTransform& transform)
566  {
567  if (id >= fixed_body_discriminator)
568  {
569  throw RdlException("Error: setting of parent transform not supported for fixed bodies!");
570  }
571 
572  unsigned int child_id = id;
573  unsigned int parent_id = lambda[id];
574 
575  if (mBodies[parent_id].mIsVirtual)
576  {
577  while (mBodies[parent_id].mIsVirtual)
578  {
579  child_id = parent_id;
580  parent_id = lambda[child_id];
581  }
582  X_T[child_id] = transform;
583  }
584  else if (id > 0)
585  {
586  X_T[id] = transform;
587  }
588  }
589 
596  Math::Quaternion GetQuaternion(unsigned int i, const Math::VectorNd& Q) const
597  {
598  assert(mJoints[i].mJointType == JointTypeSpherical);
599  unsigned int q_index = mJoints[i].q_index;
600  return Math::Quaternion(Q[q_index], Q[q_index + 1], Q[q_index + 2], Q[multdof3_w_index[i]]);
601  }
602 
609  void SetQuaternion(unsigned int i, const Math::Quaternion& quat, Math::VectorNd& Q) const
610  {
611  assert(mJoints[i].mJointType == JointTypeSpherical);
612  unsigned int q_index = mJoints[i].q_index;
613 
614  Q[q_index] = quat[0];
615  Q[q_index + 1] = quat[1];
616  Q[q_index + 2] = quat[2];
617  Q[multdof3_w_index[i]] = quat[3];
618  }
619 
620  unsigned int getCommonMovableParentId(unsigned int id_1, unsigned int id_2) const
621  {
622  if (IsFixedBodyId(id_1))
623  {
624  id_1 = mFixedBodies[id_1 - fixed_body_discriminator].mMovableParent;
625  }
626 
627  if (IsFixedBodyId(id_2))
628  {
629  id_2 = mFixedBodies[id_2 - fixed_body_discriminator].mMovableParent;
630  }
631 
632  if (id_1 == id_2)
633  {
634  return id_1;
635  }
636 
637  if (id_1 == 0 || id_2 == 0)
638  {
639  return 0;
640  }
641 
642  unsigned int chain_1_size = lambda_chain[id_1].size();
643  unsigned int chain_2_size = lambda_chain[id_2].size();
644 
645  if (chain_1_size <= chain_2_size)
646  {
647  // Can start at 1 bc every list should start with world body id which is zero
648  for (unsigned int i = 1; i < chain_1_size; i++)
649  {
650  if (lambda_chain[id_1][i] != lambda_chain[id_2][i])
651  {
652  return lambda_chain[id_1][i - 1];
653  }
654  }
655 
656  return lambda_chain[id_1][chain_1_size - 1];
657  }
658  else
659  {
660  // Can start at 1 bc every list should start with world body id which is zero
661  for (unsigned int i = 1; i < chain_2_size; i++)
662  {
663  if (lambda_chain[id_1][i] != lambda_chain[id_2][i])
664  {
665  return lambda_chain[id_2][i - 1];
666  }
667  }
668 
669  return lambda_chain[id_2][chain_2_size - 1];
670  }
671  }
672 
673  void crawlChainKinematics(unsigned int b_id, std::atomic<unsigned int>* branch_ends, const Math::VectorNd* Q, const Math::VectorNd* QDot,
674  const Math::VectorNd* QDDot);
675 
676  private:
677  bool validateRigidBodyInertia(const Body& body)
678  {
679  if (body.mIsVirtual)
680  {
681  // don't care about virtual bodies really
682  return true;
683  }
684 
686  if (rbi(0, 0) <= 0 || rbi(1, 1) <= 0 || rbi(2, 2) <= 0)
687  {
688  std::cerr << "\033[1;31m Invalid inertia: Each element of the trace must be > 0 \033[0m" << std::endl;
689  return false;
690  }
691 
692  if (rbi(0, 0) >= (rbi(1, 1) + rbi(2, 2)))
693  {
694  std::cerr << "\033[1;31m Invalid inertia: Triangle inequality not satisfied \033[0m\n" << std::endl;
695  return false;
696  }
697 
698  if (rbi(1, 1) >= (rbi(2, 2) + rbi(0, 0)))
699  {
700  std::cerr << "\033[1;31m Invalid inertia: Triangle inequality not satisfied \033[0m\n" << std::endl;
701  return false;
702  }
703 
704  if (rbi(2, 2) >= (rbi(1, 1) + rbi(0, 0)))
705  {
706  std::cerr << "\033[1;31m Invalid inertia: Triangle inequality not satisfied \033[0m\n" << std::endl;
707  return false;
708  }
709 
710  if (!(rbi - rbi.transpose()).isZero(1.e-8))
711  {
712  std::cerr << "\033[1;31m Invalid inertia: Inertia matrix is not symmetric \033[0m\n" << std::endl;
713  return false;
714  }
715 
716  Eigen::EigenSolver<Eigen::Matrix3d> solver(rbi);
717  Eigen::EigenSolver<Eigen::Matrix3d>::EigenvalueType eivals = solver.eigenvalues();
718 
719  for (unsigned int i = 0; i < eivals.rows(); i++)
720  {
721  if (eivals[i].real() <= 0)
722  {
723  std::cerr << "\033[1;31m Invalid inertia: Inertia matrix is not positive definite \033[0m\n" << std::endl;
724  return false;
725  }
726  }
727 
728  return true;
729  }
730 };
731 typedef std::shared_ptr<Model> ModelPtr;
733 } // namespace RobotDynamics
734 
735 /* _MODEL_H */
736 #endif // ifndef RDL_MODEL_H
std::vector< unsigned int > lambda_q
Definition: Model.h:159
Math::MotionVectorV S_o
Definition: Model.h:212
std::vector< Math::SpatialMatrix > IA
The spatial inertia of the bodies.
Definition: Model.h:251
std::vector< unsigned int > mJointUpdateOrder
Definition: Model.h:221
bool IsFixedBodyId(unsigned int body_id) const
Checks whether the body is rigidly attached to another body.
Definition: Model.h:483
std::vector< SpatialForce, Eigen::aligned_allocator< SpatialForce > > SpatialForceV
std::vector< Joint > mJoints
All joints.
Definition: Model.h:209
Describes all properties of a single body.
Definition: Body.h:30
Math::VectorNd u
Temporary variable u (RBDA p. 130)
Definition: Model.h:263
unsigned int GetParentBodyId(unsigned int id)
Determines id the actual parent body.
Definition: Model.h:516
std::vector< Math::SpatialVector > c_J
Definition: Model.h:217
Math::Quaternion GetQuaternion(unsigned int i, const Math::VectorNd &Q) const
Gets the quaternion for body i (only valid if body i is connected by a JointTypeSpherical joint) ...
Definition: Model.h:596
std::vector< SpatialAcceleration, Eigen::aligned_allocator< SpatialAcceleration > > SpatialAccelerationV
std::vector< unsigned int > multdof3_w_index
Definition: Model.h:240
EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(RobotDynamics::Joint)
VectorNd QDDot
std::unique_ptr< boost::asio::io_service::work > work
Definition: Model.h:334
boost::thread_group thread_pool
Definition: Model.h:336
std::vector< Math::Matrix63 > multdof3_U
Definition: Model.h:237
void operator=(const Model &)=delete
CustomJoint is a struct used to create a joint with user defined parameters. This is accomplished by ...
Definition: Joint.h:662
std::shared_ptr< Model > ModelPtr
Definition: Model.h:731
void SetQuaternion(unsigned int i, const Math::Quaternion &quat, Math::VectorNd &Q) const
Sets the quaternion for body i (only valid if body i is connected by a JointTypeSpherical joint) ...
Definition: Model.h:609
std::vector< FixedBody > mFixedBodies
All bodies that are attached to a body via a fixed joint.
Definition: Model.h:298
std::vector< unsigned int > lambda
Definition: Model.h:156
unsigned int num_branch_ends
Definition: Model.h:328
VectorNd QDot
Math::VectorNd ndof0_vec
Definition: Model.h:284
Keeps the information of a body and how it is attached to another body.
Definition: Body.h:173
Math::SpatialInertiaV Ib_c
Definition: Model.h:273
VectorNd Q
std::vector< boost::thread * > threads
Definition: Model.h:335
unsigned int addBodySphericalJoint(const unsigned int parent_id, const Math::SpatialTransform &joint_frame, const Joint &joint, const Body &body, std::string body_name="")
Math::MotionVector gravity
the cartesian vector of the gravity
Definition: Model.h:196
Math::Matrix3d mInertia
Inertia matrix at the center of mass.
Definition: Body.h:162
unsigned int appendBody(const Math::SpatialTransform &joint_frame, const Joint &joint, const Body &body, std::string body_name="")
Adds a Body to the model such that the previously added Body is the Parent.
Definition: Model.cc:517
std::vector< std::vector< unsigned int > > mu
Definition: Model.h:162
std::vector< ReferenceFramePtr > bodyFrames
Definition: Model.h:145
unsigned int addBodyCustomJoint(const unsigned int parent_id, const Math::SpatialTransform &joint_frame, CustomJoint *custom_joint, const Body &body, std::string body_name="")
Definition: Model.cc:522
Math::VectorNd nbodies0_vec
Definition: Model.h:285
ReferenceFramePtr worldFrame
Definition: Model.h:141
std::map< std::string, unsigned int > mBodyNameMap
Human readable names for the bodies.
Definition: Model.h:324
unsigned int addBody(const unsigned int parent_id, const Math::SpatialTransform &joint_frame, const Joint &joint, const Body &body, std::string body_name="")
Connects a given body to the model.
Definition: Model.cc:271
std::vector< Math::SpatialTransform > X_lambda
Transformation from the parent body to the current body .
Definition: Model.h:295
bool setThreadParameters(int policy, struct sched_param param)
Definition: Model.h:338
ReferenceFramePtr getReferenceFrame(const std::string &frameName) const
Get a fixed or moveable body&#39;s reference frame.
Definition: Model.h:448
Math::SpatialMotionV v
Definition: Model.h:202
std::shared_ptr< ReferenceFrame > ReferenceFramePtr
boost::asio::io_service io_service
Definition: Model.h:333
unsigned int q_size
The size of the -vector. For models without spherical joints the value is the same as Model::dof_coun...
Definition: Model.h:178
std::vector< Math::Momentum > hc
Definition: Model.h:275
bool IsBodyId(unsigned int id) const
Definition: Model.h:492
Compact representation of spatial transformations.
Math::MatrixNd ndof0_mat
Definition: Model.h:281
Math::SpatialForceV pA
The spatial bias force.
Definition: Model.h:254
std::vector< Math::Matrix63 > multdof3_S_o
Definition: Model.h:236
void SetJointFrame(unsigned int id, const Math::SpatialTransform &transform)
Sets the joint frame transformtion, i.e. the second argument to Model::addBody(). ...
Definition: Model.h:565
std::vector< Body > mBodies
All bodies 0 ... N_B, including the base.
Definition: Model.h:321
Describes a joint relative to the predecessor body.
Definition: Joint.h:228
unsigned int GetBodyId(const char *body_name) const
Returns the id of a body that was passed to addBody()
Definition: Model.h:432
Quaternion that are used for singularity free joints.
Definition: Quaternion.h:25
Math::VectorNd q0_vec
Definition: Model.h:283
Math::VectorNd d
Temporary variable D_i (RBDA p. 130)
Definition: Model.h:260
Eigen::VectorXd VectorNd
Definition: rdl_eigenmath.h:25
void crawlChainKinematics(unsigned int b_id, std::atomic< unsigned int > *branch_ends, const Math::VectorNd *Q, const Math::VectorNd *QDot, const Math::VectorNd *QDDot)
Definition: Model.cc:539
Math::SpatialAccelerationV a
The spatial velocity of the bodies.
Definition: Model.h:200
std::vector< CustomJoint * > mCustomJoints
Definition: Model.h:242
std::vector< SpatialMotion, Eigen::aligned_allocator< SpatialMotion > > SpatialMotionV
std::map< std::string, ReferenceFramePtr > referenceFrameMap
Definition: Model.h:327
std::vector< SpatialInertia, Eigen::aligned_allocator< SpatialInertia > > SpatialInertiaV
std::vector< Math::Matrix3d > multdof3_Dinv
Definition: Model.h:238
std::vector< ReferenceFramePtr > bodyCenteredFrames
Definition: Model.h:152
Model(unsigned int *n_threads=nullptr)
Constructor.
Definition: Model.cc:22
Contains all information about the rigid body model.
Definition: Model.h:121
unsigned int getCommonMovableParentId(unsigned int id_1, unsigned int id_2) const
Definition: Model.h:620
std::vector< Math::SpatialVector > U
Temporary variable U_i (RBDA p. 130)
Definition: Model.h:257
Math::SpatialInertiaV I
Definition: Model.h:269
Eigen::MatrixXd MatrixNd
Definition: rdl_eigenmath.h:26
std::vector< Math::SpatialVector > c
The velocity dependent spatial acceleration.
Definition: Model.h:248
std::vector< unsigned int > mFixedJointCount
The number of fixed joints that have been declared before each joint.
Definition: Model.h:229
unsigned int fixed_body_discriminator
Value that is used to discriminate between fixed and movable bodies.
Definition: Model.h:312
Math::RigidBodyInertiaV Ic
Definition: Model.h:270
Math::SpatialTransform GetJointFrame(unsigned int id)
Returns the joint frame transformtion, i.e. the second argument to Model::addBody().
Definition: Model.h:537
bool validateRigidBodyInertia(const Body &body)
Definition: Model.h:677
A custom exception.
Math::MatrixNd three_x_qd0
Definition: Model.h:282
Math::SpatialMotionV v_J
Definition: Model.h:219
std::vector< std::vector< unsigned int > > lambda_chain
Definition: Model.h:157
std::vector< Math::Matrix63 > multdof3_S
Motion subspace for joints with 3 degrees of freedom.
Definition: Model.h:235
std::string GetBodyName(unsigned int body_id) const
Returns the name of a body for a given body id.
Definition: Model.h:464
std::vector< ReferenceFramePtr > fixedBodyFrames
Definition: Model.h:154
3 DoF joint using Quaternions for joint positional variables and
Definition: Joint.h:195
std::vector< Math::SpatialTransform > X_J
Definition: Model.h:215
std::vector< Math::Vector3d > multdof3_u
Definition: Model.h:239
std::vector< MotionVector, Eigen::aligned_allocator< MotionVector > > MotionVectorV
Math::SpatialForceV f
Internal forces on the body (used only InverseDynamics())
Definition: Model.h:266
unsigned int dof_count
number of degrees of freedoms of the model
Definition: Model.h:169
Namespace for all structures of the RobotDynamics library.
Definition: Body.h:21
ReferenceFramePtr comFrame
Definition: Model.h:331
std::vector< Math::SpatialTransform > X_T
Transformations from the parent body to the frame of the joint.
Definition: Model.h:225
std::vector< RigidBodyInertia, Eigen::aligned_allocator< RigidBodyInertia > > RigidBodyInertiaV
unsigned int previously_added_body_id
Id of the previously added body, required for Model::appendBody()
Definition: Model.h:193
unsigned int qdot_size
The size of the.
Definition: Model.h:187
Math::SpatialForceV f_b
Definition: Model.h:267
Math::MotionVectorV S
Definition: Model.h:211


rdl_dynamics
Author(s):
autogenerated on Tue Apr 20 2021 02:25:27