CompliantContactSubsystem.h

Go to the documentation of this file.
00001 #ifndef SimTK_SIMBODY_COMPLIANT_CONTACT_SUBSYSTEM_H_
00002 #define SimTK_SIMBODY_COMPLIANT_CONTACT_SUBSYSTEM_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                      SimTK Core: SimTK Simbody(tm)                         *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK Core biosimulation toolkit originating from      *
00008  * Simbios, the NIH National Center for Physics-Based Simulation of           *
00009  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
00010  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
00011  *                                                                            *
00012  * Portions copyright (c) 2008-10 Stanford University and the Authors.        *
00013  * Authors: Peter Eastman, Michael Sherman                                    *
00014  * Contributors:                                                              *
00015  *                                                                            *
00016  * Permission is hereby granted, free of charge, to any person obtaining a    *
00017  * copy of this software and associated documentation files (the "Software"), *
00018  * to deal in the Software without restriction, including without limitation  *
00019  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
00020  * and/or sell copies of the Software, and to permit persons to whom the      *
00021  * Software is furnished to do so, subject to the following conditions:       *
00022  *                                                                            *
00023  * The above copyright notice and this permission notice shall be included in *
00024  * all copies or substantial portions of the Software.                        *
00025  *                                                                            *
00026  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
00027  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
00028  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
00029  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
00030  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
00031  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
00032  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
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 //                        COMPLIANT CONTACT SUBSYSTEM
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    // don't show in Doxygen docs
00188 SimTK_PIMPL_DOWNCAST(CompliantContactSubsystem, ForceSubsystem);
00191 //--------------------------------------------------------------------------
00192                                  private:
00193 class CompliantContactSubsystemImpl& updImpl();
00194 const CompliantContactSubsystemImpl& getImpl() const;
00195 };
00196 
00197 
00198 
00199 //==============================================================================
00200 //                               CONTACT FORCE
00201 //==============================================================================
00250 class ContactForce {
00251 public:
00253 ContactForce() {} // invalid
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;        // shift & reexpress in B
00292     m_forceOnSurface2   = ~X_AB.R()*m_forceOnSurface2;      // reexpress in B
00293 }
00294 
00295 ContactId       m_contactId;            // Which Contact produced this force?
00296 Vec3            m_contactPt;            // In some frame F
00297 SpatialVec      m_forceOnSurface2;      // at contact pt, in F; neg. for Surf1
00298 Real            m_potentialEnergy;      // > 0 when due to compression
00299 Real            m_powerLoss;            // > 0 means dissipation
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 //                              CONTACT DETAIL
00312 //==============================================================================
00405 class ContactDetail {
00406 public:
00407 int             m_whichSurface;         // 0=patch, 1=surface1, 2=surface2
00408 int             m_elementId;            // meaning defined by patch type
00409 Transform       m_patchFrame;           // X_GP
00410 Vec2            m_patchHalfDimensions;  // x >= y >= 0
00411 Vec3            m_deformation;          // vec to undeformed loc of material
00412 Vec3            m_deformationRate;      // d/dt deformation, w.r.t. body frame
00413 SpatialVec      m_slipVelocity;         // material slip rate
00414 SpatialVec      m_forceOnSurface2InP;   // applied at OP, -force to surf1
00415 Real            m_patchArea;            // >= 0
00416 Real            m_peakPressure;         // > 0 in compression
00417 Real            m_potentialEnergy;      // > 0 when due to compression
00418 Real            m_powerLoss;            // > 0 means dissipation
00419 };
00420 
00421 
00422 
00423 //==============================================================================
00424 //                               CONTACT PATCH
00425 //==============================================================================
00446 class SimTK_SIMBODY_EXPORT ContactPatch {
00447 public:
00448 ContactForce            m_resultant;
00449 Array_<ContactDetail>   m_elements;
00450 };
00451 
00452 
00453 
00454 //==============================================================================
00455 //                          CONTACT FORCE GENERATOR
00456 //==============================================================================
00465 class SimTK_SIMBODY_EXPORT ContactForceGenerator {
00466 public:
00467 class ElasticFoundation;        // for TriangleMeshContact
00468 class HertzCircular;            // for PointContact
00469 class HertzElliptical;          // for EllipticalPointContact
00470 
00471 // These are for response to unknown ContactTypeIds.
00472 class DoNothing;     // do nothing if called
00473 class ThrowError;    // throw an error if called
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,  // relative surface velocity (S2 in S1)
00505     ContactForce&           contactForce) const = 0;
00506 
00513 virtual void calcContactPatch
00514    (const State&            state,
00515     const Contact&          overlapping,
00516     const SpatialVec&       V_S1S2,  // relative surface velocity (S2 in S1)
00517     ContactPatch&           patch) const = 0;
00518 
00519 
00520 //--------------------------------------------------------------------------
00521 private:
00522     // This generator should be called only for Contact objects of the 
00523     // indicated type id.
00524     ContactTypeId                       m_contactType;
00525     // This is a reference to the owning CompliantContactSubsystem if any;
00526     // don't delete on destruction.
00527     const CompliantContactSubsystem*    m_compliantContactSubsys;
00528 };
00529 
00530 
00531 
00532 
00533 //==============================================================================
00534 //                         HERTZ CIRCULAR GENERATOR
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 //                       ELASTIC FOUNDATION GENERATOR
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, // 0..1
00602     Real k, Real c, Real us, Real ud, Real uv,
00603     const Vec3&                 resultantPt_M, // where to apply forces
00604     SpatialVec&                 resultantForceOnOther_M, // at resultant pt
00605     Real&                       potentialEnergy,
00606     Real&                       powerLoss,
00607     Vec3&                       weightedCenterOfPressure_M, // COP
00608     Real&                       sumOfAllPressureMoments,    // COP weight
00609     Array_<ContactDetail>*      contactDetails) const;
00610 };
00611 
00612 
00613 
00614 
00615 //==============================================================================
00616 //                        DO NOTHING FORCE GENERATOR
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 //                       THROW ERROR FORCE GENERATOR
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 } // namespace SimTK
00675 
00676 #endif // SimTK_SIMBODY_COMPLIANT_CONTACT_SUBSYSTEM_H_

Generated on Thu Aug 12 16:37:05 2010 for SimTKcore by  doxygen 1.6.1