Simbody  3.4 (development)
SubsystemGuts.h
Go to the documentation of this file.
00001 #ifndef SimTK_SimTKCOMMON_SUBSYSTEM_GUTS_H_
00002 #define SimTK_SimTKCOMMON_SUBSYSTEM_GUTS_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                       Simbody(tm): SimTKcommon                             *
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) 2006-12 Stanford University and the Authors.        *
00013  * Authors: Michael Sherman                                                   *
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 "SimTKcommon/basics.h"
00028 #include "SimTKcommon/Simmatrix.h"
00029 #include "SimTKcommon/internal/State.h"
00030 
00031 #include <cassert>
00032 
00033 namespace SimTK {
00034 
00035 class System;
00036 class DecorativeGeometry;
00037 
00038 
00042 class SimTK_SimTKCOMMON_EXPORT Subsystem::Guts {
00043 public:
00044     Guts(const Guts&);
00045     Guts& operator=(const Guts&);
00046 
00047     // This constructor is for use by concrete Subsystems. Note that this
00048     // serves as a default constructor since both arguments have defaults.
00049     explicit Guts(const String& name="<NONAME>", 
00050                   const String& version="0.0.0");
00051     virtual ~Guts();
00052 
00053     const String& getName()    const;
00054     const String& getVersion() const;
00055 
00056     // Use these to allocate state variables and cache entries that are owned
00057     // by this Subsystem.
00058 
00059     // qdot, qdotdot also allocated in cache
00060     QIndex allocateQ(State& s, const Vector& qInit) const;
00061     // udot is also allocated in the cache
00062     UIndex allocateU(State& s, const Vector& uInit) const;
00063     // zdot is also allocated in the cache
00064     ZIndex allocateZ(State& s, const Vector& zInit) const;
00065 
00066     DiscreteVariableIndex allocateDiscreteVariable
00067        (State& s, Stage g, AbstractValue* v) const;
00068     DiscreteVariableIndex allocateAutoUpdateDiscreteVariable
00069        (State&, Stage invalidates, AbstractValue* v, Stage updateDependsOn) const; 
00070 
00071     // Cache entries
00072     CacheEntryIndex allocateCacheEntry
00073        (const State&, Stage dependsOn, Stage computedBy, AbstractValue* v) const;
00074     CacheEntryIndex allocateCacheEntry
00075        (const State& state, Stage g, AbstractValue* v) const 
00076     {   return allocateCacheEntry(state, g, g, v); }
00077     CacheEntryIndex allocateLazyCacheEntry   
00078        (const State& state, Stage earliest, AbstractValue* v) const 
00079     {   return allocateCacheEntry(state, earliest, Stage::Infinity, v); }
00080 
00081     // qerr, uerr, udoterr are all cache entries, not variables
00082     // allocating udoterr also allocates matching multipliers
00083     QErrIndex allocateQErr(const State& s, int nqerr) const;
00084     UErrIndex allocateUErr(const State& s, int nuerr) const;
00085     UDotErrIndex allocateUDotErr(const State& s, int nudoterr) const;
00086     EventTriggerByStageIndex allocateEventTriggersByStage
00087        (const State&, Stage, int ntriggers) const;
00088 
00089     // These return views on State shared global resources. The views
00090     // are private to this subsystem, but the global resources themselves
00091     // are not allocated until the *System* advances to stage Model.
00092     // Note that there is no subsystem equivalent of the State's "y"
00093     // vector because in general a subsystem's state variables will
00094     // not be contiguous. However, a subsystem's q's, u's, and z's
00095     // will all be contiguous within those arrays.
00096     const Vector& getQ(const State&) const;
00097     const Vector& getU(const State&) const;
00098     const Vector& getZ(const State&) const;
00099     const Vector& getUWeights(const State&) const;
00100     const Vector& getZWeights(const State&) const;
00101 
00102     const Vector& getQDot(const State&) const;
00103     const Vector& getUDot(const State&) const;
00104     const Vector& getZDot(const State&) const;
00105     const Vector& getQDotDot(const State&) const;
00106 
00107     const Vector& getQErr(const State&) const;
00108     const Vector& getUErr(const State&) const;
00109     const Vector& getQErrWeights(const State&) const;
00110     const Vector& getUErrWeights(const State&) const;
00111 
00112     const Vector& getUDotErr(const State&) const;
00113     const Vector& getMultipliers(const State&) const;
00114     const Vector& getEventTriggersByStage(const State&, Stage) const;
00115 
00116     // These return writable access to this subsystem's partition in the
00117     // State pool of continuous variables. These can be called at Stage::Model
00118     // or higher, and if necesary they invalidate the Position (q), Velocity (u),
00119     // or Dynamics (z) stage respectively.
00120     Vector& updQ(State&) const; // invalidates Stage::Position
00121     Vector& updU(State&) const; // invalidates Stage::Velocity
00122     Vector& updZ(State&) const; // invalidates Stage::Dynamics
00123 
00124     // For convenience.
00125     void setQ(State& s, const Vector& q) const {
00126         assert(q.size() == getNQ(s));
00127         updQ(s) = q;
00128     }
00129     void setU(State& s, const Vector& u) const {
00130         assert(u.size() == getNU(s));
00131         updU(s) = u;
00132     }
00133     void setZ(State& s, const Vector& z) const {
00134         assert(z.size() == getNZ(s));
00135         updZ(s) = z;
00136     }
00137 
00138     // These update the State cache which is mutable; hence, const State. They
00139     // can be called only if the previous stage has already been realized, e.g.,
00140     // updQDot() is allowed only while realizing the Velocity stage, requiring
00141     // that Position stage has already been realized.
00142     Vector& updQDot(const State&) const;
00143     Vector& updUDot(const State&) const;
00144     Vector& updZDot(const State&) const;
00145     Vector& updQDotDot(const State&) const;
00146     Vector& updQErr(const State&) const;
00147     Vector& updUErr(const State&) const;
00148     Vector& updUDotErr(const State&) const;
00149     Vector& updMultipliers(const State&) const;
00150     Vector& updEventTriggersByStage(const State&, Stage) const;
00151 
00152     // These pull out the State entries which belong exclusively to
00153     // this Subsystem. These variables and cache entries are available
00154     // as soon as this subsystem is at stage Model.
00155     Stage getStage(const State&) const;
00156     const AbstractValue& getDiscreteVariable(const State&, DiscreteVariableIndex) const;
00157 
00158     Real getDiscreteVarLastUpdateTime(const State& s, DiscreteVariableIndex dx) const
00159     {   return s.getDiscreteVarLastUpdateTime(getMySubsystemIndex(),dx); }
00160     CacheEntryIndex getDiscreteVarUpdateIndex(const State& s, DiscreteVariableIndex dx) const
00161     {   return s.getDiscreteVarUpdateIndex(getMySubsystemIndex(),dx); }
00162     const AbstractValue& getDiscreteVarUpdateValue(const State& s, DiscreteVariableIndex dx) const
00163     {   return s.getDiscreteVarUpdateValue(getMySubsystemIndex(),dx); }
00164     AbstractValue& updDiscreteVarUpdateValue(const State& s, DiscreteVariableIndex dx) const
00165     {   return s.updDiscreteVarUpdateValue(getMySubsystemIndex(),dx); }
00166     bool isDiscreteVarUpdateValueRealized(const State& s, DiscreteVariableIndex dx) const
00167     {   return s.isDiscreteVarUpdateValueRealized(getMySubsystemIndex(),dx); }
00168     void markDiscreteVarUpdateValueRealized(const State& s, DiscreteVariableIndex dx) const
00169     {   return s.markDiscreteVarUpdateValueRealized(getMySubsystemIndex(),dx); }
00170 
00171     // State is *not* mutable here -- must have write access to change state variables.
00172     AbstractValue& updDiscreteVariable(State&, DiscreteVariableIndex) const;
00173     const AbstractValue& getCacheEntry(const State&, CacheEntryIndex) const;
00174     // State is mutable here.
00175     AbstractValue& updCacheEntry(const State&, CacheEntryIndex) const;
00176 
00177     bool isCacheValueRealized(const State&, CacheEntryIndex) const;
00178     void markCacheValueRealized(const State&, CacheEntryIndex) const;
00179     void markCacheValueNotRealized(const State&, CacheEntryIndex) const;
00180 
00181     // Dimensions. These are valid at System Stage::Model while access to the various
00182     // arrays may have stricter requirements. Hence it is better to use these
00183     // routines than to get a reference to a Vector above and ask for its size().
00184 
00185     SystemQIndex getQStart      (const State&) const;
00186     int getNQ          (const State&) const;
00187     SystemUIndex getUStart      (const State&) const;
00188     int getNU          (const State&) const;
00189     SystemZIndex getZStart      (const State&) const;
00190     int getNZ          (const State&) const;
00191     SystemQErrIndex getQErrStart   (const State&) const;
00192     int getNQErr       (const State&) const;
00193     SystemUErrIndex getUErrStart   (const State&) const;
00194     int getNUErr       (const State&) const;
00195     SystemUDotErrIndex getUDotErrStart(const State&) const;
00196     int getNUDotErr    (const State&) const;
00197     SystemMultiplierIndex getMultipliersStart(const State&) const;
00198     int getNMultipliers(const State&) const;
00199     SystemEventTriggerByStageIndex 
00200         getEventTriggerStartByStage(const State&, Stage) const;
00201     int getNEventTriggersByStage(const State&, Stage) const;
00202 
00203     MeasureIndex adoptMeasure(AbstractMeasure& m);
00204     AbstractMeasure getMeasure(MeasureIndex) const;
00205     template <class T> Measure_<T> getMeasure_(MeasureIndex mx) const
00206     {   return Measure_<T>::getAs(getMeasure(mx));}
00207 
00208     bool isInSystem() const;
00209     bool isInSameSystem(const Subsystem& otherSubsystem) const;
00210 
00211     const System& getSystem() const;
00212     System&       updSystem();
00213 
00214     SubsystemIndex getMySubsystemIndex() const;
00215 
00216     // Internal use only
00217     const Subsystem& getOwnerSubsystemHandle() const;
00218     Subsystem& updOwnerSubsystemHandle();
00219     void setOwnerSubsystemHandle(Subsystem&);
00220     bool hasOwnerSubsystemHandle() const;
00221 
00222     void setSystem(System&, SubsystemIndex);
00223 
00224     class GutsRep;
00225     explicit Guts(GutsRep* r) : rep(r) { }
00226     bool           hasRep() const {return rep!=0;}
00227     const GutsRep& getRep() const {assert(rep); return *rep;}
00228     GutsRep&       updRep() const {assert(rep); return *rep;}
00229     void setRep(GutsRep& r) {assert(!rep); rep = &r;}
00230 
00231     bool subsystemTopologyHasBeenRealized() const;
00232     void invalidateSubsystemTopologyCache() const;
00233 
00234     // These are wrappers for the virtual methods defined below. They
00235     // are used to ensure good behavior. Most of them deal automatically with
00236     // the Subsystem's Measures, as well as invoking the corresponding virtual
00237     // for the Subsystem's own processing.
00238 
00239     Subsystem::Guts* clone() const;
00240 
00241     // Realize this subsystem's part of the State from Stage-1 to Stage
00242     // for the indicated stage. After doing some checking, these routines
00243     // call the concrete subsystem's corresponding virtual method, and
00244     // on return they make sure the stage has been properly updated.
00245     // Note that these will do nothing if the Subsystem stage is already
00246     // at or greater than the indicated stage.
00247     void realizeSubsystemTopology    (State&) const;
00248     void realizeSubsystemModel       (State&) const;
00249     void realizeSubsystemInstance    (const State&) const;
00250     void realizeSubsystemTime        (const State&) const;
00251     void realizeSubsystemPosition    (const State&) const;
00252     void realizeSubsystemVelocity    (const State&) const;
00253     void realizeSubsystemDynamics    (const State&) const;
00254     void realizeSubsystemAcceleration(const State&) const;
00255     void realizeSubsystemReport      (const State&) const;
00256 
00257     // Generate decorative geometry computable at a specific stage. This will
00258     // throw an exception if this subsystem's state hasn't already been realized
00259     // to that stage. Note that the list is not inclusive -- you have to
00260     // request geometry from each stage to get all of it.
00261     // The generated geometry will be *appended* to the supplied output vector.
00262     void calcDecorativeGeometryAndAppend
00263        (const State&, Stage, Array_<DecorativeGeometry>&) const;
00264     
00265     void createScheduledEvent(const State& state, EventId& eventId) const;
00266     void createTriggeredEvent(const State& state, EventId& eventId, 
00267                               EventTriggerByStageIndex& triggerFunctionIndex,
00268                               Stage stage) const;
00269 
00270     // These methods are called by the corresponding methods of System.
00271     // Each subsystem is responsible for defining its own events, and
00272     // System then combines the information from them, and dispatches events
00273     // to the appropriate subsystems for handling when they occur.
00274     void calcEventTriggerInfo
00275        (const State&, Array_<EventTriggerInfo>&) const;
00276     void calcTimeOfNextScheduledEvent
00277        (const State&, Real& tNextEvent, Array_<EventId>& eventIds, 
00278         bool includeCurrentTime) const;
00279     void calcTimeOfNextScheduledReport
00280        (const State&, Real& tNextEvent, Array_<EventId>& eventIds, 
00281         bool includeCurrentTime) const;
00282     void handleEvents
00283        (State&, Event::Cause, const Array_<EventId>& eventIds,
00284         const HandleEventsOptions& options, HandleEventsResults& results) const;
00285     void reportEvents
00286        (const State&, Event::Cause, const Array_<EventId>& eventIds) const;
00287 
00288 protected:
00289     // These virtual methods should be overridden in concrete Subsystems as
00290     // necessary. They should never be called directly; instead call the
00291     // wrapper routines above, which have the same name but without the "Impl"
00292     // (implementation) at the end.
00293     
00294     // The "realize..." wrappers will call the "realize...Impl" methods below
00295     // only when the current stage for the Subsystem is the one just prior
00296     // to the stage being realized. For example, realizeSubsystemVelocityImpl()
00297     // is called by realizeSubsystemVelocity() only when the passed-in State
00298     // shows this subsystem's stage to be exactly Stage::Position.
00299     //
00300     // The default implementations provided here do nothing. That means the
00301     // wrappers will simply check that the current stage is correct and
00302     // advance it if necessary.
00303 
00304     // The destructor is already virtual; see above.
00305 
00306     virtual Subsystem::Guts* cloneImpl() const = 0;
00307 
00308     virtual int realizeSubsystemTopologyImpl(State& s)       const {return 0;}
00309     virtual int realizeSubsystemModelImpl   (State& s)       const {return 0;}
00310     virtual int realizeSubsystemInstanceImpl(const State& s) const {return 0;}
00311     virtual int realizeSubsystemTimeImpl    (const State& s) const {return 0;}
00312     virtual int realizeSubsystemPositionImpl(const State& s) const {return 0;}
00313     virtual int realizeSubsystemVelocityImpl(const State& s) const {return 0;}
00314     virtual int realizeSubsystemDynamicsImpl(const State& s) const {return 0;}
00315     virtual int realizeSubsystemAccelerationImpl(const State& s)const{return 0;}
00316     virtual int realizeSubsystemReportImpl  (const State& s) const {return 0;}
00317 
00318     virtual int calcDecorativeGeometryAndAppendImpl
00319        (const State&, Stage, Array_<DecorativeGeometry>&) const {return 0;}
00320 
00321     virtual void calcEventTriggerInfoImpl
00322        (const State&, Array_<EventTriggerInfo>&) const {}
00323     virtual void calcTimeOfNextScheduledEventImpl
00324        (const State&, Real& tNextEvent, Array_<EventId>& eventIds, 
00325         bool includeCurrentTime) const {}
00326     virtual void calcTimeOfNextScheduledReportImpl
00327        (const State&, Real& tNextEvent, Array_<EventId>& eventIds, 
00328         bool includeCurrentTime) const {}
00329     virtual void handleEventsImpl
00330        (State&, Event::Cause, const Array_<EventId>& eventIds,
00331         const HandleEventsOptions& options, 
00332         HandleEventsResults& results) const {}
00333     virtual void reportEventsImpl
00334        (const State&, Event::Cause, const Array_<EventId>& eventIds) const {}
00335 
00336 protected:
00337     void advanceToStage(const State& s, Stage g) const;
00338 
00339 private:
00340     // this is the only data member in the base class
00341     GutsRep* rep; // opaque implementation of Subsystem::Guts base class.
00342 
00343 friend class GutsRep;
00344 };
00345 
00346 } // namespace SimTK
00347 
00348 #endif // SimTK_SimTKCOMMON_SUBSYSTEM_GUTS_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines