State.h

Go to the documentation of this file.
00001 #ifndef SimTK_SimTKCOMMON_STATE_H_
00002 #define SimTK_SimTKCOMMON_STATE_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                      SimTK Core: SimTKcommon                               *
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) 2005-7 Stanford University and the Authors.         *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors: Peter Eastman                                                *
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/basics.h"
00036 #include "SimTKcommon/Simmatrix.h"
00037 
00038 #include <ostream>
00039 #include <cassert>
00040 #include <set>
00041 
00042 namespace SimTK {
00043 
00044 SimTK_DEFINE_UNIQUE_INDEX_TYPE(SubsystemIndex)
00045 
00046 // TODO: these need an option to have associated "update" variables in the cache,
00047 // analogous to the derivative variables qdot,udot,zdot that we create
00048 // for the continuous variables. Consider whether "discrete variable" should
00049 // be reserved for those that are updated in time, with something else like
00050 // "parameter variable" for those that just hold externally set data.
00051 
00052 class SimTK_SimTKCOMMON_EXPORT DiscreteVariable {
00053 public:
00054     DiscreteVariable() : rep(0) { }
00055     DiscreteVariable(const DiscreteVariable&);
00056     DiscreteVariable& operator=(const DiscreteVariable&);
00057     ~DiscreteVariable();
00058 
00059     // This takes ownership of the AbstractValue pointer.
00060     DiscreteVariable(Stage, AbstractValue* vp);
00061 
00062     Stage getStage() const;
00063     const AbstractValue& getValue() const;
00064     AbstractValue&       updValue();
00065 
00066 private:
00067     class DiscreteVariableRep* rep;
00068 };
00069 
00070 class SimTK_SimTKCOMMON_EXPORT CacheEntry : public DiscreteVariable {
00071 public:
00072     CacheEntry() : DiscreteVariable() { }
00073 
00074     // This takes ownership of the AbstractValue pointer.
00075     CacheEntry(Stage g, AbstractValue* vp)
00076         : DiscreteVariable(g,vp) { }
00077 
00078     CacheEntry(const CacheEntry& ce) : DiscreteVariable(ce) { }
00079     CacheEntry& operator=(const CacheEntry& ce) {
00080         DiscreteVariable::operator=(ce);
00081         return *this;
00082     }
00083 };
00084 
00085 class EventStatus {
00086 public:
00087     EventStatus() { initialize(); }
00088     // default destructor, copy constructor, copy assignment
00089 
00090     // Event trigger (which zero crossings cause triggering). Can be
00091     // OR'ed together to make a mask.
00092     enum EventTrigger {
00093         NoEventTrigger          =0x0000,    // must be 0
00094 
00095         PositiveToNegative      =0x0001,    // 1
00096         NegativeToPositive      =0x0002,    // 2
00097 
00098         Falling                 =(PositiveToNegative), // 1
00099         Rising                  =(NegativeToPositive), // 2
00100         AnySignChange           =(PositiveToNegative|NegativeToPositive)    // 3
00101     };
00102 
00103     bool isEventPending() const {return transitionSeen != NoEventTrigger;}
00104     EventTrigger getEventTrigger() const {return transitionSeen;}
00105     Real getLastTriggerTime() const {return lastTriggerTime;}
00106     Real getLastTriggerTimeBestGuess() const {return lastTriggerTimeBestGuess;}
00107     Real getBeforeValue() const {return beforeValue;}
00108     Real getAfterValue() const {return afterValue;}
00109     Real getLocalizationWindow() const {return localizationWindow;}
00110 
00111     void setEventTriggered(EventTrigger transition, Real triggerTime,
00112                            Real actualTimeEst, Real window,
00113                            Real before, Real after)
00114     {
00115         assert(transition != NoEventTrigger);
00116         assert(triggerTime >= 0 && actualTimeEst >= 0 
00117                && triggerTime >= actualTimeEst);
00118 
00119         transitionSeen = transition;
00120         lastTriggerTime = triggerTime;
00121         lastTriggerTimeBestGuess = actualTimeEst;
00122         localizationWindow = window;
00123         beforeValue = before;
00124         afterValue  = after;
00125     }
00126 
00127     void clearEventTrigger() {
00128         transitionSeen = NoEventTrigger;
00129     }
00130 
00131     // Classify a before/after sign transition.
00132     static EventTrigger classifyTransition(int before, int after) {
00133         if (before==after)
00134             return NoEventTrigger;
00135         if (before==0)
00136             return NoEventTrigger; // Do not report transitions away from zero.
00137         if (before==1)
00138             return PositiveToNegative;
00139         // before==-1
00140         return NegativeToPositive;
00141     }
00142 
00143     static EventTrigger maskTransition(EventTrigger transition, EventTrigger mask) {
00144         return EventTrigger(transition & mask); // we're depending on NoEventTrigger==0
00145     }
00146 
00147     SimTK_SimTKCOMMON_EXPORT static String eventTriggerString(EventTrigger e);
00148 private:
00149     void initialize() {
00150         transitionSeen = NoEventTrigger;
00151         lastTriggerTime = lastTriggerTimeBestGuess = localizationWindow
00152             = beforeValue = afterValue = NaN;
00153     }
00154 
00155     EventTrigger transitionSeen;
00156     Real         lastTriggerTime; // digital
00157     Real         lastTriggerTimeBestGuess; // analog, <=lastTriggerTime
00158     Real         localizationWindow;
00159     Real         beforeValue, afterValue;
00160 };
00161 
00266 class SimTK_SimTKCOMMON_EXPORT State {
00267 public:
00269     State();
00270     ~State();
00271 
00273     void clear();
00274 
00278     void setNSubsystems(int i);
00279 
00282     void initializeSubsystem(SubsystemIndex, const String& name, const String& version);
00283 
00288     State(const State&);
00289 
00294     State& operator=(const State&);
00295 
00302     int addSubsystem(const String& name, const String& version);
00303 
00304     int getNSubsystems() const;
00305     const String& getSubsystemName   (SubsystemIndex) const;
00306     const String& getSubsystemVersion(SubsystemIndex) const;
00307     const Stage&  getSubsystemStage  (SubsystemIndex) const;
00308 
00310     const Stage& getSystemStage() const;
00311 
00315     void invalidateAll(Stage) const;  // cache is mutable
00316 
00322     void advanceSubsystemToStage(SubsystemIndex, Stage) const;
00323     void advanceSystemToStage(Stage) const;
00324 
00332 
00333     int allocateQ(SubsystemIndex, const Vector& qInit); // qdot, qdotdot also allocated in cache
00334     int allocateU(SubsystemIndex, const Vector& uInit); // udot                    "
00335     int allocateZ(SubsystemIndex, const Vector& zInit); // zdot                    "
00336 
00346 
00347     int allocateQErr   (SubsystemIndex, int nqerr);    // these are cache entries
00348     int allocateUErr   (SubsystemIndex, int nuerr);
00349     int allocateUDotErr(SubsystemIndex, int nudoterr);
00350 
00355     int allocateEvent(SubsystemIndex, Stage, int nevent);
00356 
00360     int allocateDiscreteVariable(SubsystemIndex, Stage, AbstractValue* v);
00362     int allocateCacheEntry      (SubsystemIndex, Stage, AbstractValue* v);
00363     
00367 
00368     int getNY() const; // = nq+nu+nz
00369     int getQStart() const; int getNQ() const;
00370     int getUStart() const; int getNU() const;
00371     int getZStart() const; int getNZ() const;
00372 
00373     int getNYErr() const; // = nqerr+nuerr
00374     int getQErrStart() const; int getNQErr() const; // =mp + #quaternions
00375     int getUErrStart() const; int getNUErr() const; // =mp+mv
00376 
00377     int getNUDotErr() const;     // =mp+mv+ma
00378     int getNMultipliers() const; // =mp+mv+ma, necessarily the same as NUDotErr
00379 
00380     int getQStart(SubsystemIndex)       const; int getNQ(SubsystemIndex)       const;
00381     int getUStart(SubsystemIndex)       const; int getNU(SubsystemIndex)       const;
00382     int getZStart(SubsystemIndex)       const; int getNZ(SubsystemIndex)       const;
00383 
00384     int getQErrStart(SubsystemIndex)    const; int getNQErr(SubsystemIndex)    const;
00385     int getUErrStart(SubsystemIndex)    const; int getNUErr(SubsystemIndex)    const;
00386     int getUDotErrStart(SubsystemIndex) const; int getNUDotErr(SubsystemIndex) const;
00387     int getMultipliersStart(SubsystemIndex i) const;
00388     int getNMultipliers(SubsystemIndex i)     const;
00389 
00390         // Event handling
00391     int getNEvents() const; // total
00392     int getEventStartByStage(Stage) const; // per-stage
00393     int getNEventsByStage(Stage) const;
00394     int getEventStartByStage(SubsystemIndex, Stage) const;
00395     int getNEventsByStage(SubsystemIndex, Stage) const;
00396 
00397     const Vector& getEvents() const;
00398     const Vector& getEventsByStage(Stage) const;
00399     const Vector& getEventsByStage(SubsystemIndex, Stage) const;
00400 
00401     Vector& updEvents() const; // mutable
00402     Vector& updEventsByStage(Stage) const;
00403     Vector& updEventsByStage(SubsystemIndex, Stage) const;
00404 
00406     const Vector& getQ(SubsystemIndex) const;
00407     const Vector& getU(SubsystemIndex) const;
00408     const Vector& getZ(SubsystemIndex) const;
00409 
00410     Vector& updQ(SubsystemIndex);
00411     Vector& updU(SubsystemIndex);
00412     Vector& updZ(SubsystemIndex);
00413 
00415     const Vector& getQDot(SubsystemIndex) const;
00416     const Vector& getUDot(SubsystemIndex) const;
00417     const Vector& getZDot(SubsystemIndex) const;
00418     const Vector& getQDotDot(SubsystemIndex) const;
00419 
00420     Vector& updQDot(SubsystemIndex) const;    // these are mutable
00421     Vector& updUDot(SubsystemIndex) const;
00422     Vector& updZDot(SubsystemIndex) const;
00423     Vector& updQDotDot(SubsystemIndex) const;
00424 
00425     const Vector& getQErr(SubsystemIndex) const;
00426     const Vector& getUErr(SubsystemIndex) const;
00427     const Vector& getUDotErr(SubsystemIndex) const;
00428     const Vector& getMultipliers(SubsystemIndex) const;
00429     Vector& updQErr(SubsystemIndex) const;    // these are mutable
00430     Vector& updUErr(SubsystemIndex) const;
00431     Vector& updUDotErr(SubsystemIndex) const;
00432     Vector& updMultipliers(SubsystemIndex) const;
00433 
00435     const Real&   getTime() const;
00436     const Vector& getY() const; // {Q,U,Z} packed and in that order
00437 
00439     const Vector& getQ() const;
00440     const Vector& getU() const;
00441     const Vector& getZ() const;
00442 
00445     Real&   updTime();  // Back up to Stage::Time-1
00446     Vector& updY();     // Back up to Stage::Congfigured-1
00447 
00449     void setTime(Real t);
00450     void setY(const Vector& y);
00451 
00453     Vector& updQ();     // Back up to Stage::Position-1
00454     Vector& updU();     // Back up to Stage::Velocity-1
00455     Vector& updZ();     // Back up to Stage::Dynamics-1
00456 
00458     void setQ(const Vector& q);
00459     void setU(const Vector& u);
00460     void setZ(const Vector& z);
00461 
00462     const Vector& getYDot()    const; // Stage::Acceleration
00463 
00465     const Vector& getQDot()    const; // Stage::Velocity
00466     const Vector& getZDot()    const; // Stage::Dynamics
00467     const Vector& getUDot()    const; // Stage::Acceleration
00468 
00470     const Vector& getQDotDot() const; // Stage::Acceleration
00471 
00473     Vector& updYDot() const;    // Stage::Acceleration-1
00474     Vector& updQDot() const;    // Stage::Velocity-1     (view into YDot)
00475     Vector& updZDot() const;    // Stage::Dynamics-1            "
00476     Vector& updUDot() const;    // Stage::Acceleration-1        "
00477 
00481     Vector& updQDotDot() const; // Stage::Acceleration-1
00482 
00484     const Vector& getYErr() const; // {QErr,UErr} packed and in that order
00485 
00487     const Vector& getQErr() const;  // Stage::Position (index 3 constraints)
00488     const Vector& getUErr() const;  // Stage::Velocity (index 2 constraints)
00489 
00491     const Vector& getUDotErr()     const; // Stage::Acceleration (index 1 constraints)
00492     const Vector& getMultipliers() const; // Stage::Acceleration
00493 
00495     Vector& updYErr() const; // Stage::Dynamics-1
00496     Vector& updQErr() const; // Stage::Position-1 (view into YErr)
00497     Vector& updUErr() const; // Stage::Velocity-1        "
00498 
00499     Vector& updUDotErr()     const; // Stage::Acceleration-1 (not a view)
00500     Vector& updMultipliers() const; // Stage::Acceleration-1 (not a view)
00501 
00503     const AbstractValue& getDiscreteVariable(SubsystemIndex, int index) const;
00504 
00506     AbstractValue&       updDiscreteVariable(SubsystemIndex, int index);
00507 
00509     void setDiscreteVariable(SubsystemIndex i, int index, const AbstractValue& v);
00510 
00512     const AbstractValue& getCacheEntry(SubsystemIndex, int index) const;
00513 
00515     AbstractValue& updCacheEntry(SubsystemIndex, int index) const; // mutable
00516     
00527     void createRestrictedState(State& restrictedState, EnumerationSet<Stage> restrictedStages, std::set<SubsystemIndex> restrictedSubsystems);
00528 
00531     EnumerationSet<Stage> getRestrictedStages() const;
00532 
00535     std::set<SubsystemIndex> getRestrictedSubsystems() const;
00536 
00537     String toString() const;
00538     String cacheToString() const;
00539 
00540 private:
00541     class StateRep* rep;
00542     const StateRep& getRep() const {assert(rep); return *rep;}
00543     StateRep&       updRep()       {assert(rep); return *rep;}
00544 };
00545 
00546 SimTK_SimTKCOMMON_EXPORT std::ostream& 
00547 operator<<(std::ostream& o, const State& s);
00548 
00549 } // namespace SimTK
00550 
00551 #endif // SimTK_SimTKCOMMON_STATE_H_

Generated on Thu Feb 28 01:34:32 2008 for SimTKcommon by  doxygen 1.4.7