284 lines
12 KiB
C++
284 lines
12 KiB
C++
// The structs and classes defined here provide a basic inverse fynamics implementation used
|
|
// by MultiBodyTree
|
|
// User interaction should be through MultiBodyTree
|
|
|
|
#ifndef MULTI_BODY_REFERENCE_IMPL_HPP_
|
|
#define MULTI_BODY_REFERENCE_IMPL_HPP_
|
|
|
|
#include "../IDConfig.hpp"
|
|
#include "../MultiBodyTree.hpp"
|
|
|
|
namespace btInverseDynamics {
|
|
|
|
/// Structure for for rigid body mass properties, connectivity and kinematic state
|
|
/// all vectors and matrices are in body-fixed frame, if not indicated otherwise.
|
|
/// The body-fixed frame is located in the joint connecting the body to its parent.
|
|
struct RigidBody {
|
|
ID_DECLARE_ALIGNED_ALLOCATOR();
|
|
// 1 Inertial properties
|
|
/// Mass
|
|
idScalar m_mass;
|
|
/// Mass times center of gravity in body-fixed frame
|
|
vec3 m_body_mass_com;
|
|
/// Moment of inertia w.r.t. body-fixed frame
|
|
mat33 m_body_I_body;
|
|
|
|
// 2 dynamic properties
|
|
/// Left-hand side of the body equation of motion, translational part
|
|
vec3 m_eom_lhs_translational;
|
|
/// Left-hand side of the body equation of motion, rotational part
|
|
vec3 m_eom_lhs_rotational;
|
|
/// Force acting at the joint when the body is cut from its parent;
|
|
/// includes impressed joint force in J_JT direction,
|
|
/// as well as constraint force,
|
|
/// in body-fixed frame
|
|
vec3 m_force_at_joint;
|
|
/// Moment acting at the joint when the body is cut from its parent;
|
|
/// includes impressed joint moment in J_JR direction, and constraint moment
|
|
/// in body-fixed frame
|
|
vec3 m_moment_at_joint;
|
|
/// external (user provided) force acting at the body-fixed frame's origin, written in that
|
|
/// frame
|
|
vec3 m_body_force_user;
|
|
/// external (user provided) moment acting at the body-fixed frame's origin, written in that
|
|
/// frame
|
|
vec3 m_body_moment_user;
|
|
// 3 absolute kinematic properties
|
|
/// Position of body-fixed frame relative to world frame
|
|
/// this is currently only for debugging purposes
|
|
vec3 m_body_pos;
|
|
/// Absolute velocity of body-fixed frame
|
|
vec3 m_body_vel;
|
|
/// Absolute acceleration of body-fixed frame
|
|
/// NOTE: if gravitational acceleration is not zero, this is the accelation PLUS gravitational
|
|
/// acceleration!
|
|
vec3 m_body_acc;
|
|
/// Absolute angular velocity
|
|
vec3 m_body_ang_vel;
|
|
/// Absolute angular acceleration
|
|
/// NOTE: if gravitational acceleration is not zero, this is the accelation PLUS gravitational
|
|
/// acceleration!
|
|
vec3 m_body_ang_acc;
|
|
|
|
// 4 relative kinematic properties.
|
|
// these are in the parent body frame
|
|
/// Transform from world to body-fixed frame;
|
|
/// this is currently only for debugging purposes
|
|
mat33 m_body_T_world;
|
|
/// Transform from parent to body-fixed frame
|
|
mat33 m_body_T_parent;
|
|
/// Vector from parent to child frame in parent frame
|
|
vec3 m_parent_pos_parent_body;
|
|
/// Relative angular velocity
|
|
vec3 m_body_ang_vel_rel;
|
|
/// Relative linear velocity
|
|
vec3 m_parent_vel_rel;
|
|
/// Relative angular acceleration
|
|
vec3 m_body_ang_acc_rel;
|
|
/// Relative linear acceleration
|
|
vec3 m_parent_acc_rel;
|
|
|
|
// 5 Data describing the joint type and geometry
|
|
/// Type of joint
|
|
JointType m_joint_type;
|
|
/// Position of joint frame (body-fixed frame at q=0) relative to the parent frame
|
|
/// Components are in body-fixed frame of the parent
|
|
vec3 m_parent_pos_parent_body_ref;
|
|
/// Orientation of joint frame (body-fixed frame at q=0) relative to the parent frame
|
|
mat33 m_body_T_parent_ref;
|
|
/// Joint rotational Jacobian, ie, the partial derivative of the body-fixed frames absolute
|
|
/// angular velocity w.r.t. the generalized velocity of this body's relative degree of freedom.
|
|
/// For revolute joints this is the joint axis, for prismatic joints it is a null matrix.
|
|
/// (NOTE: dimensions will have to be dynamic for additional joint types!)
|
|
vec3 m_Jac_JR;
|
|
/// Joint translational Jacobian, ie, the partial derivative of the body-fixed frames absolute
|
|
/// linear velocity w.r.t. the generalized velocity of this body's relative degree of freedom.
|
|
/// For prismatic joints this is the joint axis, for revolute joints it is a null matrix.
|
|
/// (NOTE: dimensions might have to be dynamic for additional joint types!)
|
|
vec3 m_Jac_JT;
|
|
/// m_Jac_JT in the parent frame, it, m_body_T_parent_ref.transpose()*m_Jac_JT
|
|
vec3 m_parent_Jac_JT;
|
|
/// Start of index range for the position degree(s) of freedom describing this body's motion
|
|
/// relative to
|
|
/// its parent. The indices are wrt the multibody system's q-vector of generalized coordinates.
|
|
int m_q_index;
|
|
|
|
// 6 Scratch data for mass matrix computation using "composite rigid body algorithm"
|
|
/// mass of the subtree rooted in this body
|
|
idScalar m_subtree_mass;
|
|
/// center of mass * mass for subtree rooted in this body, in body-fixed frame
|
|
vec3 m_body_subtree_mass_com;
|
|
/// moment of inertia of subtree rooted in this body, w.r.t. body origin, in body-fixed frame
|
|
mat33 m_body_subtree_I_body;
|
|
|
|
#if (defined BT_ID_HAVE_MAT3X) && (defined BT_ID_WITH_JACOBIANS)
|
|
/// translational jacobian in body-fixed frame d(m_body_vel)/du
|
|
mat3x m_body_Jac_T;
|
|
/// rotationsl jacobian in body-fixed frame d(m_body_ang_vel)/du
|
|
mat3x m_body_Jac_R;
|
|
/// components of linear acceleration depending on u
|
|
/// (same as is d(m_Jac_T)/dt*u)
|
|
vec3 m_body_dot_Jac_T_u;
|
|
/// components of angular acceleration depending on u
|
|
/// (same as is d(m_Jac_T)/dt*u)
|
|
vec3 m_body_dot_Jac_R_u;
|
|
#endif
|
|
};
|
|
|
|
/// The MBS implements a tree structured multibody system
|
|
class MultiBodyTree::MultiBodyImpl {
|
|
friend class MultiBodyTree;
|
|
|
|
public:
|
|
ID_DECLARE_ALIGNED_ALLOCATOR();
|
|
|
|
enum KinUpdateType {
|
|
POSITION_ONLY,
|
|
POSITION_VELOCITY,
|
|
POSITION_VELOCITY_ACCELERATION
|
|
};
|
|
|
|
/// constructor
|
|
/// @param num_bodies the number of bodies in the system
|
|
/// @param num_dofs number of degrees of freedom in the system
|
|
MultiBodyImpl(int num_bodies_, int num_dofs_);
|
|
|
|
/// \copydoc MultiBodyTree::calculateInverseDynamics
|
|
int calculateInverseDynamics(const vecx& q, const vecx& u, const vecx& dot_u,
|
|
vecx* joint_forces);
|
|
///\copydoc MultiBodyTree::calculateMassMatrix
|
|
int calculateMassMatrix(const vecx& q, const bool update_kinematics,
|
|
const bool initialize_matrix, const bool set_lower_triangular_matrix,
|
|
matxx* mass_matrix);
|
|
/// calculate kinematics (vector quantities)
|
|
/// Depending on type, update positions only, positions & velocities, or positions, velocities
|
|
/// and accelerations.
|
|
int calculateKinematics(const vecx& q, const vecx& u, const vecx& dot_u, const KinUpdateType type);
|
|
#if (defined BT_ID_HAVE_MAT3X) && (defined BT_ID_WITH_JACOBIANS)
|
|
/// calculate jacobians and (if type == POSITION_VELOCITY), also velocity-dependent accelration terms.
|
|
int calculateJacobians(const vecx& q, const vecx& u, const KinUpdateType type);
|
|
/// \copydoc MultiBodyTree::getBodyDotJacobianTransU
|
|
int getBodyDotJacobianTransU(const int body_index, vec3* world_dot_jac_trans_u) const ;
|
|
/// \copydoc MultiBodyTree::getBodyDotJacobianRotU
|
|
int getBodyDotJacobianRotU(const int body_index, vec3* world_dot_jac_rot_u) const;
|
|
/// \copydoc MultiBodyTree::getBodyJacobianTrans
|
|
int getBodyJacobianTrans(const int body_index, mat3x* world_jac_trans) const ;
|
|
/// \copydoc MultiBodyTree::getBodyJacobianRot
|
|
int getBodyJacobianRot(const int body_index, mat3x* world_jac_rot) const;
|
|
/// Add relative Jacobian component from motion relative to parent body
|
|
/// @param body the body to add the Jacobian component for
|
|
void addRelativeJacobianComponent(RigidBody&body);
|
|
#endif
|
|
/// generate additional index sets from the parent_index array
|
|
/// @return -1 on error, 0 on success
|
|
int generateIndexSets();
|
|
/// set gravity acceleration in world frame
|
|
/// @param gravity gravity vector in the world frame
|
|
/// @return 0 on success, -1 on error
|
|
int setGravityInWorldFrame(const vec3& gravity);
|
|
/// pretty print tree
|
|
void printTree();
|
|
/// print tree data
|
|
void printTreeData();
|
|
/// initialize fixed data
|
|
void calculateStaticData();
|
|
/// \copydoc MultiBodyTree::getBodyFrame
|
|
int getBodyFrame(const int index, vec3* world_origin, mat33* body_T_world) const;
|
|
/// \copydoc MultiBodyTree::getParentIndex
|
|
int getParentIndex(const int body_index, int* m_parent_index);
|
|
/// \copydoc MultiBodyTree::getJointType
|
|
int getJointType(const int body_index, JointType* joint_type) const;
|
|
/// \copydoc MultiBodyTree::getJointTypeStr
|
|
int getJointTypeStr(const int body_index, const char** joint_type) const;
|
|
/// \copydoc MultiBodyTree::getParentRParentBodyRef
|
|
int getParentRParentBodyRef(const int body_index, vec3* r) const;
|
|
/// \copydoc MultiBodyTree::getBodyTParentRef
|
|
int getBodyTParentRef(const int body_index, mat33* T) const;
|
|
/// \copydoc MultiBodyTree::getBodyAxisOfMotion
|
|
int getBodyAxisOfMotion(const int body_index, vec3* axis) const;
|
|
/// \copydoc MultiBodyTree:getDoFOffset
|
|
int getDoFOffset(const int body_index, int* q_index) const;
|
|
/// \copydoc MultiBodyTree::getBodyOrigin
|
|
int getBodyOrigin(const int body_index, vec3* world_origin) const;
|
|
/// \copydoc MultiBodyTree::getBodyCoM
|
|
int getBodyCoM(const int body_index, vec3* world_com) const;
|
|
/// \copydoc MultiBodyTree::getBodyTransform
|
|
int getBodyTransform(const int body_index, mat33* world_T_body) const;
|
|
/// \copydoc MultiBodyTree::getBodyAngularVelocity
|
|
int getBodyAngularVelocity(const int body_index, vec3* world_omega) const;
|
|
/// \copydoc MultiBodyTree::getBodyLinearVelocity
|
|
int getBodyLinearVelocity(const int body_index, vec3* world_velocity) const;
|
|
/// \copydoc MultiBodyTree::getBodyLinearVelocityCoM
|
|
int getBodyLinearVelocityCoM(const int body_index, vec3* world_velocity) const;
|
|
/// \copydoc MultiBodyTree::getBodyAngularAcceleration
|
|
int getBodyAngularAcceleration(const int body_index, vec3* world_dot_omega) const;
|
|
/// \copydoc MultiBodyTree::getBodyLinearAcceleration
|
|
int getBodyLinearAcceleration(const int body_index, vec3* world_acceleration) const;
|
|
/// \copydoc MultiBodyTree::getUserInt
|
|
int getUserInt(const int body_index, int* user_int) const;
|
|
/// \copydoc MultiBodyTree::getUserPtr
|
|
int getUserPtr(const int body_index, void** user_ptr) const;
|
|
/// \copydoc MultiBodyTree::setUserInt
|
|
int setUserInt(const int body_index, const int user_int);
|
|
/// \copydoc MultiBodyTree::setUserPtr
|
|
int setUserPtr(const int body_index, void* const user_ptr);
|
|
///\copydoc MultiBodytTree::setBodyMass
|
|
int setBodyMass(const int body_index, const idScalar mass);
|
|
///\copydoc MultiBodytTree::setBodyFirstMassMoment
|
|
int setBodyFirstMassMoment(const int body_index, const vec3& first_mass_moment);
|
|
///\copydoc MultiBodytTree::setBodySecondMassMoment
|
|
int setBodySecondMassMoment(const int body_index, const mat33& second_mass_moment);
|
|
///\copydoc MultiBodytTree::getBodyMass
|
|
int getBodyMass(const int body_index, idScalar* mass) const;
|
|
///\copydoc MultiBodytTree::getBodyFirstMassMoment
|
|
int getBodyFirstMassMoment(const int body_index, vec3* first_mass_moment) const;
|
|
///\copydoc MultiBodytTree::getBodySecondMassMoment
|
|
int getBodySecondMassMoment(const int body_index, mat33* second_mass_moment) const;
|
|
/// \copydoc MultiBodyTree::clearAllUserForcesAndMoments
|
|
void clearAllUserForcesAndMoments();
|
|
/// \copydoc MultiBodyTree::addUserForce
|
|
int addUserForce(const int body_index, const vec3& body_force);
|
|
/// \copydoc MultiBodyTree::addUserMoment
|
|
int addUserMoment(const int body_index, const vec3& body_moment);
|
|
|
|
private:
|
|
// debug function. print tree structure to stdout
|
|
void printTree(int index, int indentation);
|
|
// get string representation of JointType (for debugging)
|
|
const char* jointTypeToString(const JointType& type) const;
|
|
// get number of degrees of freedom from joint type
|
|
int bodyNumDoFs(const JointType& type) const;
|
|
// number of bodies in the system
|
|
int m_num_bodies;
|
|
// number of degrees of freedom
|
|
int m_num_dofs;
|
|
// Gravitational acceleration (in world frame)
|
|
vec3 m_world_gravity;
|
|
// vector of bodies in the system
|
|
// body 0 is used as an environment body and is allways fixed.
|
|
// The bodies are ordered such that a parent body always has an index
|
|
// smaller than its child.
|
|
idArray<RigidBody>::type m_body_list;
|
|
// Parent_index[i] is the index for i's parent body in body_list.
|
|
// This fully describes the tree.
|
|
idArray<int>::type m_parent_index;
|
|
// child_indices[i] contains a vector of indices of
|
|
// all children of the i-th body
|
|
idArray<idArray<int>::type>::type m_child_indices;
|
|
// Indices of rotary joints
|
|
idArray<int>::type m_body_revolute_list;
|
|
// Indices of prismatic joints
|
|
idArray<int>::type m_body_prismatic_list;
|
|
// Indices of floating joints
|
|
idArray<int>::type m_body_floating_list;
|
|
// a user-provided integer
|
|
idArray<int>::type m_user_int;
|
|
// a user-provided pointer
|
|
idArray<void*>::type m_user_ptr;
|
|
#if (defined BT_ID_HAVE_MAT3X) && (defined BT_ID_WITH_JACOBIANS)
|
|
mat3x m_m3x;
|
|
#endif
|
|
};
|
|
}
|
|
#endif
|