State Class Reference

#include <State.h>

List of all members.


Detailed Description

This is the handle class for the hidden State implementation.

This object is intended to contain all State information for a SimTK::System, except topological information which is stored in the System itself. A System is "const" after its topology has been constructed and realized.

Systems are composed of Subsystems, and the State supports that concept by allowing per-subsystem partitioning of the total System state. This allows subsytems to have their own private state variables, while permitting the system to allow shared access to state among the subsystems when necessary.

The State provides services reflecting the structure of the equations it expects to find in the System. Three different views of the same state information are supported to accommodate three different users:

The system is expected to be a "hybrid DAE", that is, a mixture of continuous and discrete dynamic equations, and algebraic constraints. There is an independent variable t, continuous state variables y, and discrete state variables d.

The continuous part is an ODE-on-a-manifold system suitable for solution via coordinate projection, structured like this for the view taken by numerical methods: (1) y' = f(d;t,y) differential equations (2) c = c(d;t,y) algebraic equations (manifold is c=0) (3) e = e(d;t,y) event triggers (watch for zero crossings) with initial conditions t0,y0,d0 such that c=0. The discrete variables d are updated upon occurence of specific events, which are detected using the set of scalar-valued event trigger functions e (3).

In the more detailed view as seen from the System, we consider y={q,u,z} to be partitioned into position variables q, velocity variables u, and auxiliary variables z. There will be algebraic constraints involving q, u, and u's time derivatives udot. The system is now assumed to look like this:

      (4) qdot    = Q(q) u
      (5) zdot    = zdot(d;t,q,u,z)

      (6) M(q) udot + ~G(q) mult = f(d;t,q,u,z)
          G(q) udot              = b(d;t,q,u)

      (7) udotErr = [ pdotdot(d;t,q,u) ]      = 0
                    [ vdot(d;t,q,u)    ]
                    [ a(d;t,q,u)       ]

      (8) uErr    = [ pdot(d;t,q,u) ]
                    [ v(d;t,q,u)    ]         = 0

      (9) qErr    = [ p(d;t,q) ]              = 0
                    [ n(q)     ]
 
Here G = [P;V;A] with A(q) being the coefficient matrix for constraints appearing only at the acceleration level, and V(q)=partial(v)/partial(u) the coefficient matrix for the velocity (nonholonomic) constraints, and P(q)=partial(pdot)/partial(u) is the coefficient matrix of the first time derivatives of the position (holonomic) constraints. Note that uErr in Eq 8 is assumed to include equations resulting from differentiation of p() in Eq 9, as well as ones first introduced at the velocity level (nonholonomic constraints), and udotErr is similarly built from acceleration-only constraints a() and derivatives of higher-level constraints.

If a system allocates nq q's, nu u's, and nz z's the State will also allocate matching cache variables qdot, qdotdot, udot, and zdot. If mp position (holonomic) constraints (9), mpv velocity constraints (8) and mpva acceleration constraints (7) are allocated, the state creates cache entries of like sizes qErr, uErr, udotErr. In addition room for the mpva Lagrange multipliers 'mult' is allocated in the cache.

In the final view, the Subsystem view, the same variables and cache entries exist, but only the ones allocated by that Subsystem are visible. All of a Subsystem's q's are consecutive in memory, as are its u's, uErr's, etc., but the q's are not adjacent to the u's as they are for the System's view.

The default constructor creates a State containing no state variables and with its realization cache stage set to Stage::Empty. During Subsystem construction, variables and cache entries for any stage can be allocated, however *all* Model stage variables must be allocated during this time. At the end of construction, call advanceSubsystemToStage(Topology) which will put the Subsystem at Stage::Topology. Then the Subsystems realize their Model stages, during which variables at any stage > Model, and cache entries at any stage >= Model can be allocated. After that call advanceSubsystemToStage(Model) which sets the stage to Stage::Model and disallows further allocation.

Note that there is a global Stage for the state as a whole, and individual Stages for each subsystem. The global stage can never be higher than the lowest subsystem stage. Global resources are allocated when the global Stage advances to "Model" and tossed out if that stage is invalidated. Note that subsystems will "register" their use of the global variable pools during their own modeling stages, but that the actual global resources won't exist until the *system* has been advanced to Model stage.


Public Member Functions

 State ()
 Create an empty State.
 ~State ()
void clear ()
 Restore State to default-constructed condition.
void setNSubsystems (int i)
 Set the number of subsystems in this state.
void initializeSubsystem (SubsystemIndex, const String &name, const String &version)
 Set the name and version for a given subsystem, which must already have a slot allocated.
 State (const State &)
 Make the current State a copy of the source state, copying only state variables and not the cache.
Stateoperator= (const State &)
 Make the current State a copy of the source state, copying only state variables and not the cache.
int addSubsystem (const String &name, const String &version)
 Register a new subsystem as a client of this State.
int getNSubsystems () const
const StringgetSubsystemName (SubsystemIndex) const
const StringgetSubsystemVersion (SubsystemIndex) const
const StagegetSubsystemStage (SubsystemIndex) const
const StagegetSystemStage () const
 This returns the *global* stage for this State.
void invalidateAll (Stage) const
 If any subsystem or the system stage is currently at or higher than the passed-in one, back up to the stage just prior.
void advanceSubsystemToStage (SubsystemIndex, Stage) const
 Advance the current stage by one to the indicated stage.
void advanceSystemToStage (Stage) const
int allocateQ (SubsystemIndex, const Vector &qInit)
 These are shared among all the subsystems and are not allocated until the *System* is advanced to Stage::Model.
int allocateU (SubsystemIndex, const Vector &uInit)
int allocateZ (SubsystemIndex, const Vector &zInit)
int allocateQErr (SubsystemIndex, int nqerr)
 Slots for constraint errors are handled similarly, although these are just cache entries not state variables.
int allocateUErr (SubsystemIndex, int nuerr)
int allocateUDotErr (SubsystemIndex, int nudoterr)
int allocateEvent (SubsystemIndex, Stage, int nevent)
 Slots for event witness values are similar to constraint errors.
int allocateDiscreteVariable (SubsystemIndex, Stage, AbstractValue *v)
 DiscreteVariables and CacheEntries are private to each subsystem and are allocated immediately.
int allocateCacheEntry (SubsystemIndex, Stage, AbstractValue *v)
int getNY () const
 Dimensions.
int getQStart () const
int getNQ () const
int getUStart () const
int getNU () const
int getZStart () const
int getNZ () const
int getNYErr () const
int getQErrStart () const
int getNQErr () const
int getUErrStart () const
int getNUErr () const
int getNUDotErr () const
int getNMultipliers () const
int getQStart (SubsystemIndex) const
int getNQ (SubsystemIndex) const
int getUStart (SubsystemIndex) const
int getNU (SubsystemIndex) const
int getZStart (SubsystemIndex) const
int getNZ (SubsystemIndex) const
int getQErrStart (SubsystemIndex) const
int getNQErr (SubsystemIndex) const
int getUErrStart (SubsystemIndex) const
int getNUErr (SubsystemIndex) const
int getUDotErrStart (SubsystemIndex) const
int getNUDotErr (SubsystemIndex) const
int getMultipliersStart (SubsystemIndex i) const
int getNMultipliers (SubsystemIndex i) const
int getNEvents () const
int getEventStartByStage (Stage) const
int getNEventsByStage (Stage) const
int getEventStartByStage (SubsystemIndex, Stage) const
int getNEventsByStage (SubsystemIndex, Stage) const
const VectorgetEvents () const
const VectorgetEventsByStage (Stage) const
const VectorgetEventsByStage (SubsystemIndex, Stage) const
VectorupdEvents () const
VectorupdEventsByStage (Stage) const
VectorupdEventsByStage (SubsystemIndex, Stage) const
const VectorgetQ (SubsystemIndex) const
 Per-subsystem access to the global shared variables.
const VectorgetU (SubsystemIndex) const
const VectorgetZ (SubsystemIndex) const
VectorupdQ (SubsystemIndex)
VectorupdU (SubsystemIndex)
VectorupdZ (SubsystemIndex)
const VectorgetQDot (SubsystemIndex) const
 Per-subsystem access to the shared cache entries.
const VectorgetUDot (SubsystemIndex) const
const VectorgetZDot (SubsystemIndex) const
const VectorgetQDotDot (SubsystemIndex) const
VectorupdQDot (SubsystemIndex) const
VectorupdUDot (SubsystemIndex) const
VectorupdZDot (SubsystemIndex) const
VectorupdQDotDot (SubsystemIndex) const
const VectorgetQErr (SubsystemIndex) const
const VectorgetUErr (SubsystemIndex) const
const VectorgetUDotErr (SubsystemIndex) const
const VectorgetMultipliers (SubsystemIndex) const
VectorupdQErr (SubsystemIndex) const
VectorupdUErr (SubsystemIndex) const
VectorupdUDotErr (SubsystemIndex) const
VectorupdMultipliers (SubsystemIndex) const
const Real & getTime () const
 You can call these as long as *system* stage >= Model.
