Simbody  3.4 (development)
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  *                               Simbody(tm)                                  *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK 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/home/simbody.  *
00011  *                                                                            *
00012  * Portions copyright (c) 2011-12 Stanford University and the Authors.        *
00013  * Authors: Michael Sherman, Peter Eastman                                    *
00014  * Contributors:                                                              *
00015  *                                                                            *
00016  * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
00017  * not use this file except in compliance with the License. You may obtain a  *
00018  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
00019  *                                                                            *
00020  * Unless required by applicable law or agreed to in writing, software        *
00021  * distributed under the License is distributed on an "AS IS" BASIS,          *
00022  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
00023  * See the License for the specific language governing permissions and        *
00024  * limitations under the License.                                             *
00025  * -------------------------------------------------------------------------- */
00026 
00027 #include "SimTKmath.h"
00028 #include "simbody/internal/common.h"
00029 #include "simbody/internal/ContactSurface.h"
00030 
00031 namespace SimTK {
00032 
00033 
00034 class MultibodySystem;
00035 class MobilizedBody;
00036 class ContactTracker;
00037 class Contact;
00038 class ContactSnapshot;
00039 
00144 //==============================================================================
00145 //                          CONTACT TRACKER SUBSYSTEM
00146 //==============================================================================
00147 class SimTK_SIMBODY_EXPORT ContactTrackerSubsystem : public Subsystem {
00148 public:
00149 ContactTrackerSubsystem();
00150 explicit ContactTrackerSubsystem(MultibodySystem&);
00151 
00156 int getNumSurfaces() const;
00158 const MobilizedBody& getMobilizedBody(ContactSurfaceIndex surfIx) const;
00161 const ContactSurface& getContactSurface(ContactSurfaceIndex surfIx) const;
00164 const Transform& getContactSurfaceTransform(ContactSurfaceIndex surfIx) const;
00165 
00171 void adoptContactTracker(ContactTracker* tracker);
00172 
00176 bool hasContactTracker(ContactGeometryTypeId surface1, 
00177                        ContactGeometryTypeId surface2) const;
00178 
00184 const ContactTracker& getContactTracker(ContactGeometryTypeId surface1, 
00185                                         ContactGeometryTypeId surface2,
00186                                         bool& reverseOrder) const;
00187 
00190 const ContactSnapshot& getPreviousActiveContacts(const State& state) const;
00191 
00194 const ContactSnapshot& getPreviousPredictedContacts(const State& state) const;
00195 
00207 const ContactSnapshot& getActiveContacts(const State& state) const;
00208 
00217 const ContactSnapshot& getPredictedContacts(const State& state) const;
00218 
00225 bool realizeActiveContacts(const State& state, 
00226                            bool         lastTry,
00227                            Real&        stepAdvice) const;
00228 
00232 bool realizePredictedContacts(const State& state, 
00233                               bool         lastTry,
00234                               Real&        stepAdvice) const;
00235 
00236 SimTK_PIMPL_DOWNCAST(ContactTrackerSubsystem, Subsystem);
00237 
00238 //--------------------------------------------------------------------------
00239 private:
00240 class ContactTrackerSubsystemImpl& updImpl();
00241 const ContactTrackerSubsystemImpl& getImpl() const;
00242 };
00243 
00244 
00245 
00246 //==============================================================================
00247 //                            CONTACT SNAPSHOT
00248 //==============================================================================
00259 class SimTK_SIMBODY_EXPORT ContactSnapshot {
00260 //TODO: replace with fast hash tables
00261 typedef std::map<ContactId,int>     ContactMap;
00262 // Note: we always order the key so that the first surface index is less than
00263 // the second (they can't be equal!).
00264 typedef std::map<std::pair<ContactSurfaceIndex,ContactSurfaceIndex>, 
00265                  ContactId>         SurfaceMap;
00266 public:
00268 ContactSnapshot() : m_time(NaN) {}
00269 
00271 void clear() {
00272     m_time = NaN;
00273     m_contacts.clear();
00274     m_id2contact.clear();
00275     m_surfPair2id.clear();
00276 }
00277 
00279 void setTimestamp(Real time) {m_time=time;}
00281 Real getTimestamp() const {return m_time;}
00282 
00288 void adoptContact(Contact& contact) {
00289     const ContactId id = contact.getContactId();
00290     ContactSurfaceIndex surf1(contact.getSurface1());
00291     ContactSurfaceIndex surf2(contact.getSurface2());
00292     assert(id.isValid() && surf1.isValid() && surf2.isValid());
00293 
00294     // Surface pair must be ordered (low,high) for the map.
00295     if (surf1 > surf2) std::swap(surf1,surf2);
00296 
00297     assert(!hasContact(id));
00298     assert(!hasContact(surf1,surf2));
00299 
00300     const int indx = m_contacts.size();
00301     m_contacts.push_back(contact); // shallow copy
00302     m_id2contact[id] = indx;
00303     m_surfPair2id[std::make_pair(surf1,surf2)] = id;
00304 }
00305 
00307 bool hasContact(ContactId id) const 
00308 {   return m_id2contact.find(id) != m_id2contact.end(); }
00311 bool hasContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2) const
00312 {   if (surf1 > surf2) std::swap(surf1,surf2);
00313     return m_surfPair2id.find(std::make_pair(surf1,surf2)) 
00314         != m_surfPair2id.end(); }
00315 
00317 int getNumContacts() const {return m_contacts.size();}
00322 const Contact& getContact(int n) const {return m_contacts[n];}
00326 const Contact& getContactById(ContactId id) const
00327 {   static Contact empty;
00328     ContactMap::const_iterator p = m_id2contact.find(id);
00329     return p==m_id2contact.end() ? empty : m_contacts[p->second]; }
00333 ContactId getContactIdForSurfacePair(ContactSurfaceIndex surf1,
00334                                      ContactSurfaceIndex surf2) const
00335 {   if (surf1 > surf2) std::swap(surf1,surf2);
00336     SurfaceMap::const_iterator p = 
00337         m_surfPair2id.find(std::make_pair(surf1,surf2));
00338     return p==m_surfPair2id.end() ? ContactId() : p->second; }
00339 
00340 //--------------------------------------------------------------------------
00341                                 private:
00342 
00343 // Remove a Contact occupying a particular slot in the Contact array. This
00344 // will result in another Contact object being moved to occupy the now-empty
00345 // slot to keep the array compact.
00346 void removeContact(int n) {
00347     assert(0 <= n && n < m_contacts.size());
00348     if (n+1 == m_contacts.size()) {
00349         m_contacts.pop_back(); // this was the last one
00350         return;
00351     }
00352     // Move the last one to replace this one and update the map.
00353     m_contacts[n] = m_contacts.back();  // shallow copy
00354     m_contacts.pop_back();              // destruct
00355     m_id2contact[m_contacts[n].getContactId()] = n;
00356 }
00357 
00358 
00359 Real                m_time;         // when this snapshot was taken
00360 Array_<Contact,int> m_contacts;     // all the contact pairs
00361 ContactMap          m_id2contact;   // the contact pairs by contactId
00362 SurfaceMap          m_surfPair2id;  // surfacepair -> contactId map
00363 };
00364 
00365 // for debugging
00366 inline std::ostream& operator<<(std::ostream& o, const ContactSnapshot& cs) {
00367     o << "Contact snapshot: time=" << cs.getTimestamp()
00368         << " numContacts=" << cs.getNumContacts() << std::endl;
00369     return o;
00370 }
00371 
00372 
00373 } // namespace SimTK
00374 
00375 #endif // SimTK_SIMBODY_CONTACT_TRACKER_SUBSYSTEM_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines