00001 #ifndef SimTK_SIMBODY_COMPLIANT_CONTACT_SUBSYSTEM_H_
00002 #define SimTK_SIMBODY_COMPLIANT_CONTACT_SUBSYSTEM_H_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "simbody/internal/common.h"
00036 #include "simbody/internal/ForceSubsystem.h"
00037 #include "simbody/internal/Contact.h"
00038 #include "simbody/internal/ContactGeometry.h"
00039
00040 #include <cassert>
00041
00042 namespace SimTK {
00043
00044 class MultibodySystem;
00045 class SimbodyMatterSubsystem;
00046 class ContactTrackerSubsystem;
00047 class ContactForceGenerator;
00048 class Contact;
00049 class ContactForce;
00050 class ContactPatch;
00051
00052
00053
00054
00055
00056
00062 class SimTK_SIMBODY_EXPORT CompliantContactSubsystem : public ForceSubsystem {
00063 public:
00065 CompliantContactSubsystem() {}
00066
00072 CompliantContactSubsystem(MultibodySystem&,
00073 const ContactTrackerSubsystem&);
00074
00076 Real getTransitionVelocity() const;
00078 void setTransitionVelocity(Real vt);
00080 Real getOOTransitionVelocity() const;
00081
00086 int getNumContactForces(const State& state) const;
00091 const ContactForce& getContactForce(const State& state, int n) const;
00092
00115 Real getDissipatedEnergy(const State& state) const;
00116
00129 void setDissipatedEnergy(State& state, Real energy) const;
00130
00141 void calcContactPatchDetails(const State& state,
00142 Array_<ContactPatch>& patches) const;
00143
00148 void adoptForceGenerator(ContactForceGenerator* generator);
00149
00154 void adoptDefaultForceGenerator(ContactForceGenerator* generator);
00155
00158 bool hasForceGenerator(ContactTypeId contact) const;
00159
00163 bool hasDefaultForceGenerator() const;
00164
00168 const ContactForceGenerator&
00169 getContactForceGenerator(ContactTypeId contact) const;
00170
00173 const ContactForceGenerator& getDefaultForceGenerator() const;
00174
00179 const ContactTrackerSubsystem& getContactTrackerSubsystem() const;
00180
00185 const MultibodySystem& getMultibodySystem() const;
00186
00188 SimTK_PIMPL_DOWNCAST(CompliantContactSubsystem, ForceSubsystem);
00191
00192 private:
00193 class CompliantContactSubsystemImpl& updImpl();
00194 const CompliantContactSubsystemImpl& getImpl() const;
00195 };
00196
00197
00198
00199
00200
00201
00250 class ContactForce {
00251 public:
00253 ContactForce() {}
00254
00259 ContactForce(ContactId id, const Vec3& contactPt,
00260 const SpatialVec& forceOnSurface2,
00261 Real potentialEnergy, Real powerLoss)
00262 : m_contactId(id), m_contactPt(contactPt),
00263 m_forceOnSurface2(forceOnSurface2),
00264 m_potentialEnergy(potentialEnergy), m_powerLoss(powerLoss) {}
00265
00271 void setTo(ContactId id, const Vec3& contactPt,
00272 const SpatialVec& forceOnSurface2,
00273 Real potentialEnergy, Real powerLoss)
00274 { m_contactId = id;
00275 m_contactPt = contactPt;
00276 m_forceOnSurface2 = forceOnSurface2;
00277 m_potentialEnergy = potentialEnergy;
00278 m_powerLoss = powerLoss; }
00279
00282 void clear() {m_contactId.invalidate();}
00284 bool isValid() const {return m_contactId.isValid();}
00285
00290 void changeFrameInPlace(const Transform& X_AB) {
00291 m_contactPt = ~X_AB*m_contactPt;
00292 m_forceOnSurface2 = ~X_AB.R()*m_forceOnSurface2;
00293 }
00294
00295 ContactId m_contactId;
00296 Vec3 m_contactPt;
00297 SpatialVec m_forceOnSurface2;
00298 Real m_potentialEnergy;
00299 Real m_powerLoss;
00300 };
00301
00302 inline std::ostream& operator<<(std::ostream& o, const ContactForce& f) {
00303 o << "ContactForce for ContactId " << f.m_contactId << " (ground frame):\n";
00304 o << " contact point=" << f.m_contactPt << "\n";
00305 o << " force on surf2 =" << f.m_forceOnSurface2 << "\n";
00306 o << " pot. energy=" << f.m_potentialEnergy << " powerLoss=" << f.m_powerLoss;
00307 return o << "\n";
00308 }
00309
00310
00311
00312
00405 class ContactDetail {
00406 public:
00407 int m_whichSurface;
00408 int m_elementId;
00409 Transform m_patchFrame;
00410 Vec2 m_patchHalfDimensions;
00411 Vec3 m_deformation;
00412 Vec3 m_deformationRate;
00413 SpatialVec m_slipVelocity;
00414 SpatialVec m_forceOnSurface2InP;
00415 Real m_patchArea;
00416 Real m_peakPressure;
00417 Real m_potentialEnergy;
00418 Real m_powerLoss;
00419 };
00420
00421
00422
00423
00424
00425
00446 class SimTK_SIMBODY_EXPORT ContactPatch {
00447 public:
00448 ContactForce m_resultant;
00449 Array_<ContactDetail> m_elements;
00450 };
00451
00452
00453
00454
00455
00456
00465 class SimTK_SIMBODY_EXPORT ContactForceGenerator {
00466 public:
00467 class ElasticFoundation;
00468 class HertzCircular;
00469 class HertzElliptical;
00470
00471
00472 class DoNothing;
00473 class ThrowError;
00474
00476 explicit ContactForceGenerator(ContactTypeId type): m_contactType(type) {}
00477
00481 ContactTypeId getContactTypeId() const {return m_contactType;}
00482
00483 const CompliantContactSubsystem& getCompliantContactSubsystem() const
00484 { assert(m_compliantContactSubsys); return *m_compliantContactSubsys; }
00485 void setCompliantContactSubsystem(const CompliantContactSubsystem* sub)
00486 { m_compliantContactSubsys = sub; }
00487
00489 virtual ~ContactForceGenerator() {}
00490
00501 virtual void calcContactForce
00502 (const State& state,
00503 const Contact& overlapping,
00504 const SpatialVec& V_S1S2,
00505 ContactForce& contactForce) const = 0;
00506
00513 virtual void calcContactPatch
00514 (const State& state,
00515 const Contact& overlapping,
00516 const SpatialVec& V_S1S2,
00517 ContactPatch& patch) const = 0;
00518
00519
00520
00521 private:
00522
00523
00524 ContactTypeId m_contactType;
00525
00526
00527 const CompliantContactSubsystem* m_compliantContactSubsys;
00528 };
00529
00530
00531
00532
00533
00534
00535
00536
00540 class SimTK_SIMBODY_EXPORT ContactForceGenerator::HertzCircular
00541 : public ContactForceGenerator {
00542 public:
00543 HertzCircular()
00544 : ContactForceGenerator(CircularPointContact::classTypeId()) {}
00545
00546 virtual ~HertzCircular() {}
00547 virtual void calcContactForce
00548 (const State& state,
00549 const Contact& overlapping,
00550 const SpatialVec& V_S1S2,
00551 ContactForce& contactForce) const;
00552
00553 virtual void calcContactPatch
00554 (const State& state,
00555 const Contact& overlapping,
00556 const SpatialVec& V_S1S2,
00557 ContactPatch& patch) const;
00558 };
00559
00560
00561
00562
00563
00564
00565
00569 class SimTK_SIMBODY_EXPORT ContactForceGenerator::ElasticFoundation
00570 : public ContactForceGenerator {
00571 public:
00572 ElasticFoundation()
00573 : ContactForceGenerator(TriangleMeshContact::classTypeId()) {}
00574 virtual ~ElasticFoundation() {}
00575 virtual void calcContactForce
00576 (const State& state,
00577 const Contact& overlapping,
00578 const SpatialVec& V_S1S2,
00579 ContactForce& contactForce) const;
00580
00581 virtual void calcContactPatch
00582 (const State& state,
00583 const Contact& overlapping,
00584 const SpatialVec& V_S1S2,
00585 ContactPatch& patch) const;
00586
00587 private:
00588 void calcWeightedPatchCentroid
00589 (const ContactGeometry::TriangleMesh& mesh,
00590 const std::set<int>& insideFaces,
00591 Vec3& weightedPatchCentroid,
00592 Real& patchArea) const;
00593
00594 void processOneMesh
00595 (const State& state,
00596 const ContactGeometry::TriangleMesh& mesh,
00597 const std::set<int>& insideFaces,
00598 const Transform& X_MO,
00599 const SpatialVec& V_MO,
00600 const ContactGeometry& other,
00601 Real meshDeformationFraction,
00602 Real k, Real c, Real us, Real ud, Real uv,
00603 const Vec3& resultantPt_M,
00604 SpatialVec& resultantForceOnOther_M,
00605 Real& potentialEnergy,
00606 Real& powerLoss,
00607 Vec3& weightedCenterOfPressure_M,
00608 Real& sumOfAllPressureMoments,
00609 Array_<ContactDetail>* contactDetails) const;
00610 };
00611
00612
00613
00614
00615
00616
00617
00621 class SimTK_SIMBODY_EXPORT ContactForceGenerator::DoNothing
00622 : public ContactForceGenerator {
00623 public:
00624 explicit DoNothing(ContactTypeId type = ContactTypeId(0))
00625 : ContactForceGenerator(type) {}
00626 virtual ~DoNothing() {}
00627 virtual void calcContactForce
00628 (const State& state,
00629 const Contact& overlapping,
00630 const SpatialVec& V_S1S2,
00631 ContactForce& contactForce) const
00632 { SimTK_ASSERT_ALWAYS(!"implemented",
00633 "ContactForceGenerator::DoNothing::calcContactForce() not implemented yet."); }
00634 virtual void calcContactPatch
00635 (const State& state,
00636 const Contact& overlapping,
00637 const SpatialVec& V_S1S2,
00638 ContactPatch& patch) const
00639 { SimTK_ASSERT_ALWAYS(!"implemented",
00640 "ContactForceGenerator::DoNothing::calcContactPatch() not implemented yet."); }
00641 };
00642
00643
00644
00645
00646
00647
00652 class SimTK_SIMBODY_EXPORT ContactForceGenerator::ThrowError
00653 : public ContactForceGenerator {
00654 public:
00655 explicit ThrowError(ContactTypeId type = ContactTypeId(0))
00656 : ContactForceGenerator(type) {}
00657 virtual ~ThrowError() {}
00658 virtual void calcContactForce
00659 (const State& state,
00660 const Contact& overlapping,
00661 const SpatialVec& V_S1S2,
00662 ContactForce& contactForce) const
00663 { SimTK_ASSERT_ALWAYS(!"implemented",
00664 "ContactForceGenerator::ThrowError::calcContactForce() not implemented yet."); }
00665 virtual void calcContactPatch
00666 (const State& state,
00667 const Contact& overlapping,
00668 const SpatialVec& V_S1S2,
00669 ContactPatch& patch) const
00670 { SimTK_ASSERT_ALWAYS(!"implemented",
00671 "ContactForceGenerator::ThrowError::calcContactPatch() not implemented yet."); }
00672 };
00673
00674 }
00675
00676 #endif // SimTK_SIMBODY_COMPLIANT_CONTACT_SUBSYSTEM_H_