const VectorgetY () const
const VectorgetQ () const
 These are just views into Y.
const VectorgetU () const
const VectorgetZ () const
Real & updTime ()
 You can call these as long as stage >= Model, but the stage will be backed up if necessary to the indicated stage.
VectorupdY ()
void setTime (Real t)
 An alternate syntax equivalent to updTime() and updY().
void setY (const Vector &y)
VectorupdQ ()
 These are just views into Y.
VectorupdU ()
VectorupdZ ()
void setQ (const Vector &q)
 Alternate interface.
void setU (const Vector &u)
void setZ (const Vector &z)
const VectorgetYDot () const
const VectorgetQDot () const
 These are just views into YDot.
const VectorgetZDot () const
const VectorgetUDot () const
const VectorgetQDotDot () const
 This has its own space, not a view.
VectorupdYDot () const
 These are mutable.
VectorupdQDot () const
VectorupdZDot () const
VectorupdUDot () const
VectorupdQDotDot () const
 This is a separate shared cache entry, not part of YDot.
const VectorgetYErr () const
 Return the current constraint errors for all constraints.
const VectorgetQErr () const
 These are just views into YErr.
const VectorgetUErr () const
const VectorgetUDotErr () const
 These have their own space, the are not views.
const VectorgetMultipliers () const
VectorupdYErr () const
 These are mutable.
VectorupdQErr () const
VectorupdUErr () const
VectorupdUDotErr () const
VectorupdMultipliers () const
const AbstractValuegetDiscreteVariable (SubsystemIndex, int index) const
 OK if dv.stage==Model or stage >= Model.
AbstractValueupdDiscreteVariable (SubsystemIndex, int index)
 OK if dv.stage==Model or stage >= Model; set stage to dv.stage-1.
void setDiscreteVariable (SubsystemIndex i, int index, const AbstractValue &v)
 Alternate interface to updDiscreteVariable.
const AbstractValuegetCacheEntry (SubsystemIndex, int index) const
 Stage >= ce.stage.
AbstractValueupdCacheEntry (SubsystemIndex, int index) const
 Stage >= ce.stage-1; does not change stage.
void createRestrictedState (State &restrictedState, EnumerationSet< Stage > restrictedStages, std::set< SubsystemIndex > restrictedSubsystems)
 Transform a State into one which shares all the same data as this one, such that modifying either one will modify both of them.
EnumerationSet< StagegetRestrictedStages () const
 Get the set of stages which cannot be modified in this State.
std::set< SubsystemIndex > getRestrictedSubsystems () const
 Get the set of subsystems which cannot be modified in this State.
String toString () const
String cacheToString () const


Constructor & Destructor Documentation

State (  ) 

Create an empty State.

~State (  ) 

State ( const State  ) 

Make the current State a copy of the source state, copying only state variables and not the cache.

If the source state hasn't been realized to Model stage, then we don't copy its state variables either, except those associated with the Topology stage.


Member Function Documentation

int addSubsystem ( const String name,
const String version 
)

Register a new subsystem as a client of this State.

The supplied strings are stored with the State but are not interpreted by it. The intent is that they can be used to perform "sanity checks" on deserialized States to make sure they match the currently instantiated System. The subsystem index (a small integer) is returned.

void advanceSubsystemToStage ( SubsystemIndex  ,
Stage   
) const

Advance the current stage by one to the indicated stage.

The stage is passed in just to give us a chance to verify that all is as expected. You can only advance one stage at a time. Advancing to "Topology" and "Model" stages affect what you can do later.

void advanceSystemToStage ( Stage   )  const

int allocateCacheEntry ( SubsystemIndex  ,
Stage  ,
AbstractValue v 
)

See also:
allocateDiscreteVariable()

int allocateDiscreteVariable ( SubsystemIndex  ,
Stage  ,
AbstractValue v 
)

DiscreteVariables and CacheEntries are private to each subsystem and are allocated immediately.

Ownership of the AbstractValue object is taken over by the State -- don't delete the object after this call!

int allocateEvent ( SubsystemIndex  ,
Stage  ,
int  nevent 
)

Slots for event witness values are similar to constraint errors.

However, this also allocates a discrete state variable to hold the "triggered" indication. The Stage here is the stage at which the event witness function can first be examined.

int allocateQ ( SubsystemIndex  ,
const Vector qInit 
)

These are shared among all the subsystems and are not allocated until the *System* is advanced to Stage::Model.

