ContactTrackerSubsystem.h

Go to the documentation of this file.
00001 #ifndef SimTK_SIMBODY_CONTACT_TRACKER_SUBSYSTEM_H_
00002 #define SimTK_SIMBODY_CONTACT_TRACKER_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) 2010 Stanford University and the Authors.           *
00013  * Authors: Michael Sherman, Peter Eastman                                    *
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 "SimTKcommon.h"
00036 #include "simbody/internal/common.h"
00037 #include "simbody/internal/ContactGeometry.h"
00038 #include "simbody/internal/ContactSurface.h"
00039 
00040 namespace SimTK {
00041 
00042 
00043 class MultibodySystem;
00044 class MobilizedBody;
00045 class ContactTracker;
00046 class Contact;
00047 class ContactSnapshot;
00048 
00153 //==============================================================================
00154 //                          CONTACT TRACKER SUBSYSTEM
00155 //==============================================================================
00156 class SimTK_SIMBODY_EXPORT ContactTrackerSubsystem : public Subsystem {
00157 public:
00158 ContactTrackerSubsystem();
00159 explicit ContactTrackerSubsystem(MultibodySystem&);
00160 
00165 int getNumSurfaces() const;
00167 const MobilizedBody& getMobilizedBody(ContactSurfaceIndex surfIx) const;
00170 const ContactSurface& getContactSurface(ContactSurfaceIndex surfIx) const;
00173 const Transform& getContactSurfaceTransform(ContactSurfaceIndex surfIx) const;
00174 
00180 void adoptContactTracker(ContactTracker* tracker);
00181 
00185 bool hasContactTracker(ContactGeometryTypeId surface1, 
00186                        ContactGeometryTypeId surface2) const;
00187 
00193 const ContactTracker& getContactTracker(ContactGeometryTypeId surface1, 
00194                                         ContactGeometryTypeId surface2,
00195                                         bool& reverseOrder) const;
00196 
00199 const ContactSnapshot& getPreviousActiveContacts(const State& state) const;
00200 
00203 const ContactSnapshot& getPreviousPredictedContacts(const State& state) const;
00204 
00216 const ContactSnapshot& getActiveContacts(const State& state) const;
00217 
00226 const ContactSnapshot& getPredictedContacts(const State& state) const;
00227 
00234 bool realizeActiveContacts(const State& state, 
00235                            bool         lastTry,
00236                            Real&        stepAdvice) const;
00237 
00241 bool realizePredictedContacts(const State& state, 
00242                               bool         lastTry,
00243                               Real&        stepAdvice) const;
00244 
00245 SimTK_PIMPL_DOWNCAST(ContactTrackerSubsystem, Subsystem);
00246 
00247 //--------------------------------------------------------------------------
00248 private:
00249 class ContactTrackerSubsystemImpl& updImpl();
00250 const ContactTrackerSubsystemImpl& getImpl() const;
00251 };
00252 
00253 
00254 
00255 //==============================================================================
00256 //                            CONTACT SNAPSHOT
00257 //==============================================================================
00268 class SimTK_SIMBODY_EXPORT ContactSnapshot {
00269 //TODO: replace with fast hash tables
00270 typedef std::map<ContactId,int>     ContactMap;
00271 // Note: we always order the key so that the first surface index is less than
00272 // the second (they can't be equal!).
00273 typedef std::map<std::pair<ContactSurfaceIndex,ContactSurfaceIndex>, 
00274                  ContactId>         SurfaceMap;
00275 public:
00277 ContactSnapshot() : m_time(NaN) {}
00278 
00280 void clear() {
00281     m_time = NaN;
00282     m_contacts.clear();
00283     m_id2contact.clear();
00284     m_surfPair2id.clear();
00285 }
00286 
00288 void setTimestamp(Real time) {m_time=time;}
00290 Real getTimestamp() const {return m_time;}
00291 
00297 void adoptContact(Contact& contact) {
00298     const ContactId id = contact.getContactId();
00299     ContactSurfaceIndex surf1(contact.getSurface1());
00300     ContactSurfaceIndex surf2(contact.getSurface2());
00301     assert(id.isValid() && surf1.isValid() && surf2.isValid());
00302 
00303     // Surface pair must be ordered (low,high) for the map.
00304     if (surf1 > surf2) std::swap(surf1,surf2);
00305 
00306     assert(!hasContact(id));
00307     assert(!hasContact(surf1,surf2));
00308 
00309     const int indx = m_contacts.size();
00310     m_contacts.push_back(contact); // shallow copy
00311     m_id2contact[id] = indx;
00312     m_surfPair2id[std::make_pair(surf1,surf2)] = id;
00313 }
00314 
00316 bool hasContact(ContactId id) const 
00317 {   return m_id2contact.find(id) != m_id2contact.end(); }
00320 bool hasContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2) const
00321 {   if (surf1 > surf2) std::swap(surf1,surf2);
00322     return m_surfPair2id.find(std::make_pair(surf1,surf2)) 
00323         != m_surfPair2id.end(); }
00324 
00326 int getNumContacts() const {return m_contacts.size();}
00331 const Contact& getContact(int n) const {return m_contacts[n];}
00335 const Contact& getContactById(ContactId id) const
00336 {   static Contact empty;
00337     ContactMap::const_iterator p = m_id2contact.find(id);
00338     return p==m_id2contact.end() ? empty : m_contacts[p->second]; }
00342 ContactId getContactIdForSurfacePair(ContactSurfaceIndex surf1,
00343                                      ContactSurfaceIndex surf2) const
00344 {   if (surf1 > surf2) std::swap(surf1,surf2);
00345     SurfaceMap::const_iterator p = 
00346         m_surfPair2id.find(std::make_pair(surf1,surf2));
00347     return p==m_surfPair2id.end() ? ContactId() : p->second; }
00348 
00349 //--------------------------------------------------------------------------
00350                                 private:
00351 
00352 // Remove a Contact occupying a particular slot in the Contact array. This
00353 // will result in another Contact object being moved to occupy the now-empty
00354 // slot to keep the array compact.
00355 void removeContact(int n) {
00356     assert(0 <= n && n < m_contacts.size());
00357     if (n+1 == m_contacts.size()) {
00358         m_contacts.pop_back(); // this was the last one
00359         return;
00360     }
00361     // Move the last one to replace this one and update the map.
00362     m_contacts[n] = m_contacts.back();  // shallow copy
00363     m_contacts.pop_back();              // destruct
00364     m_id2contact[m_contacts[n].getContactId()] = n;
00365 }
00366 
00367 
00368 Real                m_time;         // when this snapshot was taken
00369 Array_<Contact,int> m_contacts;     // all the contact pairs
00370 ContactMap          m_id2contact;   // the contact pairs by contactId
00371 SurfaceMap          m_surfPair2id;  // surfacepair -> contactId map
00372 };
00373 
00374 // for debugging
00375 inline std::ostream& operator<<(std::ostream& o, const ContactSnapshot& cs) {
00376     o << "Contact snapshot: time=" << cs.getTimestamp()
00377         << " numContacts=" << cs.getNumContacts() << std::endl;
00378     return o;
00379 }
00380 
00381 
00382 
00383 //==============================================================================
00384 //                              CONTACT TRACKER
00385 //==============================================================================
00403 class SimTK_SIMBODY_EXPORT ContactTracker {
00404 public:
00405 class HalfSpaceSphere;
00406 class SphereSphere;
00407 class HalfSpaceTriangleMesh;
00408 class SphereTriangleMesh;
00409 class TriangleMeshTriangleMesh;
00410 
00412 ContactTracker(ContactGeometryTypeId typeOfSurface1,
00413                ContactGeometryTypeId typeOfSurface2)
00414 :   m_surfaceTypes(typeOfSurface1, typeOfSurface2)
00415 {
00416 }
00417 
00420 const std::pair<ContactGeometryTypeId,ContactGeometryTypeId>&
00421 getContactGeometryTypeIds() const {return m_surfaceTypes;}
00422 
00423 virtual ~ContactTracker() {}
00424 
00430 virtual bool trackContact
00431    (const Contact&         priorStatus,
00432     const Transform& X_GS1, 
00433     const ContactGeometry& surface1,
00434     const Transform& X_GS2, 
00435     const ContactGeometry& surface2,
00436     Real                   cutoff,
00437     Contact&               currentStatus) const = 0;
00438 
00445 virtual bool predictContact
00446    (const Contact&         priorStatus,
00447     const Transform& X_GS1, const SpatialVec& V_GS1, const SpatialVec& A_GS1,
00448     const ContactGeometry& surface1,
00449     const Transform& X_GS2, const SpatialVec& V_GS2, const SpatialVec& A_GS2,
00450     const ContactGeometry& surface2,
00451     Real                   cutoff,
00452     Real                   intervalOfInterest,
00453     Contact&               predictedStatus) const = 0;
00454 
00460 virtual bool initializeContact
00461    (const Transform& X_GS1, const SpatialVec& V_GS1,
00462     const ContactGeometry& surface1,
00463     const Transform& X_GS2, const SpatialVec& V_GS2,
00464     const ContactGeometry& surface2,
00465     Real                   cutoff,
00466     Real                   intervalOfInterest,
00467     Contact&               contactStatus) const = 0;
00468 
00469 //--------------------------------------------------------------------------
00470                                 private:
00471 // This tracker should be called only for surfaces of these two types,
00472 // in this order.
00473 std::pair<ContactGeometryTypeId,ContactGeometryTypeId> m_surfaceTypes;
00474 };
00475 
00476 
00477 
00478 //==============================================================================
00479 //                     HALFSPACE-SPHERE CONTACT TRACKER
00480 //==============================================================================
00483 class SimTK_SIMBODY_EXPORT ContactTracker::HalfSpaceSphere 
00484 :   public ContactTracker {
00485 public:
00486 HalfSpaceSphere() 
00487 :   ContactTracker(ContactGeometry::HalfSpace::classTypeId(),
00488                    ContactGeometry::Sphere::classTypeId()) {}
00489 
00490 virtual ~HalfSpaceSphere() {}
00491 
00492 virtual bool trackContact
00493    (const Contact&         priorStatus,
00494     const Transform& X_GS1, 
00495     const ContactGeometry& surface1,
00496     const Transform& X_GS2, 
00497     const ContactGeometry& surface2,
00498     Real                   cutoff,
00499     Contact&               currentStatus) const;
00500 
00501 virtual bool predictContact
00502    (const Contact&         priorStatus,
00503     const Transform& X_GS1, const SpatialVec& V_GS1, const SpatialVec& A_GS1,
00504     const ContactGeometry& surface1,
00505     const Transform& X_GS2, const SpatialVec& V_GS2, const SpatialVec& A_GS2,
00506     const ContactGeometry& surface2,
00507     Real                   cutoff,
00508     Real                   intervalOfInterest,
00509     Contact&               predictedStatus) const;
00510 
00511 virtual bool initializeContact
00512    (const Transform& X_GS1, const SpatialVec& V_GS1,
00513     const ContactGeometry& surface1,
00514     const Transform& X_GS2, const SpatialVec& V_GS2,
00515     const ContactGeometry& surface2,
00516     Real                   cutoff,
00517     Real                   intervalOfInterest,
00518     Contact&               contactStatus) const;
00519 };
00520 
00521 
00522 
00523 //==============================================================================
00524 //                       SPHERE-SPHERE CONTACT TRACKER
00525 //==============================================================================
00528 class SimTK_SIMBODY_EXPORT ContactTracker::SphereSphere 
00529 :   public ContactTracker {
00530 public:
00531 SphereSphere() 
00532 :   ContactTracker(ContactGeometry::Sphere::classTypeId(),
00533                    ContactGeometry::Sphere::classTypeId()) {}
00534 
00535 virtual ~SphereSphere() {}
00536 
00537 virtual bool trackContact
00538    (const Contact&         priorStatus,
00539     const Transform& X_GS1, 
00540     const ContactGeometry& surface1,
00541     const Transform& X_GS2, 
00542     const ContactGeometry& surface2,
00543     Real                   cutoff,
00544     Contact&               currentStatus) const;
00545 
00546 virtual bool predictContact
00547    (const Contact&         priorStatus,
00548     const Transform& X_GS1, const SpatialVec& V_GS1, const SpatialVec& A_GS1,
00549     const ContactGeometry& surface1,
00550     const Transform& X_GS2, const SpatialVec& V_GS2, const SpatialVec& A_GS2,
00551     const ContactGeometry& surface2,
00552     Real                   cutoff,
00553     Real                   intervalOfInterest,
00554     Contact&               predictedStatus) const;
00555 
00556 virtual bool initializeContact
00557    (const Transform& X_GS1, const SpatialVec& V_GS1,
00558     const ContactGeometry& surface1,
00559     const Transform& X_GS2, const SpatialVec& V_GS2,
00560     const ContactGeometry& surface2,
00561     Real                   cutoff,
00562     Real                   intervalOfInterest,
00563     Contact&               contactStatus) const;
00564 };
00565 
00566 
00567 
00568 //==============================================================================
00569 //                 HALFSPACE-TRIANGLE MESH CONTACT TRACKER
00570 //==============================================================================
00573 class SimTK_SIMBODY_EXPORT ContactTracker::HalfSpaceTriangleMesh
00574 :   public ContactTracker {
00575 public:
00576 HalfSpaceTriangleMesh() 
00577 :   ContactTracker(ContactGeometry::HalfSpace::classTypeId(),
00578                    ContactGeometry::TriangleMesh::classTypeId()) {}
00579 
00580 virtual ~HalfSpaceTriangleMesh() {}
00581 
00582 virtual bool trackContact
00583    (const Contact&         priorStatus,
00584     const Transform& X_GS1, 
00585     const ContactGeometry& surface1,    // the half space
00586     const Transform& X_GS2, 
00587     const ContactGeometry& surface2,    // the mesh
00588     Real                   cutoff,
00589     Contact&               currentStatus) const;
00590 
00591 virtual bool predictContact
00592    (const Contact&         priorStatus,
00593     const Transform& X_GS1, const SpatialVec& V_GS1, const SpatialVec& A_GS1,
00594     const ContactGeometry& surface1,
00595     const Transform& X_GS2, const SpatialVec& V_GS2, const SpatialVec& A_GS2,
00596     const ContactGeometry& surface2,
00597     Real                   cutoff,
00598     Real                   intervalOfInterest,
00599     Contact&               predictedStatus) const;
00600 
00601 virtual bool initializeContact
00602    (const Transform& X_GS1, const SpatialVec& V_GS1,
00603     const ContactGeometry& surface1,
00604     const Transform& X_GS2, const SpatialVec& V_GS2,
00605     const ContactGeometry& surface2,
00606     Real                   cutoff,
00607     Real                   intervalOfInterest,
00608     Contact&               contactStatus) const;
00609 
00610 private:
00611 void processBox(const ContactGeometry::TriangleMesh&              mesh, 
00612                 const ContactGeometry::TriangleMesh::OBBTreeNode& node, 
00613                 const Transform& X_HM, const UnitVec3& hsNormal_M, 
00614                 Real hsFaceHeight_M, std::set<int>& insideFaces) const;
00615 void addAllTriangles(const ContactGeometry::TriangleMesh::OBBTreeNode& node, 
00616                      std::set<int>& insideFaces) const; 
00617 };
00618 
00619 
00620 
00621 //==============================================================================
00622 //                 SPHERE - TRIANGLE MESH CONTACT TRACKER
00623 //==============================================================================
00626 class SimTK_SIMBODY_EXPORT ContactTracker::SphereTriangleMesh
00627 :   public ContactTracker {
00628 public:
00629 SphereTriangleMesh() 
00630 :   ContactTracker(ContactGeometry::Sphere::classTypeId(),
00631                    ContactGeometry::TriangleMesh::classTypeId()) {}
00632 
00633 virtual ~SphereTriangleMesh() {}
00634 
00635 virtual bool trackContact
00636    (const Contact&         priorStatus,
00637     const Transform& X_GS1, 
00638     const ContactGeometry& surface1,    // the sphere
00639     const Transform& X_GS2, 
00640     const ContactGeometry& surface2,    // the mesh
00641     Real                   cutoff,
00642     Contact&               currentStatus) const;
00643 
00644 virtual bool predictContact
00645    (const Contact&         priorStatus,
00646     const Transform& X_GS1, const SpatialVec& V_GS1, const SpatialVec& A_GS1,
00647     const ContactGeometry& surface1,
00648     const Transform& X_GS2, const SpatialVec& V_GS2, const SpatialVec& A_GS2,
00649     const ContactGeometry& surface2,
00650     Real                   cutoff,
00651     Real                   intervalOfInterest,
00652     Contact&               predictedStatus) const;
00653 
00654 virtual bool initializeContact
00655    (const Transform& X_GS1, const SpatialVec& V_GS1,
00656     const ContactGeometry& surface1,
00657     const Transform& X_GS2, const SpatialVec& V_GS2,
00658     const ContactGeometry& surface2,
00659     Real                   cutoff,
00660     Real                   intervalOfInterest,
00661     Contact&               contactStatus) const;
00662 
00663 private:
00664 void processBox
00665    (const ContactGeometry::TriangleMesh&              mesh, 
00666     const ContactGeometry::TriangleMesh::OBBTreeNode& node, 
00667     const Vec3& center_M, Real radius2,   
00668     std::set<int>& insideFaces) const ;
00669 };
00670 
00671 
00672 
00673 //==============================================================================
00674 //             TRIANGLE MESH - TRIANGLE MESH CONTACT TRACKER
00675 //==============================================================================
00678 class SimTK_SIMBODY_EXPORT ContactTracker::TriangleMeshTriangleMesh
00679 :   public ContactTracker {
00680 public:
00681 TriangleMeshTriangleMesh() 
00682 :   ContactTracker(ContactGeometry::TriangleMesh::classTypeId(),
00683                    ContactGeometry::TriangleMesh::classTypeId()) {}
00684 
00685 virtual ~TriangleMeshTriangleMesh() {}
00686 
00687 virtual bool trackContact
00688    (const Contact&         priorStatus,
00689     const Transform& X_GS1, 
00690     const ContactGeometry& surface1,    // mesh1
00691     const Transform& X_GS2, 
00692     const ContactGeometry& surface2,    // mesh2
00693     Real                   cutoff,
00694     Contact&               currentStatus) const;
00695 
00696 virtual bool predictContact
00697    (const Contact&         priorStatus,
00698     const Transform& X_GS1, const SpatialVec& V_GS1, const SpatialVec& A_GS1,
00699     const ContactGeometry& surface1,
00700     const Transform& X_GS2, const SpatialVec& V_GS2, const SpatialVec& A_GS2,
00701     const ContactGeometry& surface2,
00702     Real                   cutoff,
00703     Real                   intervalOfInterest,
00704     Contact&               predictedStatus) const;
00705 
00706 virtual bool initializeContact
00707    (const Transform& X_GS1, const SpatialVec& V_GS1,
00708     const ContactGeometry& surface1,
00709     const Transform& X_GS2, const SpatialVec& V_GS2,
00710     const ContactGeometry& surface2,
00711     Real                   cutoff,
00712     Real                   intervalOfInterest,
00713     Contact&               contactStatus) const;
00714 
00715 private:
00716 void findIntersectingFaces
00717    (const ContactGeometry::TriangleMesh&                mesh1, 
00718     const ContactGeometry::TriangleMesh&                mesh2,
00719     const ContactGeometry::TriangleMesh::OBBTreeNode&   node1, 
00720     const ContactGeometry::TriangleMesh::OBBTreeNode&   node2, 
00721     const OrientedBoundingBox&                          node2Bounds_M1,
00722     const Transform&                                    X_M1M2, 
00723     std::set<int>&                                      insideFaces1, 
00724     std::set<int>&                                      insideFaces2) const; 
00725 void findBuriedFaces
00726    (const ContactGeometry::TriangleMesh&    mesh,
00727     const ContactGeometry::TriangleMesh&    otherMesh,
00728     const Transform&                        X_OM, 
00729     std::set<int>&                          insideFaces) const;
00730 void tagFaces(const ContactGeometry::TriangleMesh&   mesh, 
00731               Array_<int>&                           faceType,
00732               std::set<int>&                         triangles, 
00733               int                                    index,
00734               int                                    depth) const;
00735 };
00736 
00737 } // namespace SimTK
00738 
00739 #endif // SimTK_SIMBODY_CONTACT_TRACKER_SUBSYSTEM_H_

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