00001
00002
00003
00004
00005
00006
00007 #ifndef _RIGID_BODY_H
00008 #define _RIGID_BODY_H
00009
00010 #include <list>
00011 #include <boost/shared_ptr.hpp>
00012 #include <boost/weak_ptr.hpp>
00013 #include <boost/enable_shared_from_this.hpp>
00014 #include <Physsim/Constants.h>
00015 #include <Physsim/CollisionGeometry.h>
00016 #include <Physsim/DynamicBody.h>
00017 #include <Physsim/Vector3.h>
00018 #include <Physsim/Matrix3.h>
00019 #include <Physsim/Matrix4.h>
00020 #include <Physsim/Quat.h>
00021 #include <Physsim/Vector3.h>
00022 #include <Physsim/SVector6.h>
00023
00024 namespace Physsim {
00025
00026 class ArticulatedBody;
00027 class CollisionGeometry;
00028
00030
00038 class RigidBody : public DynamicBody
00039 {
00040 public:
00041 RigidBody();
00042 virtual ~RigidBody() {}
00043 virtual void load_state(BaseConstPtr clone, bimap<BasePtr, BasePtr>* correspondence = NULL);
00044 virtual bool is_struct_identical(BaseConstPtr object) const;
00045 virtual void save_state(BasePtr object, bimap<BasePtr, BasePtr>* correspondence = NULL) const;
00046 virtual void clone(BasePtr& cloned, bimap<BasePtr, BasePtr>* obj_map = NULL) const;
00047 void set_avel(const Vector3& avel, bool update_angular_momentum = false);
00048 void set_qvel(const Quat& qd, bool update_angular_momentum = false);
00049 void set_lvel(const Vector3& lvel, bool update_linear_momentum = false);
00050 virtual VectorN get_state_deriv();
00051 virtual void set_state(const VectorN& state);
00052 virtual VectorN get_state();
00053 void add_force(const Vector3& force);
00054 void add_torque(const Vector3& torque);
00055 void set_transform(const Matrix4& transform);
00056 void set_transform(const Quat& q, const Vector3& x);
00057 void set_inertia(const Matrix3& m);
00058 void set_enabled(bool flag);
00059 void set_orientation(const Quat& q);
00060 void set_position(const Vector3& pos);
00061 void remove_collision_geometry(CollisionGeometryPtr g);
00062 void add_force(const Vector3& f, const Vector3& p);
00063 void apply_impulse(const Vector3& j, const Vector3& p);
00064 void apply_impulse(const Vector3& j, const Vector3& k, const Vector3& p);
00065 void set_mass(Real mass);
00066 Matrix3 det_collision_matrix(const Matrix3& contact_frame_transpose, const Vector3& contact_point);
00067 virtual void transform(const Matrix4& transform) { set_transform(transform * _F); }
00068 virtual void calc_fwd_dyn();
00069 std::list<CollisionGeometryPtr> get_all_collision_geometries() const;
00070 void set_linear_momentum(const Vector3& P, bool update_velocity = false);
00071 void set_angular_momentum(const Vector3& L, bool update_velocity = false);
00072 virtual void set_visualization_data(SoNode* vdata) { Visualizable::set_visualization_data(vdata); synchronize(); }
00073 virtual void load_from_xml(XMLTreeConstPtr node, std::map<std::string, BasePtr>& id_map);
00074 virtual void save_to_xml(XMLTreePtr node, std::list<BaseConstPtr>& shared_objects) const;
00075 Real calc_point_accel(const Vector3& point, const Vector3& dir);
00076 static Real calc_sep_accel(RigidBody& rb1, RigidBody& rb2, const Vector3& point, const Vector3& dir, const Vector3& dir_dot);
00077 Real calc_point_vel(const Vector3& point, const Vector3& dir) const;
00078 virtual void output_object_state(std::ostream& out) const;
00079 bool remove_child_link(RigidBodyConstPtr link);
00080 Vector3 get_inner_joint_to_com_vector_global() const;
00081 void set_inner_joint_to_com_vector_link(const Vector3& v);
00082 void set_inner_joint_to_com_vector_global(const Vector3& v);
00083 const Vector3& get_com_to_outer_joint_vector_link(RigidBodyConstPtr child) const;
00084 Vector3 get_com_to_outer_joint_vector_global(RigidBodyConstPtr child) const;
00085 void add_child_link_global(RigidBodyPtr child, const Vector3& v);
00086 bool is_child_link(RigidBodyConstPtr query) const;
00087 void reset_spatial_transforms();
00088 const SMatrix6& get_spatial_transform_forward();
00089 const SMatrix6& get_spatial_transform_backward();
00090 const SMatrix6& get_spatial_transform_link_to_global();
00091 const SMatrix6& get_spatial_transform_global_to_link();
00092 SVector6 get_spatial_accel(ReferenceFrameType rftype);
00093 void set_spatial_accel(const SVector6& a, ReferenceFrameType rftype);
00094 SVector6 get_spatial_velocity(ReferenceFrameType rftype);
00095 void set_spatial_velocity(const SVector6& v, ReferenceFrameType rftype);
00096 std::list<RigidBodyPtr> get_child_links() const;
00097 void add_child_link_link(RigidBodyPtr l, const Vector3& com_to_child_inner_joint_vec_link);
00098 void set_inner_joint(JointPtr j);
00099 void set_parent_link(RigidBodyPtr l);
00100
00102 RigidBodyPtr get_this() { return boost::dynamic_pointer_cast<RigidBody>(shared_from_this()); }
00103
00105 RigidBodyConstPtr get_this() const { return boost::dynamic_pointer_cast<const RigidBody>(shared_from_this()); }
00106
00108 const Matrix4& get_transform() const { return _F; }
00109
00111 Real get_mass() const { return _mass; }
00112
00114 Real get_mass_inv() const { return _mass_inv; }
00115
00117 const Matrix3& get_inertia() const { return _I; }
00118
00120 const Matrix3& get_inertia_inv() const { return _Iinv; }
00121
00123 const Vector3& get_position() const { return _x; }
00124
00126 const Quat& get_orientation() const { return _q; }
00127
00129 const Vector3& get_lvel() const { return _xd; }
00130
00132 const Vector3& get_avel() const { return _omega; }
00133
00135 const Quat& get_qvel() const { return _qd; }
00136
00138
00142 const Vector3& get_laccel() { return _a; }
00143
00145
00149 const Vector3& get_aaccel() { return _alpha; }
00150
00152 void set_aaccel(const Vector3& a) { _alpha = a; }
00153
00155 void set_laccel(const Vector3& a) { _a = a; }
00156
00158 const SMatrix6& get_spatial_iso_inertia_link() { return _Ii_iso; }
00159
00161 void reset_accumulators() { _forces = ZEROS_3; _torques = ZEROS_3; }
00162
00164
00168 const Vector3& sum_forces() const { return _forces; }
00169
00171
00175 const Vector3& sum_torques() const { return _torques; }
00176
00178 bool is_enabled() const { return _enabled; }
00179
00181 unsigned num_collision_geometries() const { return _geometries.size(); }
00182
00184 void add_collision_geometry(CollisionGeometryPtr g) { g->set_rigid_body(get_this()); _geometries.push_back(g); synchronize(); }
00185
00187 void remove_collision_geometry(unsigned i) { _geometries[i] = _geometries.back(); _geometries.pop_back(); }
00188
00190 void clear_collision_geometries() { _geometries.clear(); }
00191
00193 CollisionGeometryPtr get_collision_geometry(unsigned i) { return _geometries[i]; }
00194
00196 const std::vector<CollisionGeometryPtr>& get_collision_geometries() const { return _geometries; }
00197
00199 const Vector3& get_linear_momentum() const { return _P; }
00200
00202 void update_linear_momentum() { _P = _mass * _xd; }
00203
00205 const Vector3& get_angular_momentum() const { return _L; }
00206
00208 void update_angular_momentum() { _L = _I * _omega; }
00209
00211
00215 boost::weak_ptr<ArticulatedBody> get_articulated_body() const { return _abody; }
00216
00218
00222 void set_articulated_body(boost::weak_ptr<ArticulatedBody> body) { _abody = body; }
00223
00225 const std::map<RigidBodyPtr, Vector3>& get_child_link_map() const { return _child_links; }
00226
00228 bool is_base() const { assert(!_abody.expired()); return _parent_link.expired(); }
00229
00231
00236 const Vector3& get_inner_joint_to_com_vector_link() const { return _d; }
00237
00239 boost::weak_ptr<Joint> get_inner_joint() const { return _inner_joint; }
00240
00242 boost::weak_ptr<RigidBody> get_parent_link() const { return _parent_link; }
00243
00245 unsigned num_child_links() const { return _child_links.size(); }
00246
00248 bool is_end_effector() const { assert (!_abody.expired()); return _child_links.empty(); }
00249
00251
00260 void set_child_link_link(RigidBodyPtr child, const Vector3& com_to_inner_joint_vec_link) { add_child_link_link(child, com_to_inner_joint_vec_link); }
00261
00263
00273 void set_child_link_global(RigidBodyPtr child, const Vector3& com_to_inner_joint_vec_global) { add_child_link_global(child, com_to_inner_joint_vec_global); }
00274
00276 void clear_child_links() { _child_links.clear(); }
00277
00279 unsigned get_index() { return _link_idx; }
00280
00282
00286 void set_index(unsigned index) { _link_idx = index; }
00287
00288 private:
00289
00291 Real _mass;
00292
00294 Real _mass_inv;
00295
00297 Matrix3 _I;
00298
00300 Matrix3 _Iinv;
00301
00303 Vector3 _P;
00304
00306 Vector3 _L;
00307
00309 Vector3 _omega;
00310
00312 Vector3 _x;
00313
00315 Vector3 _xd;
00316
00318 Quat _q;
00319
00321 Quat _qd;
00322
00324 Matrix4 _F;
00325
00327 Vector3 _forces;
00328
00330 Vector3 _torques;
00331
00333 static const unsigned STATE_DIM = 13;
00334
00335 void synchronize();
00336
00338 unsigned _link_idx;
00339
00341 SMatrix6 _Ii_iso;
00342
00344 SMatrixNPtr _Is0;
00345
00347 SMatrixNPtr _Isi;
00348
00350 SMatrix6Ptr _X_im1_i;
00351
00353 SMatrix6Ptr _X_i_im1;
00354
00356 SMatrix6Ptr _X_0_i;
00357
00359 SMatrix6Ptr _X_i_0;
00360
00362 Vector3 _a;
00363
00365 Vector3 _alpha;
00366
00368 std::vector<CollisionGeometryPtr> _geometries;
00369
00371 bool _enabled;
00372
00374 boost::weak_ptr<ArticulatedBody> _abody;
00375
00377 Vector3 _d;
00378
00380 boost::weak_ptr<RigidBody> _parent_link;
00381
00383 boost::weak_ptr<Joint> _inner_joint;
00384
00386 std::map<RigidBodyPtr, Vector3> _child_links;
00387 };
00388
00389 }
00390
00391 #endif
00392