The returned index is local to each subsystem. After the System is modeled, we guarantee that all the q's for a subsystem will be contiguous, and similarly for u's and z's. However, q,u,z will *not* be contiguous with each other. The *global* y is contiguous, and global q,u,z are contiguous within y, in that order.

int allocateQErr ( SubsystemIndex  ,
int  nqerr 
)

Slots for constraint errors are handled similarly, although these are just cache entries not state variables.

Q errors and U errors will each be contiguous for a given subsystem, but *not* with each other. However, yerr={qerr,uerr} *is* a single contiguous vector. UDotErr is a separate quantity, not part of yerr. Again the UDotErr's for each subsystem will be contiguous within the larger UDotErr Vector. Allocating a UDotErr has the side effect of allocating another Vector of the same size in the cache for the corresponding Lagrange multipliers, and these are partitioned identically to UDotErrs.

int allocateU ( SubsystemIndex  ,
const Vector uInit 
)

int allocateUDotErr ( SubsystemIndex  ,
int  nudoterr 
)

int allocateUErr ( SubsystemIndex  ,
int  nuerr 
)

int allocateZ ( SubsystemIndex  ,
const Vector zInit 
)

String cacheToString (  )  const

void clear (  ) 

Restore State to default-constructed condition.

void createRestrictedState ( State restrictedState,
EnumerationSet< Stage restrictedStages,
std::set< SubsystemIndex >  restrictedSubsystems 
)

Transform a State into one which shares all the same data as this one, such that modifying either one will modify both of them.

The new State restricts which stages and subsystems may be modified. Any attempt to modify restricted data through that object will produce an exception.

This method can only add restrictions, not remove them. If this State was itself created by createRestrictedState(), the new state will inherit all of the restrictions from this one, in addition to any that are specified in the arguments.

const AbstractValue& getCacheEntry ( SubsystemIndex  ,
int  index 
) const

Stage >= ce.stage.

const AbstractValue& getDiscreteVariable ( SubsystemIndex  ,
int  index 
) const

OK if dv.stage==Model or stage >= Model.

const Vector& getEvents (  )  const

const Vector& getEventsByStage ( SubsystemIndex  ,
Stage   
) const

const Vector& getEventsByStage ( Stage   )  const

int getEventStartByStage ( SubsystemIndex  ,
Stage   
) const

int getEventStartByStage ( Stage   )  const

const Vector& getMultipliers (  )  const

const Vector& getMultipliers ( SubsystemIndex   )  const

int getMultipliersStart ( SubsystemIndex  i  )  const

int getNEvents (  )  const

int getNEventsByStage ( SubsystemIndex  ,
Stage   
) const

int getNEventsByStage ( Stage   )  const

int getNMultipliers ( SubsystemIndex  i  )  const

int getNMultipliers (  )  const

int getNQ ( SubsystemIndex   )  const

int getNQ (  )  const

int getNQErr ( SubsystemIndex   )  const

int getNQErr (  )  const

int getNSubsystems (  )  const

int getNU ( SubsystemIndex   )  const

int getNU (  )  const

int getNUDotErr ( SubsystemIndex   )  const

int getNUDotErr (  )  const

int getNUErr ( SubsystemIndex   )  const

int getNUErr (  )  const

int getNY (  )  const

Dimensions.

These are valid at Stage::Model while access to the various arrays may have stricter requirements. Hence it is better to use these routines than to get a reference to a Vector and ask for its size().

int getNYErr (  )  const

int getNZ ( SubsystemIndex   )  const

int getNZ (  )  const

const Vector& getQ (  )  const

These are just views into Y.

const Vector& getQ ( SubsystemIndex   )  const

Per-subsystem access to the global shared variables.

const Vector& getQDot (  )  const

These are just views into YDot.

const Vector& getQDot ( SubsystemIndex   )  const

Per-subsystem access to the shared cache entries.

const Vector& getQDotDot (  )  const

This has its own space, not a view.

const Vector& getQDotDot ( SubsystemIndex   )  const

const Vector& getQErr (  )  const

These are just views into YErr.

const Vector& getQErr ( SubsystemIndex   )  const

int getQErrStart ( SubsystemIndex   )  const

int getQErrStart (  )  const

int getQStart ( SubsystemIndex   )  const

int getQStart (  )  const

EnumerationSet<Stage> getRestrictedStages (  )  const

Get the set of stages which cannot be modified in this State.

Attempting to modify any of these stages will produce an exception.

std::set<SubsystemIndex> getRestrictedSubsystems (  )  const

Get the set of subsystems which cannot be modified in this State.

Attempting to modify any of these subsystems will produce an exception.

const String& getSubsystemName ( SubsystemIndex   )  const

const Stage& getSubsystemStage ( SubsystemIndex   )  const

const String& getSubsystemVersion ( SubsystemIndex   )  const

const Stage& getSystemStage (  )  const

This returns the *global* stage for this State.

const Real& getTime (  )  const

You can call these as long as *system* stage >= Model.

const Vector& getU (  )  const

const Vector& getU ( SubsystemIndex   )  const

const Vector& getUDot (  )  const

const Vector& getUDot ( SubsystemIndex   )  const

const Vector& getUDotErr (  )  const

These have their own space, the are not views.

const Vector& getUDotErr ( SubsystemIndex   )  const

int getUDotErrStart ( SubsystemIndex   )  const

const Vector& getUErr (  )  const

const Vector& getUErr ( SubsystemIndex   )  const

int getUErrStart ( SubsystemIndex   )  const

int getUErrStart (  )  const

int getUStart ( SubsystemIndex   )  const

int getUStart (  )  const

const Vector& getY (  )  const

const Vector& getYDot (  )  const

const Vector& getYErr (  )  const

Return the current constraint errors for all constraints.

const Vector& getZ (  )  const

const Vector& getZ ( SubsystemIndex   )  const

const Vector& getZDot (  )  const

const Vector& getZDot ( SubsystemIndex   )  const

int getZStart ( SubsystemIndex   )  const

int getZStart (  )  const

void initializeSubsystem ( SubsystemIndex  ,
const String name,
const String version 
)

Set the name and version for a given subsystem, which must already have a slot allocated.

void invalidateAll ( Stage   )  const

If any subsystem or the system stage is currently at or higher than the passed-in one, back up to the stage just prior.

Otherwise do nothing.

State& operator= ( const State  ) 

Make the current State a copy of the source state, copying only state variables and not the cache.

If the source state hasn't been realized to Model stage, then we don't copy its state variables either, except those associated with the Topology stage.

void setDiscreteVariable ( SubsystemIndex  i,
int  index,
const AbstractValue v 
)

Alternate interface to updDiscreteVariable.

void setNSubsystems ( int  i  ) 

Set the number of subsystems in this state.

This is done during initialization of the State by a System; it completely wipes out anything that used to be in the state so use cautiously!

void setQ ( const Vector q  ) 

Alternate interface.

void setTime ( Real  t  ) 

An alternate syntax equivalent to updTime() and updY().

void setU ( const Vector u  ) 

void setY ( const Vector y  ) 

void setZ ( const Vector z  ) 

String toString (  )  const

AbstractValue& updCacheEntry ( SubsystemIndex  ,
int  index 
) const

Stage >= ce.stage-1; does not change stage.

AbstractValue& updDiscreteVariable ( SubsystemIndex  ,
int  index 
)

OK if dv.stage==Model or stage >= Model; set stage to dv.stage-1.

Vector& updEvents (  )  const

Vector& updEventsByStage ( SubsystemIndex  ,
Stage   
) const

Vector& updEventsByStage ( Stage   )  const

Vector& updMultipliers (  )  const

Vector& updMultipliers ( SubsystemIndex   )  const

Vector& updQ (  ) 

These are just views into Y.

Vector& updQ ( SubsystemIndex   ) 

Vector& updQDot (  )  const

Vector& updQDot ( SubsystemIndex   )  const

Vector& updQDotDot (  )  const

This is a separate shared cache entry, not part of YDot.

If you have a direct 2nd order integrator you can integrate QDotDot (twice) to get Q.

Vector& updQDotDot ( SubsystemIndex   )  const

Vector& updQErr (  )  const

Vector& updQErr ( SubsystemIndex   )  const

Real& updTime (  ) 

You can call these as long as stage >= Model, but the stage will be backed up if necessary to the indicated stage.

Vector& updU (  ) 

Vector& updU ( SubsystemIndex   ) 

Vector& updUDot (  )  const

Vector& updUDot ( SubsystemIndex   )  const

Vector& updUDotErr (  )  const

Vector& updUDotErr ( SubsystemIndex   )  const

Vector& updUErr (  )  const

Vector& updUErr ( SubsystemIndex   )  const

Vector& updY (  ) 

Vector& updYDot (  )  const

These are mutable.

Vector& updYErr (  )  const

These are mutable.

Vector& updZ (  ) 

Vector& updZ ( SubsystemIndex   ) 

Vector& updZDot (  )  const

Vector& updZDot ( SubsystemIndex   )  const


The documentation for this class was generated from the following file:
Generated on Thu Feb 28 01:34:36 2008 for SimTKcommon by  doxygen 1.4.7