Simbody
3.7
|
This subsystem identifies and tracks potential contacts between the mobilized bodies of a multibody system. More...
Public Member Functions | |
ContactTrackerSubsystem (MultibodySystem &system) | |
Create a new ContactTrackerSubsystem and install it into the given MultibodySystem. More... | |
SimTK_PIMPL_DOWNCAST (ContactTrackerSubsystem, Subsystem) | |
Find Active Contacts | |
Determine what contacts are occurring. | |
const ContactSnapshot & | getActiveContacts (const State &state) const |
Get the calculated value of the ContactSnapshot cache entry representing the current set of Contact pairs for this system, as determined by the various Tracker algorithms registered with this subsystem. More... | |
const ContactSnapshot & | getPredictedContacts (const State &state) const |
(Advanced) Get an additional set of predicted Contacts that can be anticipated from current velocity and acceleration information. More... | |
Contact Surface Identification | |
These methods map between the assigned ContactSurfaceIndex and the surfaces that were attached to each MobilizedBody in the MultibodySystem. | |
int | getNumSurfaces () const |
Get the number of surfaces being managed by this contact tracker subsystem. More... | |
ContactSurfaceIndex | getContactSurfaceIndex (MobilizedBodyIndex mobod, int contactSurfaceOrdinal) const |
Obtain the ContactSurfaceIndex that was assigned by this ContactTrackerSubsystem to a particular instance of a ContactSurface on a MobilizedBody. More... | |
const MobilizedBody & | getMobilizedBody (ContactSurfaceIndex surfIx) const |
Get the MobilizedBody associated with a particular contact surface. More... | |
const ContactSurface & | getContactSurface (ContactSurfaceIndex surfIx) const |
Get the ContactSurface object (detailed geometry and material properties) that is associated with the given ContactSurfaceIndex. More... | |
const Transform & | getContactSurfaceTransform (ContactSurfaceIndex surfIx) const |
Get the transform X_BS that gives the pose of the indicated contact surface with respect to the body frame of the body to which it is attached. More... | |
Contact Tracker management | |
Most users won't need to use these methods. | |
void | adoptContactTracker (ContactTracker *tracker) |
Register the contact tracking algorithm to use for a particular pair of ContactGeometry types, replacing the existing tracker if any. More... | |
bool | hasContactTracker (ContactGeometryTypeId surface1, ContactGeometryTypeId surface2) const |
Return true if this subsystem has a contact tracker registered that can deal with ineractions between surfaces using the indicated pair of geometry types, in either order. More... | |
const ContactTracker & | getContactTracker (ContactGeometryTypeId surface1, ContactGeometryTypeId surface2, bool &reverseOrder) const |
Return the contact tracker to be used for an interaction between the indicated types of contact geometry. More... | |
Advanced/Obscure | |
You probably don't want to call any of these methods. Some may be unimplemented. | |
const ContactSnapshot & | getPreviousActiveContacts (const State &state) const |
(Advanced) Obtain the value of the ContactSnapshot state variable representing the most recently known set of Contacts for this system. More... | |
const ContactSnapshot & | getPreviousPredictedContacts (const State &state) const |
(Advanced) Obtain the value of the ContactSnapshot state variable representing the most recently predicted set of impending Contacts for this system. More... | |
bool | realizeActiveContacts (const State &state, bool lastTry, Real &stepAdvice) const |
(Advanced) Calculate the current ActiveContacts set at Position stage or later if it hasn't already been done and return true if successful. More... | |
bool | realizePredictedContacts (const State &state, bool lastTry, Real &stepAdvice) const |
(Advanced) Calculate the set of anticipated Contacts set at Acceleration stage if not already calculated and return true if successful. More... | |
ContactTrackerSubsystem () | |
(Advanced) Default constructor creates an empty Subsystem not associated with any MultibodySystem; not very useful. More... | |
Public Member Functions inherited from SimTK::Subsystem | |
Subsystem () | |
Default constructor creates and empty handle with a null Subsystem::Guts pointer. More... | |
Subsystem (const Subsystem &) | |
Copy constructor clones the Subsystem::Guts object if there is one and makes this the owner handle of the new clone. More... | |
Subsystem & | operator= (const Subsystem &) |
Copy assignment deletes the Subsystem::Guts object if there is one and then behaves like the copy constructor. More... | |
~Subsystem () | |
Destructor deletes the referenced Subsystem::Guts object if this is the owner handle of that object, otherwise does nothing. More... | |
QIndex | allocateQ (State &s, const Vector &qInit) const |
UIndex | allocateU (State &s, const Vector &uInit) const |
ZIndex | allocateZ (State &s, const Vector &zInit) const |
DiscreteVariableIndex | allocateDiscreteVariable (State &s, Stage g, AbstractValue *v) const |
DiscreteVariableIndex | allocateAutoUpdateDiscreteVariable (State &s, Stage invalidates, AbstractValue *v, Stage updateDependsOn) const |
CacheEntryIndex | allocateCacheEntry (const State &s, Stage dependsOn, Stage computedBy, AbstractValue *v) const |
CacheEntryIndex | allocateCacheEntry (const State &state, Stage g, AbstractValue *v) const |
CacheEntryIndex | allocateLazyCacheEntry (const State &state, Stage earliest, AbstractValue *v) const |
QErrIndex | allocateQErr (const State &s, int nqerr) const |
UErrIndex | allocateUErr (const State &s, int nuerr) const |
UDotErrIndex | allocateUDotErr (const State &s, int nudoterr) const |
EventTriggerByStageIndex | allocateEventTriggersByStage (const State &s, Stage g, int ntriggers) const |
const Vector & | getQ (const State &s) const |
const Vector & | getU (const State &s) const |
const Vector & | getZ (const State &s) const |
const Vector & | getUWeights (const State &s) const |
const Vector & | getZWeights (const State &s) const |
Vector & | updQ (State &s) const |
Vector & | updU (State &s) const |
Vector & | updZ (State &s) const |
const Vector & | getQDot (const State &s) const |
const Vector & | getUDot (const State &s) const |
const Vector & | getZDot (const State &s) const |
const Vector & | getQDotDot (const State &s) const |
Vector & | updQDot (const State &s) const |
Vector & | updUDot (const State &s) const |
Vector & | updZDot (const State &s) const |
Vector & | updQDotDot (const State &s) const |
const Vector & | getQErr (const State &s) const |
const Vector & | getUErr (const State &s) const |
const Vector & | getQErrWeights (const State &s) const |
const Vector & | getUErrWeights (const State &s) const |
const Vector & | getUDotErr (const State &s) const |
const Vector & | getMultipliers (const State &s) const |
const Vector & | getEventTriggersByStage (const State &s, Stage g) const |
Vector & | updQErr (const State &s) const |
Vector & | updUErr (const State &s) const |
Vector & | updUDotErr (const State &s) const |
Vector & | updMultipliers (const State &s) const |
Vector & | updEventTriggersByStage (const State &s, Stage g) const |
SystemQIndex | getQStart (const State &s) const |
int | getNQ (const State &s) const |
SystemUIndex | getUStart (const State &s) const |
int | getNU (const State &s) const |
SystemZIndex | getZStart (const State &s) const |
int | getNZ (const State &s) const |
SystemQErrIndex | getQErrStart (const State &s) const |
int | getNQErr (const State &s) const |
SystemUErrIndex | getUErrStart (const State &s) const |
int | getNUErr (const State &s) const |
SystemUDotErrIndex | getUDotErrStart (const State &s) const |
int | getNUDotErr (const State &s) const |
SystemMultiplierIndex | getMultipliersStart (const State &s) const |
int | getNMultipliers (const State &s) const |
SystemEventTriggerByStageIndex | getEventTriggerStartByStage (const State &s, Stage g) const |
int | getNEventTriggersByStage (const State &s, Stage g) const |
void | setQ (State &s, const Vector &q) const |
void | setU (State &s, const Vector &u) const |
void | setZ (State &s, const Vector &z) const |
Stage | getStage (const State &s) const |
void | advanceToStage (const State &s, Stage g) const |
const AbstractValue & | getDiscreteVariable (const State &s, DiscreteVariableIndex index) const |
AbstractValue & | updDiscreteVariable (State &s, DiscreteVariableIndex index) const |
const AbstractValue & | getCacheEntry (const State &s, CacheEntryIndex index) const |
AbstractValue & | updCacheEntry (const State &s, CacheEntryIndex index) const |
Real | getDiscreteVarLastUpdateTime (const State &s, DiscreteVariableIndex dx) const |
CacheEntryIndex | getDiscreteVarUpdateIndex (const State &s, DiscreteVariableIndex dx) const |
const AbstractValue & | getDiscreteVarUpdateValue (const State &s, DiscreteVariableIndex dx) const |
AbstractValue & | updDiscreteVarUpdateValue (const State &s, DiscreteVariableIndex dx) const |
bool | isDiscreteVarUpdateValueRealized (const State &s, DiscreteVariableIndex dx) const |
void | markDiscreteVarUpdateValueRealized (const State &s, DiscreteVariableIndex dx) const |
bool | isCacheValueRealized (const State &s, CacheEntryIndex cx) const |
void | markCacheValueRealized (const State &s, CacheEntryIndex cx) const |
void | markCacheValueNotRealized (const State &s, CacheEntryIndex cx) const |
const String & | getName () const |
Obtain the Subsystem name if one was given on construction of the concrete Subsystem. More... | |
const String & | getVersion () const |
Obtain the Subsystem version string if one was given on construction. More... | |
bool | isInSystem () const |
Return true if this Subsystem is contained in a System. More... | |
bool | isInSameSystem (const Subsystem &otherSubsystem) const |
Return true if this Subsystem is contained in the same System as contains the given otherSubsystem. More... | |
const System & | getSystem () const |
Return a const reference to the System that contains this Subsystem. More... | |
System & | updSystem () |
Return a writable reference to the System that contains this Subsystem. More... | |
void | setSystem (System &system, SubsystemIndex subx) |
Inform this Subsystem of the System that contains it, as well as the SubsystemIndex which the System has assigned to it. More... | |
SubsystemIndex | getMySubsystemIndex () const |
Return the SubsystemIndex within the containing System. More... | |
bool | isEmptyHandle () const |
Return true if this handle has a null Subsystem::Guts pointer. More... | |
bool | isSameSubsystem (const Subsystem &otherSubsystem) const |
Determine if this Subsystem handle refers to the same Subsystem::Guts object as handle otherSubsystem. More... | |
bool | isOwnerHandle () const |
Is this Subsystem handle the owner of the Subsystem::Guts object it points to? This is true if the handle is empty or if its Guts object points back to this handle. More... | |
bool | subsystemTopologyHasBeenRealized () const |
Returns true if this Subsystem's realizeTopology() method has been called since the last topological change or call to invalidateSubsystemTopologyCache(). More... | |
void | invalidateSubsystemTopologyCache () const |
Always call this method when a topological change is made to this Subsystem to indicate that any Stage::Topology cache values may need recomputation. More... | |
MeasureIndex | adoptMeasure (AbstractMeasure &) |
Obtain the Subsystem name if one was given on construction of the concrete Subsystem. More... | |
AbstractMeasure | getMeasure (MeasureIndex) const |
Obtain the Subsystem name if one was given on construction of the concrete Subsystem. More... | |
template<class T > | |
Measure_< T > | getMeasure_ (MeasureIndex mx) const |
Obtain the Subsystem name if one was given on construction of the concrete Subsystem. More... | |
const Subsystem::Guts & | getSubsystemGuts () const |
Obtain the Subsystem name if one was given on construction of the concrete Subsystem. More... | |
Subsystem::Guts & | updSubsystemGuts () |
Obtain the Subsystem name if one was given on construction of the concrete Subsystem. More... | |
void | adoptSubsystemGuts (Subsystem::Guts *g) |
Obtain the Subsystem name if one was given on construction of the concrete Subsystem. More... | |
Subsystem (Subsystem::Guts *g) | |
Obtain the Subsystem name if one was given on construction of the concrete Subsystem. More... | |
bool | hasGuts () const |
Obtain the Subsystem name if one was given on construction of the concrete Subsystem. More... | |
This subsystem identifies and tracks potential contacts between the mobilized bodies of a multibody system.
It operates on the undeformed, material-independent geometry of ContactSurface objects that have been associated with those mobilized bodies, identifying and characterizing pairwise geometric relationships that occur between surfaces, and tracking the evolution of particular contacts through time. No physical response to contact is generated here; this subsystem provides only a general contact-tracking service that can be used by other parts of the MultibodySystem to generate forces, impulses, visualizations, messages, noises, or whatever. The goal here is to provide robust and extremely high performance characterization of geometric interactions in a way that is useful for a variety of contact response models.
The ContactTrackerSubsystem maintains an evolving set of tracked Contact objects throughout a simulation; for any given State of the system the subsystem can calculate the current value of that set, which we call the "contact status" of that state. The most recently known prior valid contact status is maintained as part of the system state because the correct instantaneous evaluation of contact status may require past information, and because we are interested in discrete contact events such as initiation and breaking of contact as well as ongoing interactions.
Each Contact being tracked represents the interaction between a unique pair of ContactSurface objects; by definition there is at most one Contact between any such pair (per ContactTrackerSubsystem). The presence of a Contact in the set does not necessarily mean its two surfaces are touching, just that their proximity is interesting in some way. Each Contact is characterized as impending, initiated, ongoing, broken, or separating. At each evaluation, the last-known set of Contacts is used in conjunction with the current State to determine a disposition for each of the tracked Contacts. Contacts that have become boring are removed from the tracked set, and newly-interesting ones are assigned a new ContactId and added to the tracked contacts set. The ContactId persists as long as that Contact continues to remain in the set.
Ambiguous or impossible contact situations can occur during trial steps and can be detected as long as we know the correct contact status in the immediate past. Problems are more common when a simulation contains fast-moving objects, small objects, or thin surfaces, and a relatively large time step size is being attempted by the integrator. For example, we may find that we could have missed a contact that may have occurred since the end of the last step (pass-through), or can't determine whether a small object is deeply penetrated through a thin surface or has simple "gone around the back". In such cases the subsystem reports an error condition that will cause the integrator to reduce the step size. At the start of a time stepping study, there is no past information available to help disambiguate; in that case heuristics are used to make a "best guess" at which surfaces are in contact; those can be overridden by a knowledgable human.
As mentioned above, we track at most one Contact at a time between any pair of ContactSurface objects. However, for some surface types a single Contact may involve many geometric interactions; a mesh Contact, for example, may include a list of all the mesh faces that overlap between the two surfaces, and these do not have to be contiguous over the mesh surface. You may want to break up a concave surface into several ContactSurface objects so that you can separately track several Contacts between that surface and others.
A ContactSurface consists of a piece of surface geometry and a contact material that describes the contact-related physical properties of the surface. A body may have many ContactSurface objects attached to it, each with its own associated contact material. Within an instance of the ContactTrackerSubsystem, each ContactSurface is assigned a unique ContactSurfaceIndex. If you have more than one ContactTrackerSubsystem (not common), they will each have independent sets of ContactSurface objects (and know nothing about one another), so the (Subsystem,ContactSurfaceIndex) pair would be unique but not the index alone. You can map between the assigned ContactSurfaceIndex and the actual surface using methods of this class.
Within a ContactTrackerSubsystem, all the contact surfaces are presumed to be capable of interacting with one another unless they share membership in a "contact clique". All surfaces attached to the same mobilized body are placed together in a clique, so they will never interact. It is also common to create a clique associated with each joint and place nearby contact surfaces on adjacent mobilized bodies into that clique to avoid having to build excessively precise geometry around joints.
Each concrete type of ContactGeometry object (whether provided as part of Simbody or as an extension by the user) has a unique integer ContactGeometryTypeId. Ordered pairs of these Ids are used as a key to select a ContactTracker that is able to identify and manage contacts or potential contacts between those two kinds of geometric objects. You can provide a default tracking algorithm for unhandled pairs that will either ignore them or throw an error. Note that a ContactTracker is invoked only for "narrow phase" contact; the ContactTrackerSubsytem handles the "broad phase" and weeds out all but a few possible contacting surfaces that are then passed to ContactTracker for final disposition. All the ContactTracker objects to be used with a given ContactTrackerSubsystem must be registered with that subsystem during extended construction (Topology stage). Simbody provides default ContactTracker implementations for interactions among most of its built-in ContactGeometry types, such as Sphere-Sphere, Sphere-HalfSpace, Mesh-Sphere, Mesh-Mesh, etc. These will be pre-registered in every ContactTrackerSubsystem but you can replace them with something else if you want.
The result of a ContactTracker when applied to a pair of contact surfaces, is either a determination that the surfaces are not in contact, or a Contact object describing their contact interaction. There are different types of these Contact objects (for example, PointContact, LineContact, MeshContact) and the same algorithm may result in different kinds of Contact under different circumstances. At each evaluation, the subsystem passes in the previous Contact object, if any, that was associated with two ContactSurface objects, then receives an update from the algorithm.
|
explicit |
Create a new ContactTrackerSubsystem and install it into the given MultibodySystem.
SimTK::ContactTrackerSubsystem::ContactTrackerSubsystem | ( | ) |
(Advanced) Default constructor creates an empty Subsystem not associated with any MultibodySystem; not very useful.
const ContactSnapshot& SimTK::ContactTrackerSubsystem::getActiveContacts | ( | const State & | state | ) | const |
Get the calculated value of the ContactSnapshot cache entry representing the current set of Contact pairs for this system, as determined by the various Tracker algorithms registered with this subsystem.
You can call this at Stage::Position or later; computation of contact status will be initiated if needed. Only the past contact status and current positions are used. This cache entry value is precisely what will become the "previous active contacts" state variable at the beginning of the next time step. An error will be thrown if we have to calculate the contacts here but fail to do so; if you don't want to deal with the possibility that an error might occur here, you can realize contacts explicitly first (not common).
const ContactSnapshot& SimTK::ContactTrackerSubsystem::getPredictedContacts | ( | const State & | state | ) | const |
(Advanced) Get an additional set of predicted Contacts that can be anticipated from current velocity and acceleration information.
You can call this at Stage::Acceleration; computation will be initiated if needed. This cache entry value is precisely what will become the "previous predicted contacts" state variable at the beginning of the next time step. An error will be thrown if we have to calculate the contacts here but fail to do so; to avoid that you can realize them explicitly first (not common).
int SimTK::ContactTrackerSubsystem::getNumSurfaces | ( | ) | const |
Get the number of surfaces being managed by this contact tracker subsystem.
These are identified by ContactSurfaceIndex values from 0 to getNumSurfaces()-1
. This is available after realizeTopology()
and does not change subsequently. You can find out which ContactSurfaceIndex got assigned any particular ContactSurface using getContactSurfaceIndex()
.
ContactSurfaceIndex SimTK::ContactTrackerSubsystem::getContactSurfaceIndex | ( | MobilizedBodyIndex | mobod, |
int | contactSurfaceOrdinal | ||
) | const |
Obtain the ContactSurfaceIndex that was assigned by this ContactTrackerSubsystem to a particular instance of a ContactSurface on a MobilizedBody.
A ContactSurface is attached to a body description using Body::addContactSurface()
and then that body description is used to create an actual body instance in a MobilizedBody. The surface is identified here by specifying the MobilizedBody of interest and the small integer ordinal that was returned when Body::addContactSurface()
was called. (You can provide either a MobilizedBody or MobilizedBodyIndex here; there is an implicit conversion from MobilizedBody to its MobilizedBodyIndex.) This method will throw an exception if either argument is illegal or out of range.
const MobilizedBody& SimTK::ContactTrackerSubsystem::getMobilizedBody | ( | ContactSurfaceIndex | surfIx | ) | const |
Get the MobilizedBody associated with a particular contact surface.
const ContactSurface& SimTK::ContactTrackerSubsystem::getContactSurface | ( | ContactSurfaceIndex | surfIx | ) | const |
Get the ContactSurface object (detailed geometry and material properties) that is associated with the given ContactSurfaceIndex.
const Transform& SimTK::ContactTrackerSubsystem::getContactSurfaceTransform | ( | ContactSurfaceIndex | surfIx | ) | const |
Get the transform X_BS that gives the pose of the indicated contact surface with respect to the body frame of the body to which it is attached.
void SimTK::ContactTrackerSubsystem::adoptContactTracker | ( | ContactTracker * | tracker | ) |
Register the contact tracking algorithm to use for a particular pair of ContactGeometry types, replacing the existing tracker if any.
If the tracker takes a pair (id1,id2), we will use it both for that pair and for (id2,id1) by calling it with the arguments reversed. The subsystem takes over ownership of the supplied heap-allocated object.
bool SimTK::ContactTrackerSubsystem::hasContactTracker | ( | ContactGeometryTypeId | surface1, |
ContactGeometryTypeId | surface2 | ||
) | const |
Return true if this subsystem has a contact tracker registered that can deal with ineractions between surfaces using the indicated pair of geometry types, in either order.
const ContactTracker& SimTK::ContactTrackerSubsystem::getContactTracker | ( | ContactGeometryTypeId | surface1, |
ContactGeometryTypeId | surface2, | ||
bool & | reverseOrder | ||
) | const |
Return the contact tracker to be used for an interaction between the indicated types of contact geometry.
If the tracker requires the geometry types to be in reverse order from the (surface1,surface2) order given here, then the return argument reverseOrder will be set true, otherwise it will be false. If no tracker was registered, this will be the default tracker.
const ContactSnapshot& SimTK::ContactTrackerSubsystem::getPreviousActiveContacts | ( | const State & | state | ) | const |
(Advanced) Obtain the value of the ContactSnapshot state variable representing the most recently known set of Contacts for this system.
const ContactSnapshot& SimTK::ContactTrackerSubsystem::getPreviousPredictedContacts | ( | const State & | state | ) | const |
(Advanced) Obtain the value of the ContactSnapshot state variable representing the most recently predicted set of impending Contacts for this system.
bool SimTK::ContactTrackerSubsystem::realizeActiveContacts | ( | const State & | state, |
bool | lastTry, | ||
Real & | stepAdvice | ||
) | const |
(Advanced) Calculate the current ActiveContacts set at Position stage or later if it hasn't already been done and return true if successful.
If we can't unambiguously determine the contact status, we'll return false and give the caller a hint as to the latest time at which we think we could have succeeded. If lastTry is true, then we throw an error on failure rather than returning false.
bool SimTK::ContactTrackerSubsystem::realizePredictedContacts | ( | const State & | state, |
bool | lastTry, | ||
Real & | stepAdvice | ||
) | const |
(Advanced) Calculate the set of anticipated Contacts set at Acceleration stage if not already calculated and return true if successful.
Otherwise, problems are handled as for realizeActiveContacts().
SimTK::ContactTrackerSubsystem::SimTK_PIMPL_DOWNCAST | ( | ContactTrackerSubsystem | , |
Subsystem | |||
) |