1 /* 2 * Copyright (c) 2011-2021, The DART development contributors 3 * All rights reserved. 4 * 5 * The list of contributors can be found at: 6 * https://github.com/dartsim/dart/blob/master/LICENSE 7 * 8 * This file is provided under the following "BSD-style" License: 9 * Redistribution and use in source and binary forms, with or 10 * without modification, are permitted provided that the following 11 * conditions are met: 12 * * Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * * Redistributions in binary form must reproduce the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer in the documentation and/or other materials provided 17 * with the distribution. 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 19 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 27 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 29 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #ifndef DART_DYNAMICS_BODYNODE_HPP_ 34 #define DART_DYNAMICS_BODYNODE_HPP_ 35 36 #include <string> 37 #include <vector> 38 39 #include <Eigen/Dense> 40 #include <Eigen/StdVector> 41 42 #include "dart/common/Deprecated.hpp" 43 #include "dart/common/EmbeddedAspect.hpp" 44 #include "dart/common/Signal.hpp" 45 #include "dart/config.hpp" 46 #include "dart/dynamics/Frame.hpp" 47 #include "dart/dynamics/Node.hpp" 48 #include "dart/dynamics/Skeleton.hpp" 49 #include "dart/dynamics/SmartPointer.hpp" 50 #include "dart/dynamics/SpecializedNodeManager.hpp" 51 #include "dart/dynamics/TemplatedJacobianNode.hpp" 52 #include "dart/dynamics/detail/BodyNodeAspect.hpp" 53 #include "dart/math/Geometry.hpp" 54 55 namespace dart { 56 namespace dynamics { 57 58 class GenCoord; 59 class Skeleton; 60 class Joint; 61 class DegreeOfFreedom; 62 class Shape; 63 class EndEffector; 64 class Marker; 65 66 /// BodyNode class represents a single node of the skeleton. 67 /// 68 /// BodyNode is a basic element of the skeleton. BodyNodes are hierarchically 69 /// connected and have a set of core functions for calculating derivatives. 70 /// 71 /// BodyNode inherits Frame, and a parent Frame of a BodyNode is the parent 72 /// BodyNode of the BodyNode. 73 DART_DECLARE_CLASS_WITH_VIRTUAL_BASE_BEGIN 74 class BodyNode 75 : public detail::BodyNodeCompositeBase, 76 public virtual BodyNodeSpecializedFor<ShapeNode, EndEffector, Marker>, 77 public SkeletonRefCountingBase, 78 public TemplatedJacobianNode<BodyNode> 79 { 80 public: 81 using ColShapeAddedSignal 82 = common::Signal<void(const BodyNode*, ConstShapePtr _newColShape)>; 83 84 using ColShapeRemovedSignal = ColShapeAddedSignal; 85 86 using StructuralChangeSignal = common::Signal<void(const BodyNode*)>; 87 using CompositeProperties = common::Composite::Properties; 88 89 using AllNodeStates = detail::AllNodeStates; 90 using NodeStateMap = detail::NodeStateMap; 91 92 using AllNodeProperties = detail::AllNodeProperties; 93 using NodePropertiesMap = detail::NodePropertiesMap; 94 95 using AspectProperties = detail::BodyNodeAspectProperties; 96 using Properties = common::Composite::MakeProperties<BodyNode>; 97 98 BodyNode(const BodyNode&) = delete; 99 100 /// Destructor 101 virtual ~BodyNode(); 102 103 /// Convert 'this' into a SoftBodyNode pointer if this BodyNode is a 104 /// SoftBodyNode, otherwise return nullptr 105 virtual SoftBodyNode* asSoftBodyNode(); 106 107 /// Convert 'const this' into a SoftBodyNode pointer if this BodyNode is a 108 /// SoftBodyNode, otherwise return nullptr 109 virtual const SoftBodyNode* asSoftBodyNode() const; 110 111 /// Set the Node::State of all Nodes attached to this BodyNode 112 void setAllNodeStates(const AllNodeStates& states); 113 114 /// Get the Node::State of all Nodes attached to this BodyNode 115 AllNodeStates getAllNodeStates() const; 116 117 /// Set the Node::Properties of all Nodes attached to this BodyNode 118 void setAllNodeProperties(const AllNodeProperties& properties); 119 120 /// Get the Node::Properties of all Nodes attached to this BodyNode 121 AllNodeProperties getAllNodeProperties() const; 122 123 /// Same as setCompositeProperties() 124 void setProperties(const CompositeProperties& _properties); 125 126 /// Set the UniqueProperties of this BodyNode 127 void setProperties(const AspectProperties& _properties); 128 129 /// Set the AspectState of this BodyNode 130 void setAspectState(const AspectState& state); 131 132 /// Set the AspectProperties of this BodyNode 133 void setAspectProperties(const AspectProperties& properties); 134 135 /// Get the Properties of this BodyNode 136 Properties getBodyNodeProperties() const; 137 138 /// Copy the Properties of another BodyNode 139 void copy(const BodyNode& otherBodyNode); 140 141 /// Copy the Properties of another BodyNode 142 void copy(const BodyNode* otherBodyNode); 143 144 /// Same as copy(const BodyNode&) 145 BodyNode& operator=(const BodyNode& _otherBodyNode); 146 147 /// Give this BodyNode a copy of each Node from otherBodyNode 148 void duplicateNodes(const BodyNode* otherBodyNode); 149 150 /// Make the Nodes of this BodyNode match the Nodes of otherBodyNode. All 151 /// existing Nodes in this BodyNode will be removed. 152 void matchNodes(const BodyNode* otherBodyNode); 153 154 /// Set name. If the name is already taken, this will return an altered 155 /// version which will be used by the Skeleton 156 const std::string& setName(const std::string& _name) override; 157 158 // Documentation inherited 159 const std::string& getName() const override; 160 161 /// Set whether gravity affects this body 162 /// \param[in] _gravityMode True to enable gravity 163 void setGravityMode(bool _gravityMode); 164 165 /// Return true if gravity mode is enabled 166 bool getGravityMode() const; 167 168 /// Return true if this body can collide with others bodies 169 bool isCollidable() const; 170 171 /// Set whether this body node will collide with others in the world 172 /// \param[in] _isCollidable True to enable collisions 173 void setCollidable(bool _isCollidable); 174 175 /// Set the mass of the bodynode 176 void setMass(double mass); 177 178 /// Return the mass of the bodynode 179 double getMass() const; 180 181 /// Set moment of inertia defined around the center of mass 182 /// 183 /// Principal moments of inertia (_Ixx, _Iyy, _Izz) must be positive or zero 184 /// values. 185 void setMomentOfInertia( 186 double _Ixx, 187 double _Iyy, 188 double _Izz, 189 double _Ixy = 0.0, 190 double _Ixz = 0.0, 191 double _Iyz = 0.0); 192 193 /// Return moment of inertia defined around the center of mass 194 void getMomentOfInertia( 195 double& _Ixx, 196 double& _Iyy, 197 double& _Izz, 198 double& _Ixy, 199 double& _Ixz, 200 double& _Iyz) const; 201 202 /// Return spatial inertia 203 const Eigen::Matrix6d& getSpatialInertia() const; 204 205 /// Set the inertia data for this BodyNode 206 void setInertia(const Inertia& inertia); 207 208 /// Get the inertia data for this BodyNode 209 const Inertia& getInertia() const; 210 211 /// Return the articulated body inertia 212 const math::Inertia& getArticulatedInertia() const; 213 214 /// Return the articulated body inertia for implicit joint damping and spring 215 /// forces 216 const math::Inertia& getArticulatedInertiaImplicit() const; 217 218 /// Set center of mass expressed in body frame 219 void setLocalCOM(const Eigen::Vector3d& _com); 220 221 /// Return center of mass expressed in body frame 222 const Eigen::Vector3d& getLocalCOM() const; 223 224 /// Return the center of mass with respect to an arbitrary Frame 225 Eigen::Vector3d getCOM(const Frame* _withRespectTo = Frame::World()) const; 226 227 /// Return the linear velocity of the center of mass, expressed in terms of 228 /// arbitrary Frames 229 Eigen::Vector3d getCOMLinearVelocity( 230 const Frame* _relativeTo = Frame::World(), 231 const Frame* _inCoordinatesOf = Frame::World()) const; 232 233 /// Return the spatial velocity of the center of mass, expressed in 234 /// coordinates of this Frame and relative to the World Frame 235 Eigen::Vector6d getCOMSpatialVelocity() const; 236 237 /// Return the spatial velocity of the center of mass, expressed in terms of 238 /// arbitrary Frames 239 Eigen::Vector6d getCOMSpatialVelocity( 240 const Frame* _relativeTo, const Frame* _inCoordinatesOf) const; 241 242 /// Return the linear acceleration of the center of mass, expressed in terms 243 /// of arbitary Frames 244 Eigen::Vector3d getCOMLinearAcceleration( 245 const Frame* _relativeTo = Frame::World(), 246 const Frame* _inCoordinatesOf = Frame::World()) const; 247 248 /// Return the acceleration of the center of mass expressed in coordinates of 249 /// this BodyNode Frame and relative to the World Frame 250 Eigen::Vector6d getCOMSpatialAcceleration() const; 251 252 /// Return the spatial acceleration of the center of mass, expressed in terms 253 /// of arbitrary Frames 254 Eigen::Vector6d getCOMSpatialAcceleration( 255 const Frame* _relativeTo, const Frame* _inCoordinatesOf) const; 256 257 /// Set coefficient of friction in range of [0, ~] 258 /// \deprecated Deprecated since DART 6.10. Please set the friction 259 /// coefficient per ShapeNode of the BodyNode. This will be removed in the 260 /// next major release. 261 DART_DEPRECATED(6.10) 262 void setFrictionCoeff(double _coeff); 263 264 /// Return frictional coefficient. 265 /// \deprecated Deprecated since DART 6.10. Please set the friction 266 /// coefficient per ShapeNode of the BodyNode. This will be removed in the 267 /// next major release. 268 DART_DEPRECATED(6.10) 269 double getFrictionCoeff() const; 270 271 /// Set coefficient of restitution in range of [0, 1] 272 /// \deprecated Deprecated since DART 6.10. Please set the restitution 273 /// coefficient per ShapeNode of the BodyNode. This will be removed in the 274 /// next major release. 275 DART_DEPRECATED(6.10) 276 void setRestitutionCoeff(double _coeff); 277 278 /// Return coefficient of restitution 279 /// \deprecated Deprecated since DART 6.10. Please set the restitution 280 /// coefficient per ShapeNode of the BodyNode. This will be removed in the 281 /// next major release. 282 DART_DEPRECATED(6.10) 283 double getRestitutionCoeff() const; 284 285 //-------------------------------------------------------------------------- 286 // Structural Properties 287 //-------------------------------------------------------------------------- 288 289 /// Return the index of this BodyNode within its Skeleton 290 std::size_t getIndexInSkeleton() const; 291 292 /// Return the index of this BodyNode within its tree 293 std::size_t getIndexInTree() const; 294 295 /// Return the index of the tree that this BodyNode belongs to 296 std::size_t getTreeIndex() const; 297 298 /// Remove this BodyNode and all of its children (recursively) from their 299 /// Skeleton. If a BodyNodePtr that references this BodyNode (or any of its 300 /// children) still exists, the subtree will be moved into a new Skeleton 301 /// with the given name. If the returned SkeletonPtr goes unused and no 302 /// relevant BodyNodePtrs are held anywhere, then this BodyNode and all its 303 /// children will be deleted. 304 /// 305 /// Note that this function is actually the same as split(), but given a 306 /// different name for semantic reasons. 307 SkeletonPtr remove(const std::string& _name = "temporary"); 308 309 /// Remove this BodyNode and all of its children (recursively) from their 310 /// current parent BodyNode, and move them to another parent BodyNode. The new 311 /// parent BodyNode can either be in a new Skeleton or the current one. If you 312 /// pass in a nullptr, this BodyNode will become a new root BodyNode for its 313 /// current Skeleton. 314 /// 315 /// Using this function will result in changes to the indexing of 316 /// (potentially) all BodyNodes and Joints in the current Skeleton, even if 317 /// the BodyNodes are kept within the same Skeleton. 318 bool moveTo(BodyNode* _newParent); 319 320 /// This is a version of moveTo(BodyNode*) that allows you to explicitly move 321 /// this BodyNode into a different Skeleton. The key difference for this 322 /// version of the function is that you can make this BodyNode a root node in 323 /// a different Skeleton, which is not something that can be done by the other 324 /// version. 325 bool moveTo(const SkeletonPtr& _newSkeleton, BodyNode* _newParent); 326 327 /// A version of moveTo(BodyNode*) that also changes the Joint type of the 328 /// parent Joint of this BodyNode. This function returns the pointer to the 329 /// newly created Joint. The original parent Joint will be deleted. 330 /// 331 /// This function can be used to change the Joint type of the parent Joint of 332 /// this BodyNode, but note that the indexing of the BodyNodes and Joints in 333 /// this Skeleton will still be changed, even if only the Joint type is 334 /// changed. 335 template <class JointType> 336 JointType* moveTo( 337 BodyNode* _newParent, 338 const typename JointType::Properties& _joint 339 = typename JointType::Properties()); 340 341 /// A version of moveTo(SkeletonPtr, BodyNode*) that also changes the Joint 342 /// type of the parent Joint of this BodyNode. This function returns the 343 /// pointer to the newly created Joint. The original Joint will be deleted. 344 template <class JointType> 345 JointType* moveTo( 346 const SkeletonPtr& _newSkeleton, 347 BodyNode* _newParent, 348 const typename JointType::Properties& _joint 349 = typename JointType::Properties()); 350 351 /// Remove this BodyNode and all of its children (recursively) from their 352 /// current Skeleton and move them into a newly created Skeleton. The newly 353 /// created Skeleton will have the same Skeleton::Properties as the current 354 /// Skeleton, except it will use the specified name. The return value is a 355 /// shared_ptr to the newly created Skeleton. 356 /// 357 /// Note that the parent Joint of this BodyNode will remain the same. If you 358 /// want to change the Joint type of this BodyNode's parent Joint (for 359 /// example, make it a FreeJoint), then use the templated split<JointType>() 360 /// function. 361 SkeletonPtr split(const std::string& _skeletonName); 362 363 /// A version of split(const std::string&) that also changes the Joint type of 364 /// the parent Joint of this BodyNode. 365 template <class JointType> 366 SkeletonPtr split( 367 const std::string& _skeletonName, 368 const typename JointType::Properties& _joint 369 = typename JointType::Properties()); 370 371 /// Change the Joint type of this BodyNode's parent Joint. 372 /// 373 /// Note that this function will change the indexing of (potentially) all 374 /// BodyNodes and Joints in the Skeleton. 375 template <class JointType> 376 JointType* changeParentJointType( 377 const typename JointType::Properties& _joint 378 = typename JointType::Properties()); 379 380 /// Create clones of this BodyNode and all of its children recursively (unless 381 /// _recursive is set to false) and attach the clones to the specified 382 /// BodyNode. The specified BodyNode can be in this Skeleton or a different 383 /// Skeleton. Passing in nullptr will set the copy as a root node of the 384 /// current Skeleton. 385 /// 386 /// The return value is a pair of pointers to the root of the newly created 387 /// BodyNode tree. 388 std::pair<Joint*, BodyNode*> copyTo( 389 BodyNode* _newParent, bool _recursive = true); 390 391 /// Create clones of this BodyNode and all of its children recursively (unless 392 /// recursive is set to false) and attach the clones to the specified BodyNode 393 /// of the specified Skeleton. 394 /// 395 /// The key differences between this function and the copyTo(BodyNode*) 396 /// version is that this one allows the copied BodyNode to be const and allows 397 /// you to copy it as a root node of another Skeleton. 398 /// 399 /// The return value is a pair of pointers to the root of the newly created 400 /// BodyNode tree. 401 std::pair<Joint*, BodyNode*> copyTo( 402 const SkeletonPtr& _newSkeleton, 403 BodyNode* _newParent, 404 bool _recursive = true) const; 405 406 /// A version of copyTo(BodyNode*) that also changes the Joint type of the 407 /// parent Joint of this BodyNode. 408 template <class JointType> 409 std::pair<JointType*, BodyNode*> copyTo( 410 BodyNode* _newParent, 411 const typename JointType::Properties& _joint 412 = typename JointType::Properties(), 413 bool _recursive = true); 414 415 /// A version of copyTo(Skeleton*,BodyNode*) that also changes the Joint type 416 /// of the parent Joint of this BodyNode. 417 template <class JointType> 418 std::pair<JointType*, BodyNode*> copyTo( 419 const SkeletonPtr& _newSkeleton, 420 BodyNode* _newParent, 421 const typename JointType::Properties& _joint 422 = typename JointType::Properties(), 423 bool _recursive = true) const; 424 425 /// Create clones of this BodyNode and all of its children (recursively) and 426 /// create a new Skeleton with the specified name to attach them to. The 427 /// Skeleton::Properties of the current Skeleton will also be copied into the 428 /// new Skeleton that gets created. 429 SkeletonPtr copyAs( 430 const std::string& _skeletonName, bool _recursive = true) const; 431 432 /// A version of copyAs(const std::string&) that also changes the Joint type 433 /// of the root BodyNode. 434 template <class JointType> 435 SkeletonPtr copyAs( 436 const std::string& _skeletonName, 437 const typename JointType::Properties& _joint 438 = typename JointType::Properties(), 439 bool _recursive = true) const; 440 441 // Documentation inherited 442 SkeletonPtr getSkeleton() override; 443 444 // Documentation inherited 445 ConstSkeletonPtr getSkeleton() const override; 446 447 /// Return the parent Joint of this BodyNode 448 Joint* getParentJoint(); 449 450 /// Return the (const) parent Joint of this BodyNode 451 const Joint* getParentJoint() const; 452 453 /// Return the parent BodyNdoe of this BodyNode 454 BodyNode* getParentBodyNode(); 455 456 /// Return the (const) parent BodyNode of this BodyNode 457 const BodyNode* getParentBodyNode() const; 458 459 /// Create a Joint and BodyNode pair as a child of this BodyNode 460 template <class JointType, class NodeType = BodyNode> 461 std::pair<JointType*, NodeType*> createChildJointAndBodyNodePair( 462 const typename JointType::Properties& _jointProperties 463 = typename JointType::Properties(), 464 const typename NodeType::Properties& _bodyProperties 465 = typename NodeType::Properties()); 466 467 /// Return the number of child BodyNodes 468 std::size_t getNumChildBodyNodes() const; 469 470 /// Return the _index-th child BodyNode of this BodyNode 471 BodyNode* getChildBodyNode(std::size_t _index); 472 473 /// Return the (const) _index-th child BodyNode of this BodyNode 474 const BodyNode* getChildBodyNode(std::size_t _index) const; 475 476 /// Return the number of child Joints 477 std::size_t getNumChildJoints() const; 478 479 /// Return the _index-th child Joint of this BodyNode 480 Joint* getChildJoint(std::size_t _index); 481 482 /// Return the (const) _index-th child Joint of this BodyNode 483 const Joint* getChildJoint(std::size_t _index) const; 484 485 /// Create some Node type and attach it to this BodyNode. 486 template <class NodeType, typename... Args> 487 NodeType* createNode(Args&&... args); 488 489 DART_BAKE_SPECIALIZED_NODE_DECLARATIONS(ShapeNode) 490 491 /// Create an ShapeNode attached to this BodyNode. Pass a 492 /// ShapeNode::Properties argument into its constructor. If automaticName is 493 /// true, then the mName field of properties will be ignored, and the 494 /// ShapeNode will be automatically assigned a name: 495 /// \<BodyNodeName\>_ShapeNode_<#> 496 template <class ShapeNodeProperties> 497 ShapeNode* createShapeNode( 498 ShapeNodeProperties properties, bool automaticName = true); 499 500 /// Create a ShapeNode with an automatically assigned name: 501 /// \<BodyNodeName\>_ShapeNode_<#>. 502 template <class ShapeType> 503 ShapeNode* createShapeNode(const std::shared_ptr<ShapeType>& shape); 504 505 /// Create a ShapeNode with the specified name 506 template <class ShapeType, class StringType> 507 ShapeNode* createShapeNode( 508 const std::shared_ptr<ShapeType>& shape, StringType&& name); 509 510 /// Return the list of ShapeNodes 511 const std::vector<ShapeNode*> getShapeNodes(); 512 513 /// Return the list of (const) ShapeNodes 514 const std::vector<const ShapeNode*> getShapeNodes() const; 515 516 /// Remove all ShapeNodes from this BodyNode 517 void removeAllShapeNodes(); 518 519 /// Create a ShapeNode with the specified Aspects and an automatically 520 /// assigned name: \<BodyNodeName\>_ShapeNode_<#>. 521 template <class... Aspects> 522 ShapeNode* createShapeNodeWith(const ShapePtr& shape); 523 524 /// Create a ShapeNode with the specified name and Aspects 525 template <class... Aspects> 526 ShapeNode* createShapeNodeWith( 527 const ShapePtr& shape, const std::string& name); 528 529 /// Return the number of ShapeNodes containing given Aspect in this BodyNode 530 template <class Aspect> 531 std::size_t getNumShapeNodesWith() const; 532 533 /// Return the list of ShapeNodes containing given Aspect 534 template <class Aspect> 535 const std::vector<ShapeNode*> getShapeNodesWith(); 536 537 /// Return the list of ShapeNodes containing given Aspect 538 template <class Aspect> 539 const std::vector<const ShapeNode*> getShapeNodesWith() const; 540 541 /// Remove all ShapeNodes containing given Aspect from this BodyNode 542 template <class Aspect> 543 void removeAllShapeNodesWith(); 544 545 DART_BAKE_SPECIALIZED_NODE_DECLARATIONS(EndEffector) 546 547 /// Create an EndEffector attached to this BodyNode. Pass an 548 /// EndEffector::Properties argument into this function. 549 EndEffector* createEndEffector( 550 const EndEffector::BasicProperties& _properties); 551 552 /// Create an EndEffector with the specified name 553 EndEffector* createEndEffector(const std::string& _name = "EndEffector"); 554 555 /// Create an EndEffector with the specified name 556 EndEffector* createEndEffector(const char* _name); 557 558 DART_BAKE_SPECIALIZED_NODE_DECLARATIONS(Marker) 559 560 /// Create a Marker with the given fields 561 Marker* createMarker( 562 const std::string& name = "marker", 563 const Eigen::Vector3d& position = Eigen::Vector3d::Zero(), 564 const Eigen::Vector4d& color = Eigen::Vector4d::Constant(1.0)); 565 566 /// Create a Marker given its basic properties 567 Marker* createMarker(const Marker::BasicProperties& properties); 568 569 // Documentation inherited 570 bool dependsOn(std::size_t _genCoordIndex) const override; 571 572 // Documentation inherited 573 std::size_t getNumDependentGenCoords() const override; 574 575 // Documentation inherited 576 std::size_t getDependentGenCoordIndex(std::size_t _arrayIndex) const override; 577 578 // Documentation inherited 579 const std::vector<std::size_t>& getDependentGenCoordIndices() const override; 580 581 // Documentation inherited 582 std::size_t getNumDependentDofs() const override; 583 584 // Documentation inherited 585 DegreeOfFreedom* getDependentDof(std::size_t _index) override; 586 587 // Documentation inherited 588 const DegreeOfFreedom* getDependentDof(std::size_t _index) const override; 589 590 // Documentation inherited 591 const std::vector<DegreeOfFreedom*>& getDependentDofs() override; 592 593 // Documentation inherited 594 const std::vector<const DegreeOfFreedom*>& getDependentDofs() const override; 595 596 // Documentation inherited 597 const std::vector<const DegreeOfFreedom*> getChainDofs() const override; 598 599 //-------------------------------------------------------------------------- 600 // Properties updated by dynamics (kinematics) 601 //-------------------------------------------------------------------------- 602 603 /// Get the transform of this BodyNode with respect to its parent BodyNode, 604 /// which is also its parent Frame. 605 const Eigen::Isometry3d& getRelativeTransform() const override; 606 607 // Documentation inherited 608 const Eigen::Vector6d& getRelativeSpatialVelocity() const override; 609 610 // Documentation inherited 611 const Eigen::Vector6d& getRelativeSpatialAcceleration() const override; 612 613 // Documentation inherited 614 const Eigen::Vector6d& getPrimaryRelativeAcceleration() const override; 615 616 /// Return the partial acceleration of this body 617 const Eigen::Vector6d& getPartialAcceleration() const override; 618 619 /// Return the generalized Jacobian targeting the origin of this BodyNode. The 620 /// Jacobian is expressed in the Frame of this BodyNode. 621 const math::Jacobian& getJacobian() const override final; 622 623 // Prevent the inherited getJacobian functions from being shadowed 624 using TemplatedJacobianNode<BodyNode>::getJacobian; 625 626 /// Return the generalized Jacobian targeting the origin of this BodyNode. The 627 /// Jacobian is expressed in the World Frame. 628 const math::Jacobian& getWorldJacobian() const override final; 629 630 // Prevent the inherited getWorldJacobian functions from being shadowed 631 using TemplatedJacobianNode<BodyNode>::getWorldJacobian; 632 633 /// Return the spatial time derivative of the generalized Jacobian targeting 634 /// the origin of this BodyNode. The Jacobian is expressed in this BodyNode's 635 /// coordinate Frame. 636 /// 637 /// NOTE: Since this is a spatial time derivative, it should be used with 638 /// spatial vectors. If you are using classical linear and angular 639 /// acceleration vectors, then use getJacobianClassicDeriv(), 640 /// getLinearJacobianDeriv(), or getAngularJacobianDeriv() instead. 641 const math::Jacobian& getJacobianSpatialDeriv() const override final; 642 643 // Prevent the inherited getJacobianSpatialDeriv functions from being shadowed 644 using TemplatedJacobianNode<BodyNode>::getJacobianSpatialDeriv; 645 646 /// Return the classical time derivative of the generalized Jacobian targeting 647 /// the origin of this BodyNode. The Jacobian is expressed in the World 648 /// coordinate Frame. 649 /// 650 /// NOTE: Since this is a classical time derivative, it should be used with 651 /// classical linear and angular vectors. If you are using spatial vectors, 652 /// use getJacobianSpatialDeriv() instead. 653 const math::Jacobian& getJacobianClassicDeriv() const override final; 654 655 // Prevent the inherited getJacobianClassicDeriv functions from being shadowed 656 using TemplatedJacobianNode<BodyNode>::getJacobianClassicDeriv; 657 658 /// Return the velocity change due to the constraint impulse 659 const Eigen::Vector6d& getBodyVelocityChange() const; 660 661 /// Set whether this body node is colliding with other objects. Note that 662 /// this status is set by the constraint solver during dynamics simulation but 663 /// not by collision detector. 664 /// \param[in] _isColliding True if this body node is colliding. 665 DART_DEPRECATED(6.0) 666 void setColliding(bool _isColliding); 667 668 /// Return whether this body node is set to be colliding with other objects. 669 /// \return True if this body node is colliding. 670 DART_DEPRECATED(6.0) 671 bool isColliding(); 672 673 /// Add applying linear Cartesian forces to this node 674 /// 675 /// A force is defined by a point of application and a force vector. The 676 /// last two parameters specify frames of the first two parameters. 677 /// Coordinate transformations are applied when needed. The point of 678 /// application and the force in local coordinates are stored in mContacts. 679 /// When conversion is needed, make sure the transformations are avaialble. 680 void addExtForce( 681 const Eigen::Vector3d& _force, 682 const Eigen::Vector3d& _offset = Eigen::Vector3d::Zero(), 683 bool _isForceLocal = false, 684 bool _isOffsetLocal = true); 685 686 /// Set Applying linear Cartesian forces to this node. 687 void setExtForce( 688 const Eigen::Vector3d& _force, 689 const Eigen::Vector3d& _offset = Eigen::Vector3d::Zero(), 690 bool _isForceLocal = false, 691 bool _isOffsetLocal = true); 692 693 /// Add applying Cartesian torque to the node. 694 /// 695 /// The torque in local coordinates is accumulated in mExtTorqueBody. 696 void addExtTorque(const Eigen::Vector3d& _torque, bool _isLocal = false); 697 698 /// Set applying Cartesian torque to the node. 699 /// 700 /// The torque in local coordinates is accumulated in mExtTorqueBody. 701 void setExtTorque(const Eigen::Vector3d& _torque, bool _isLocal = false); 702 703 /// Clean up structures that store external forces: mContacts, mFext, 704 /// mExtForceBody and mExtTorqueBody. 705 /// 706 /// Called by Skeleton::clearExternalForces. 707 virtual void clearExternalForces(); 708 709 /// Clear out the generalized forces of the parent Joint and any other forces 710 /// related to this BodyNode that are internal to the Skeleton. For example, 711 /// the point mass forces for SoftBodyNodes. 712 virtual void clearInternalForces(); 713 714 /// 715 const Eigen::Vector6d& getExternalForceLocal() const; 716 717 /// 718 Eigen::Vector6d getExternalForceGlobal() const; 719 720 /// Get spatial body force transmitted from the parent joint. 721 /// 722 /// The spatial body force is transmitted to this BodyNode from the parent 723 /// body through the connecting joint. It is expressed in this BodyNode's 724 /// frame. 725 const Eigen::Vector6d& getBodyForce() const; 726 727 //---------------------------------------------------------------------------- 728 // Constraints 729 // - Following functions are managed by constraint solver. 730 //---------------------------------------------------------------------------- 731 732 /// Return true if the body can react to force or constraint impulse. 733 /// 734 /// A body node is reactive if the skeleton is mobile and the number of 735 /// dependent generalized coordinates is non zero. 736 bool isReactive() const; 737 738 /// Set constraint impulse 739 /// \param[in] _constImp Spatial constraint impulse w.r.t. body frame 740 void setConstraintImpulse(const Eigen::Vector6d& _constImp); 741 742 /// Add constraint impulse 743 /// \param[in] _constImp Spatial constraint impulse w.r.t. body frame 744 void addConstraintImpulse(const Eigen::Vector6d& _constImp); 745 746 /// Add constraint impulse 747 void addConstraintImpulse( 748 const Eigen::Vector3d& _constImp, 749 const Eigen::Vector3d& _offset, 750 bool _isImpulseLocal = false, 751 bool _isOffsetLocal = true); 752 753 /// Clear constraint impulses and cache data used for impulse-based forward 754 /// dynamics algorithm 755 virtual void clearConstraintImpulse(); 756 757 /// Return constraint impulse 758 const Eigen::Vector6d& getConstraintImpulse() const; 759 760 //---------------------------------------------------------------------------- 761 // Energies 762 //---------------------------------------------------------------------------- 763 764 /// Return Lagrangian of this body 765 double computeLagrangian(const Eigen::Vector3d& gravity) const; 766 767 /// Return kinetic energy. 768 DART_DEPRECATED(6.1) 769 virtual double getKineticEnergy() const; 770 771 /// Return kinetic energy 772 double computeKineticEnergy() const; 773 774 /// Return potential energy. 775 DART_DEPRECATED(6.1) 776 virtual double getPotentialEnergy(const Eigen::Vector3d& _gravity) const; 777 778 /// Return potential energy. 779 double computePotentialEnergy(const Eigen::Vector3d& gravity) const; 780 781 /// Return linear momentum. 782 Eigen::Vector3d getLinearMomentum() const; 783 784 /// Return angular momentum. 785 Eigen::Vector3d getAngularMomentum( 786 const Eigen::Vector3d& _pivot = Eigen::Vector3d::Zero()); 787 788 //---------------------------------------------------------------------------- 789 // Notifications 790 //---------------------------------------------------------------------------- 791 792 // Documentation inherited 793 void dirtyTransform() override; 794 795 // Documentation inherited 796 void dirtyVelocity() override; 797 798 // Documentation inherited 799 void dirtyAcceleration() override; 800 801 /// Notify the Skeleton that the tree of this BodyNode needs an articulated 802 /// inertia update 803 DART_DEPRECATED(6.2) 804 void notifyArticulatedInertiaUpdate(); 805 806 /// Notify the Skeleton that the tree of this BodyNode needs an articulated 807 /// inertia update 808 void dirtyArticulatedInertia(); 809 810 /// Tell the Skeleton that the external forces need to be updated 811 DART_DEPRECATED(6.2) 812 void notifyExternalForcesUpdate(); 813 814 /// Tell the Skeleton that the external forces need to be updated 815 void dirtyExternalForces(); 816 817 /// Tell the Skeleton that the coriolis forces need to be update 818 DART_DEPRECATED(6.2) 819 void notifyCoriolisUpdate(); 820 821 /// Tell the Skeleton that the coriolis forces need to be update 822 void dirtyCoriolisForces(); 823 824 //---------------------------------------------------------------------------- 825 // Friendship 826 //---------------------------------------------------------------------------- 827 828 friend class Skeleton; 829 friend class Joint; 830 friend class EndEffector; 831 friend class SoftBodyNode; 832 friend class PointMass; 833 friend class Node; 834 835 protected: 836 /// Constructor called by Skeleton class 837 BodyNode( 838 BodyNode* _parentBodyNode, 839 Joint* _parentJoint, 840 const Properties& _properties); 841 842 /// Delegating constructor 843 BodyNode(const std::tuple<BodyNode*, Joint*, Properties>& args); 844 845 /// Create a clone of this BodyNode. This may only be called by the Skeleton 846 /// class. 847 virtual BodyNode* clone( 848 BodyNode* _parentBodyNode, Joint* _parentJoint, bool cloneNodes) const; 849 850 /// This is needed in order to inherit the Node class, but it does nothing 851 Node* cloneNode(BodyNode* bn) const override final; 852 853 /// Initialize the vector members with proper sizes. 854 virtual void init(const SkeletonPtr& _skeleton); 855 856 /// Add a child bodynode into the bodynode 857 void addChildBodyNode(BodyNode* _body); 858 859 //---------------------------------------------------------------------------- 860 /// \{ \name Recursive dynamics routines 861 //---------------------------------------------------------------------------- 862 863 /// Separate generic child Entities from child BodyNodes for more efficient 864 /// update notices 865 void processNewEntity(Entity* _newChildEntity) override; 866 867 /// Remove this Entity from mChildBodyNodes or mNonBodyNodeEntities 868 void processRemovedEntity(Entity* _oldChildEntity) override; 869 870 /// Update transformation 871 virtual void updateTransform(); 872 873 /// Update spatial body velocity. 874 virtual void updateVelocity(); 875 876 /// Update partial spatial body acceleration due to parent joint's velocity. 877 virtual void updatePartialAcceleration() const; 878 879 /// Update articulated body inertia for forward dynamics. 880 /// \param[in] _timeStep Rquired for implicit joint stiffness and damping. 881 virtual void updateArtInertia(double _timeStep) const; 882 883 /// Update bias force associated with the articulated body inertia for forward 884 /// dynamics. 885 /// \param[in] _gravity Vector of gravitational acceleration 886 /// \param[in] _timeStep Rquired for implicit joint stiffness and damping. 887 virtual void updateBiasForce( 888 const Eigen::Vector3d& _gravity, double _timeStep); 889 890 /// Update bias impulse associated with the articulated body inertia for 891 /// impulse-based forward dynamics. 892 virtual void updateBiasImpulse(); 893 894 /// Update spatial body acceleration with the partial spatial body 895 /// acceleration for inverse dynamics. 896 virtual void updateAccelerationID(); 897 898 /// Update spatial body acceleration for forward dynamics. 899 virtual void updateAccelerationFD(); 900 901 /// Update spatical body velocity change for impluse-based forward dynamics. 902 virtual void updateVelocityChangeFD(); 903 904 /// Update spatial body force for inverse dynamics. 905 /// 906 /// The spatial body force is transmitted to this BodyNode from the parent 907 /// body through the connecting joint. It is expressed in this BodyNode's 908 /// frame. 909 virtual void updateTransmittedForceID( 910 const Eigen::Vector3d& _gravity, bool _withExternalForces = false); 911 912 /// Update spatial body force for forward dynamics. 913 /// 914 /// The spatial body force is transmitted to this BodyNode from the parent 915 /// body through the connecting joint. It is expressed in this BodyNode's 916 /// frame. 917 virtual void updateTransmittedForceFD(); 918 919 /// Update spatial body force for impulse-based forward dynamics. 920 /// 921 /// The spatial body impulse is transmitted to this BodyNode from the parent 922 /// body through the connecting joint. It is expressed in this BodyNode's 923 /// frame. 924 virtual void updateTransmittedImpulse(); 925 // TODO: Rename to updateTransmittedImpulseFD if impulse-based inverse 926 // dynamics is implemented. 927 928 /// Update the joint force for inverse dynamics. 929 virtual void updateJointForceID( 930 double _timeStep, bool _withDampingForces, bool _withSpringForces); 931 932 /// Update the joint force for forward dynamics. 933 virtual void updateJointForceFD( 934 double _timeStep, bool _withDampingForces, bool _withSpringForces); 935 936 /// Update the joint impulse for forward dynamics. 937 virtual void updateJointImpulseFD(); 938 939 /// Update constrained terms due to the constraint impulses for foward 940 /// dynamics. 941 virtual void updateConstrainedTerms(double _timeStep); 942 943 /// \} 944 945 //---------------------------------------------------------------------------- 946 /// \{ \name Equations of motion related routines 947 //---------------------------------------------------------------------------- 948 949 /// 950 virtual void updateMassMatrix(); 951 virtual void aggregateMassMatrix(Eigen::MatrixXd& _MCol, std::size_t _col); 952 virtual void aggregateAugMassMatrix( 953 Eigen::MatrixXd& _MCol, std::size_t _col, double _timeStep); 954 955 /// 956 virtual void updateInvMassMatrix(); 957 virtual void updateInvAugMassMatrix(); 958 virtual void aggregateInvMassMatrix( 959 Eigen::MatrixXd& _InvMCol, std::size_t _col); 960 virtual void aggregateInvAugMassMatrix( 961 Eigen::MatrixXd& _InvMCol, std::size_t _col, double _timeStep); 962 963 /// 964 virtual void aggregateCoriolisForceVector(Eigen::VectorXd& _C); 965 966 /// 967 virtual void aggregateGravityForceVector( 968 Eigen::VectorXd& _g, const Eigen::Vector3d& _gravity); 969 970 /// 971 virtual void updateCombinedVector(); 972 virtual void aggregateCombinedVector( 973 Eigen::VectorXd& _Cg, const Eigen::Vector3d& _gravity); 974 975 /// Aggregate the external forces mFext in the generalized coordinates 976 /// recursively 977 virtual void aggregateExternalForces(Eigen::VectorXd& _Fext); 978 979 /// 980 virtual void aggregateSpatialToGeneralized( 981 Eigen::VectorXd& _generalized, const Eigen::Vector6d& _spatial); 982 983 /// Update body Jacobian. getJacobian() calls this function if 984 /// mIsBodyJacobianDirty is true. 985 void updateBodyJacobian() const; 986 987 /// Update the World Jacobian. The commonality of using the World Jacobian 988 /// makes it worth caching. 989 void updateWorldJacobian() const; 990 991 /// Update spatial time derivative of body Jacobian. 992 /// getJacobianSpatialTimeDeriv() calls this function if 993 /// mIsBodyJacobianSpatialDerivDirty is true. 994 void updateBodyJacobianSpatialDeriv() const; 995 996 /// Update classic time derivative of body Jacobian. 997 /// getJacobianClassicDeriv() calls this function if 998 /// mIsWorldJacobianClassicDerivDirty is true. 999 void updateWorldJacobianClassicDeriv() const; 1000 1001 /// \} 1002 1003 protected: 1004 //-------------------------------------------------------------------------- 1005 // General properties 1006 //-------------------------------------------------------------------------- 1007 1008 /// A unique ID of this node globally. 1009 int mID; 1010 1011 /// Counts the number of nodes globally. 1012 static std::size_t msBodyNodeCount; 1013 1014 /// Whether the node is currently in collision with another node. 1015 /// \deprecated DART_DEPRECATED(6.0) See #670 for more detail. 1016 bool mIsColliding; 1017 1018 //-------------------------------------------------------------------------- 1019 // Structural Properties 1020 //-------------------------------------------------------------------------- 1021 1022 /// Index of this BodyNode in its Skeleton 1023 std::size_t mIndexInSkeleton; 1024 1025 /// Index of this BodyNode in its Tree 1026 std::size_t mIndexInTree; 1027 1028 /// Index of this BodyNode's tree 1029 std::size_t mTreeIndex; 1030 1031 /// Parent joint 1032 Joint* mParentJoint; 1033 1034 /// Parent body node 1035 BodyNode* mParentBodyNode; 1036 1037 /// Array of child body nodes 1038 std::vector<BodyNode*> mChildBodyNodes; 1039 1040 /// Array of child Entities that are not BodyNodes. Organizing them separately 1041 /// allows some performance optimizations. 1042 std::set<Entity*> mNonBodyNodeEntities; 1043 1044 /// A increasingly sorted list of dependent dof indices. 1045 std::vector<std::size_t> mDependentGenCoordIndices; 1046 1047 /// A version of mDependentGenCoordIndices that holds DegreeOfFreedom pointers 1048 /// instead of indices 1049 std::vector<DegreeOfFreedom*> mDependentDofs; 1050 1051 /// Same as mDependentDofs, but holds const pointers 1052 std::vector<const DegreeOfFreedom*> mConstDependentDofs; 1053 1054 //-------------------------------------------------------------------------- 1055 // Dynamical Properties 1056 //-------------------------------------------------------------------------- 1057 1058 /// Body Jacobian 1059 /// 1060 /// Do not use directly! Use getJacobian() to access this quantity 1061 mutable math::Jacobian mBodyJacobian; 1062 1063 /// Cached World Jacobian 1064 /// 1065 /// Do not use directly! Use getJacobian() to access this quantity 1066 mutable math::Jacobian mWorldJacobian; 1067 1068 /// Spatial time derivative of body Jacobian. 1069 /// 1070 /// Do not use directly! Use getJacobianSpatialDeriv() to access this quantity 1071 mutable math::Jacobian mBodyJacobianSpatialDeriv; 1072 1073 /// Classic time derivative of Body Jacobian 1074 /// 1075 /// Do not use directly! Use getJacobianClassicDeriv() to access this quantity 1076 mutable math::Jacobian mWorldJacobianClassicDeriv; 1077 1078 /// Partial spatial body acceleration due to parent joint's velocity 1079 /// 1080 /// Do not use directly! Use getPartialAcceleration() to access this quantity 1081 mutable Eigen::Vector6d mPartialAcceleration; 1082 // TODO(JS): Rename with more informative name 1083 1084 /// Is the partial acceleration vector dirty 1085 mutable bool mIsPartialAccelerationDirty; 1086 1087 /// Transmitted wrench from parent to the bodynode expressed in body-fixed 1088 /// frame 1089 Eigen::Vector6d mF; 1090 1091 /// Spatial gravity force 1092 Eigen::Vector6d mFgravity; 1093 1094 /// Articulated body inertia 1095 /// 1096 /// Do not use directly! Use getArticulatedInertia() to access this quantity 1097 mutable math::Inertia mArtInertia; 1098 1099 /// Articulated body inertia for implicit joint damping and spring forces 1100 /// 1101 /// DO not use directly! Use getArticulatedInertiaImplicit() to access this 1102 mutable math::Inertia mArtInertiaImplicit; 1103 1104 /// Bias force 1105 Eigen::Vector6d mBiasForce; 1106 1107 /// Cache data for combined vector of the system. 1108 Eigen::Vector6d mCg_dV; 1109 Eigen::Vector6d mCg_F; 1110 1111 /// Cache data for gravity force vector of the system. 1112 Eigen::Vector6d mG_F; 1113 1114 /// Cache data for external force vector of the system. 1115 Eigen::Vector6d mFext_F; 1116 1117 /// Cache data for mass matrix of the system. 1118 Eigen::Vector6d mM_dV; 1119 Eigen::Vector6d mM_F; 1120 1121 /// Cache data for inverse mass matrix of the system. 1122 Eigen::Vector6d mInvM_c; 1123 Eigen::Vector6d mInvM_U; 1124 1125 /// Cache data for arbitrary spatial value 1126 Eigen::Vector6d mArbitrarySpatial; 1127 1128 //------------------------- Impulse-based Dyanmics --------------------------- 1129 /// Velocity change due to to external impulsive force exerted on 1130 /// bodies of the parent skeleton. 1131 Eigen::Vector6d mDelV; 1132 1133 /// Impulsive bias force due to external impulsive force exerted on 1134 /// bodies of the parent skeleton. 1135 Eigen::Vector6d mBiasImpulse; 1136 1137 /// Constraint impulse: contact impulse, dynamic joint impulse 1138 Eigen::Vector6d mConstraintImpulse; 1139 1140 // TODO(JS): rename with more informative one 1141 /// Generalized impulsive body force w.r.t. body frame. 1142 Eigen::Vector6d mImpF; 1143 1144 /// Collision shape added signal 1145 ColShapeAddedSignal mColShapeAddedSignal; 1146 1147 /// Collision shape removed signal 1148 ColShapeRemovedSignal mColShapeRemovedSignal; 1149 1150 /// Structural change signal 1151 StructuralChangeSignal mStructuralChangeSignal; 1152 1153 public: 1154 // To get byte-aligned Eigen vectors 1155 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 1156 1157 //---------------------------------------------------------------------------- 1158 /// \{ \name Slot registers 1159 //---------------------------------------------------------------------------- 1160 1161 /// Slot register for collision shape added signal 1162 common::SlotRegister<ColShapeAddedSignal> onColShapeAdded; 1163 1164 /// Slot register for collision shape removed signal 1165 common::SlotRegister<ColShapeRemovedSignal> onColShapeRemoved; 1166 1167 /// Raised when (1) parent BodyNode is changed, (2) moved between Skeletons, 1168 /// (3) parent Joint is changed 1169 mutable common::SlotRegister<StructuralChangeSignal> onStructuralChange; 1170 1171 /// \} 1172 1173 private: 1174 /// Hold onto a reference to this BodyNode's own Destructor to make sure that 1175 /// it never gets destroyed. 1176 std::shared_ptr<NodeDestructor> mSelfDestructor; 1177 }; 1178 DART_DECLARE_CLASS_WITH_VIRTUAL_BASE_END 1179 1180 } // namespace dynamics 1181 } // namespace dart 1182 1183 #include "dart/dynamics/detail/BodyNode.hpp" 1184 1185 #endif // DART_DYNAMICS_BODYNODE_HPP_ 1186