Simbody
3.4 (development)
|
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_