Simbody  3.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SubsystemGuts.h
Go to the documentation of this file.
1 #ifndef SimTK_SimTKCOMMON_SUBSYSTEM_GUTS_H_
2 #define SimTK_SimTKCOMMON_SUBSYSTEM_GUTS_H_
3 
4 /* -------------------------------------------------------------------------- *
5  * Simbody(tm): SimTKcommon *
6  * -------------------------------------------------------------------------- *
7  * This is part of the SimTK biosimulation toolkit originating from *
8  * Simbios, the NIH National Center for Physics-Based Simulation of *
9  * Biological Structures at Stanford, funded under the NIH Roadmap for *
10  * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
11  * *
12  * Portions copyright (c) 2006-12 Stanford University and the Authors. *
13  * Authors: Michael Sherman *
14  * Contributors: *
15  * *
16  * Licensed under the Apache License, Version 2.0 (the "License"); you may *
17  * not use this file except in compliance with the License. You may obtain a *
18  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
19  * *
20  * Unless required by applicable law or agreed to in writing, software *
21  * distributed under the License is distributed on an "AS IS" BASIS, *
22  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
23  * See the License for the specific language governing permissions and *
24  * limitations under the License. *
25  * -------------------------------------------------------------------------- */
26 
27 #include "SimTKcommon/basics.h"
28 #include "SimTKcommon/Simmatrix.h"
30 
31 #include <cassert>
32 
33 namespace SimTK {
34 
35 class System;
36 class DecorativeGeometry;
37 
38 
43 public:
44  Guts(const Guts&);
45  Guts& operator=(const Guts&);
46 
47  // This constructor is for use by concrete Subsystems. Note that this
48  // serves as a default constructor since both arguments have defaults.
49  explicit Guts(const String& name="<NONAME>",
50  const String& version="0.0.0");
51  virtual ~Guts();
52 
53  const String& getName() const;
54  const String& getVersion() const;
55 
56  // Use these to allocate state variables and cache entries that are owned
57  // by this Subsystem.
58 
59  // qdot, qdotdot also allocated in cache
60  QIndex allocateQ(State& s, const Vector& qInit) const;
61  // udot is also allocated in the cache
62  UIndex allocateU(State& s, const Vector& uInit) const;
63  // zdot is also allocated in the cache
64  ZIndex allocateZ(State& s, const Vector& zInit) const;
65 
66  DiscreteVariableIndex allocateDiscreteVariable
67  (State& s, Stage g, AbstractValue* v) const;
68  DiscreteVariableIndex allocateAutoUpdateDiscreteVariable
69  (State&, Stage invalidates, AbstractValue* v, Stage updateDependsOn) const;
70 
71  // Cache entries
72  CacheEntryIndex allocateCacheEntry
73  (const State&, Stage dependsOn, Stage computedBy, AbstractValue* v) const;
74  CacheEntryIndex allocateCacheEntry
75  (const State& state, Stage g, AbstractValue* v) const
76  { return allocateCacheEntry(state, g, g, v); }
77  CacheEntryIndex allocateLazyCacheEntry
78  (const State& state, Stage earliest, AbstractValue* v) const
79  { return allocateCacheEntry(state, earliest, Stage::Infinity, v); }
80 
81  // qerr, uerr, udoterr are all cache entries, not variables
82  // allocating udoterr also allocates matching multipliers
83  QErrIndex allocateQErr(const State& s, int nqerr) const;
84  UErrIndex allocateUErr(const State& s, int nuerr) const;
85  UDotErrIndex allocateUDotErr(const State& s, int nudoterr) const;
86  EventTriggerByStageIndex allocateEventTriggersByStage
87  (const State&, Stage, int ntriggers) const;
88 
89  // These return views on State shared global resources. The views
90  // are private to this subsystem, but the global resources themselves
91  // are not allocated until the *System* advances to stage Model.
92  // Note that there is no subsystem equivalent of the State's "y"
93  // vector because in general a subsystem's state variables will
94  // not be contiguous. However, a subsystem's q's, u's, and z's
95  // will all be contiguous within those arrays.
96  const Vector& getQ(const State&) const;
97  const Vector& getU(const State&) const;
98  const Vector& getZ(const State&) const;
99  const Vector& getUWeights(const State&) const;
100  const Vector& getZWeights(const State&) const;
101 
102  const Vector& getQDot(const State&) const;
103  const Vector& getUDot(const State&) const;
104  const Vector& getZDot(const State&) const;
105  const Vector& getQDotDot(const State&) const;
106 
107  const Vector& getQErr(const State&) const;
108  const Vector& getUErr(const State&) const;
109  const Vector& getQErrWeights(const State&) const;
110  const Vector& getUErrWeights(const State&) const;
111 
112  const Vector& getUDotErr(const State&) const;
113  const Vector& getMultipliers(const State&) const;
114  const Vector& getEventTriggersByStage(const State&, Stage) const;
115 
116  // These return writable access to this subsystem's partition in the
117  // State pool of continuous variables. These can be called at Stage::Model
118  // or higher, and if necesary they invalidate the Position (q), Velocity (u),
119  // or Dynamics (z) stage respectively.
120  Vector& updQ(State&) const; // invalidates Stage::Position
121  Vector& updU(State&) const; // invalidates Stage::Velocity
122  Vector& updZ(State&) const; // invalidates Stage::Dynamics
123 
124  // For convenience.
125  void setQ(State& s, const Vector& q) const {
126  assert(q.size() == getNQ(s));
127  updQ(s) = q;
128  }
129  void setU(State& s, const Vector& u) const {
130  assert(u.size() == getNU(s));
131  updU(s) = u;
132  }
133  void setZ(State& s, const Vector& z) const {
134  assert(z.size() == getNZ(s));
135  updZ(s) = z;
136  }
137 
138  // These update the State cache which is mutable; hence, const State. They
139  // can be called only if the previous stage has already been realized, e.g.,
140  // updQDot() is allowed only while realizing the Velocity stage, requiring
141  // that Position stage has already been realized.
142  Vector& updQDot(const State&) const;
143  Vector& updUDot(const State&) const;
144  Vector& updZDot(const State&) const;
145  Vector& updQDotDot(const State&) const;
146  Vector& updQErr(const State&) const;
147  Vector& updUErr(const State&) const;
148  Vector& updUDotErr(const State&) const;
149  Vector& updMultipliers(const State&) const;
150  Vector& updEventTriggersByStage(const State&, Stage) const;
151 
152  // These pull out the State entries which belong exclusively to
153  // this Subsystem. These variables and cache entries are available
154  // as soon as this subsystem is at stage Model.
155  Stage getStage(const State&) const;
156  const AbstractValue& getDiscreteVariable(const State&, DiscreteVariableIndex) const;
157 
159  { return s.getDiscreteVarLastUpdateTime(getMySubsystemIndex(),dx); }
161  { return s.getDiscreteVarUpdateIndex(getMySubsystemIndex(),dx); }
163  { return s.getDiscreteVarUpdateValue(getMySubsystemIndex(),dx); }
165  { return s.updDiscreteVarUpdateValue(getMySubsystemIndex(),dx); }
167  { return s.isDiscreteVarUpdateValueRealized(getMySubsystemIndex(),dx); }
169  { return s.markDiscreteVarUpdateValueRealized(getMySubsystemIndex(),dx); }
170 
171  // State is *not* mutable here -- must have write access to change state variables.
172  AbstractValue& updDiscreteVariable(State&, DiscreteVariableIndex) const;
173  const AbstractValue& getCacheEntry(const State&, CacheEntryIndex) const;
174  // State is mutable here.
175  AbstractValue& updCacheEntry(const State&, CacheEntryIndex) const;
176 
177  bool isCacheValueRealized(const State&, CacheEntryIndex) const;
178  void markCacheValueRealized(const State&, CacheEntryIndex) const;
179  void markCacheValueNotRealized(const State&, CacheEntryIndex) const;
180 
181  // Dimensions. These are valid at System Stage::Model while access to the various
182  // arrays may have stricter requirements. Hence it is better to use these
183  // routines than to get a reference to a Vector above and ask for its size().
184 
185  SystemQIndex getQStart (const State&) const;
186  int getNQ (const State&) const;
187  SystemUIndex getUStart (const State&) const;
188  int getNU (const State&) const;
189  SystemZIndex getZStart (const State&) const;
190  int getNZ (const State&) const;
191  SystemQErrIndex getQErrStart (const State&) const;
192  int getNQErr (const State&) const;
193  SystemUErrIndex getUErrStart (const State&) const;
194  int getNUErr (const State&) const;
195  SystemUDotErrIndex getUDotErrStart(const State&) const;
196  int getNUDotErr (const State&) const;
197  SystemMultiplierIndex getMultipliersStart(const State&) const;
198  int getNMultipliers(const State&) const;
200  getEventTriggerStartByStage(const State&, Stage) const;
201  int getNEventTriggersByStage(const State&, Stage) const;
202 
203  MeasureIndex adoptMeasure(AbstractMeasure& m);
204  AbstractMeasure getMeasure(MeasureIndex) const;
205  template <class T> Measure_<T> getMeasure_(MeasureIndex mx) const
206  { return Measure_<T>::getAs(getMeasure(mx));}
207 
208  bool isInSystem() const;
209  bool isInSameSystem(const Subsystem& otherSubsystem) const;
210 
211  const System& getSystem() const;
212  System& updSystem();
213 
214  SubsystemIndex getMySubsystemIndex() const;
215 
216  // Internal use only
217  const Subsystem& getOwnerSubsystemHandle() const;
218  Subsystem& updOwnerSubsystemHandle();
219  void setOwnerSubsystemHandle(Subsystem&);
220  bool hasOwnerSubsystemHandle() const;
221 
222  void setSystem(System&, SubsystemIndex);
223 
224  class GutsRep;
225  explicit Guts(GutsRep* r) : rep(r) { }
226  bool hasRep() const {return rep!=0;}
227  const GutsRep& getRep() const {assert(rep); return *rep;}
228  GutsRep& updRep() const {assert(rep); return *rep;}
229  void setRep(GutsRep& r) {assert(!rep); rep = &r;}
230 
231  bool subsystemTopologyHasBeenRealized() const;
232  void invalidateSubsystemTopologyCache() const;
233 
234  // These are wrappers for the virtual methods defined below. They
235  // are used to ensure good behavior. Most of them deal automatically with
236  // the Subsystem's Measures, as well as invoking the corresponding virtual
237  // for the Subsystem's own processing.
238 
239  Subsystem::Guts* clone() const;
240 
241  // Realize this subsystem's part of the State from Stage-1 to Stage
242  // for the indicated stage. After doing some checking, these routines
243  // call the concrete subsystem's corresponding virtual method, and
244  // on return they make sure the stage has been properly updated.
245  // Note that these will do nothing if the Subsystem stage is already
246  // at or greater than the indicated stage.
247  void realizeSubsystemTopology (State&) const;
248  void realizeSubsystemModel (State&) const;
249  void realizeSubsystemInstance (const State&) const;
250  void realizeSubsystemTime (const State&) const;
251  void realizeSubsystemPosition (const State&) const;
252  void realizeSubsystemVelocity (const State&) const;
253  void realizeSubsystemDynamics (const State&) const;
254  void realizeSubsystemAcceleration(const State&) const;
255  void realizeSubsystemReport (const State&) const;
256 
257  // Generate decorative geometry computable at a specific stage. This will
258  // throw an exception if this subsystem's state hasn't already been realized
259  // to that stage. Note that the list is not inclusive -- you have to
260  // request geometry from each stage to get all of it.
261  // The generated geometry will be *appended* to the supplied output vector.
262  void calcDecorativeGeometryAndAppend
263  (const State&, Stage, Array_<DecorativeGeometry>&) const;
264 
265  void createScheduledEvent(const State& state, EventId& eventId) const;
266  void createTriggeredEvent(const State& state, EventId& eventId,
267  EventTriggerByStageIndex& triggerFunctionIndex,
268  Stage stage) const;
269 
270  // These methods are called by the corresponding methods of System.
271  // Each subsystem is responsible for defining its own events, and
272  // System then combines the information from them, and dispatches events
273  // to the appropriate subsystems for handling when they occur.
274  void calcEventTriggerInfo
275  (const State&, Array_<EventTriggerInfo>&) const;
276  void calcTimeOfNextScheduledEvent
277  (const State&, Real& tNextEvent, Array_<EventId>& eventIds,
278  bool includeCurrentTime) const;
279  void calcTimeOfNextScheduledReport
280  (const State&, Real& tNextEvent, Array_<EventId>& eventIds,
281  bool includeCurrentTime) const;
282  void handleEvents
283  (State&, Event::Cause, const Array_<EventId>& eventIds,
284  const HandleEventsOptions& options, HandleEventsResults& results) const;
285  void reportEvents
286  (const State&, Event::Cause, const Array_<EventId>& eventIds) const;
287 
288 protected:
289  // These virtual methods should be overridden in concrete Subsystems as
290  // necessary. They should never be called directly; instead call the
291  // wrapper routines above, which have the same name but without the "Impl"
292  // (implementation) at the end.
293 
294  // The "realize..." wrappers will call the "realize...Impl" methods below
295  // only when the current stage for the Subsystem is the one just prior
296  // to the stage being realized. For example, realizeSubsystemVelocityImpl()
297  // is called by realizeSubsystemVelocity() only when the passed-in State
298  // shows this subsystem's stage to be exactly Stage::Position.
299  //
300  // The default implementations provided here do nothing. That means the
301  // wrappers will simply check that the current stage is correct and
302  // advance it if necessary.
303 
304  // The destructor is already virtual; see above.
305 
306  virtual Subsystem::Guts* cloneImpl() const = 0;
307 
308  virtual int realizeSubsystemTopologyImpl(State& s) const {return 0;}
309  virtual int realizeSubsystemModelImpl (State& s) const {return 0;}
310  virtual int realizeSubsystemInstanceImpl(const State& s) const {return 0;}
311  virtual int realizeSubsystemTimeImpl (const State& s) const {return 0;}
312  virtual int realizeSubsystemPositionImpl(const State& s) const {return 0;}
313  virtual int realizeSubsystemVelocityImpl(const State& s) const {return 0;}
314  virtual int realizeSubsystemDynamicsImpl(const State& s) const {return 0;}
315  virtual int realizeSubsystemAccelerationImpl(const State& s)const{return 0;}
316  virtual int realizeSubsystemReportImpl (const State& s) const {return 0;}
317 
318  virtual int calcDecorativeGeometryAndAppendImpl
319  (const State&, Stage, Array_<DecorativeGeometry>&) const {return 0;}
320 
321  virtual void calcEventTriggerInfoImpl
322  (const State&, Array_<EventTriggerInfo>&) const {}
323  virtual void calcTimeOfNextScheduledEventImpl
324  (const State&, Real& tNextEvent, Array_<EventId>& eventIds,
325  bool includeCurrentTime) const {}
326  virtual void calcTimeOfNextScheduledReportImpl
327  (const State&, Real& tNextEvent, Array_<EventId>& eventIds,
328  bool includeCurrentTime) const {}
329  virtual void handleEventsImpl
330  (State&, Event::Cause, const Array_<EventId>& eventIds,
331  const HandleEventsOptions& options,
332  HandleEventsResults& results) const {}
333  virtual void reportEventsImpl
334  (const State&, Event::Cause, const Array_<EventId>& eventIds) const {}
335 
336 protected:
337  void advanceToStage(const State& s, Stage g) const;
338 
339 private:
340  // this is the only data member in the base class
341  GutsRep* rep; // opaque implementation of Subsystem::Guts base class.
342 
343 friend class GutsRep;
344 };
345 
346 } // namespace SimTK
347 
348 #endif // SimTK_SimTKCOMMON_SUBSYSTEM_GUTS_H_
AbstractValue & updDiscreteVarUpdateValue(SubsystemIndex, DiscreteVariableIndex) const
For an auto-updating discrete variable, return a writable reference to the value of its associated up...
The abstract parent of all Subsystems.
Definition: Subsystem.h:61
#define SimTK_SimTKCOMMON_EXPORT
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:202
Unique integer type for Subsystem-local uDotErr indexing.
bool isDiscreteVarUpdateValueRealized(SubsystemIndex, DiscreteVariableIndex) const
Check whether the update value for this auto-update discrete variable has already been computed since...
bool hasRep() const
Definition: SubsystemGuts.h:226
Unique integer type for Subsystem-local u indexing.
virtual int realizeSubsystemModelImpl(State &s) const
Definition: SubsystemGuts.h:309
Measure_< T > getMeasure_(MeasureIndex mx) const
Definition: SubsystemGuts.h:205
Unique integer type for Subsystem-local uErr indexing.
Real getDiscreteVarLastUpdateTime(SubsystemIndex, DiscreteVariableIndex) const
Return the time of last update for this discrete variable.
Unique integer type for Subsystem-local qErr indexing.
This class is basically a glorified enumerated type, type-safe and range checked but permitting conve...
Definition: Stage.h:50
void setRep(GutsRep &r)
Definition: SubsystemGuts.h:229
int size() const
Definition: BigMatrix.h:1411
Guts(GutsRep *r)
Definition: SubsystemGuts.h:225
CacheEntryIndex getDiscreteVarUpdateIndex(SubsystemIndex, DiscreteVariableIndex) const
For an auto-updating discrete variable, return the CacheEntryIndex for its associated update cache en...
virtual int realizeSubsystemPositionImpl(const State &s) const
Definition: SubsystemGuts.h:312
This is the base class for all Measure handle classes.
Definition: Measure.h:151
This unique integer type is for indexing global "multiplier-like" arrays, that is, arrays that inherently have the same dimension as the total number of Lagrange multipliers in the full System-level view of the State.
This is the handle class for the hidden State implementation.
Definition: State.h:264
void setU(State &s, const Vector &u) const
Definition: SubsystemGuts.h:129
const GutsRep & getRep() const
Definition: SubsystemGuts.h:227
These are all the possible causes for events.
Definition: Event.h:123
const AbstractValue & getDiscreteVarUpdateValue(const State &s, DiscreteVariableIndex dx) const
Definition: SubsystemGuts.h:162
virtual int realizeSubsystemDynamicsImpl(const State &s) const
Definition: SubsystemGuts.h:314
The SimTK::Array_<T> container class is a plug-compatible replacement for the C++ standard template l...
Definition: Array.h:50
This unique integer type is for indexing global "q-like" arrays, that is, arrays that inherently have...
This unique integer type is for indexing global "qErr-like" arrays, that is, arrays that inherently h...
Unique integer type for Subsystem-local z indexing.
This unique integer type is for indexing global "uErr-like" arrays, that is, arrays that inherently h...
AbstractValue & updDiscreteVarUpdateValue(const State &s, DiscreteVariableIndex dx) const
Definition: SubsystemGuts.h:164
void setZ(State &s, const Vector &z) const
Definition: SubsystemGuts.h:133
Unique integer type for Subsystem-local q indexing.
The abstract parent of all Subsystem "Guts" implementation classes.
Definition: SubsystemGuts.h:42
virtual int realizeSubsystemTimeImpl(const State &s) const
Definition: SubsystemGuts.h:311
Higher than any legitimate Stage.
Definition: Stage.h:63
virtual int realizeSubsystemReportImpl(const State &s) const
Definition: SubsystemGuts.h:316
void markDiscreteVarUpdateValueRealized(const State &s, DiscreteVariableIndex dx) const
Definition: SubsystemGuts.h:168
This unique integer type is for identifying a triggered event within a particular Stage of the full S...
virtual int realizeSubsystemTopologyImpl(State &s) const
Definition: SubsystemGuts.h:308
GutsRep & updRep() const
Definition: SubsystemGuts.h:228
bool isDiscreteVarUpdateValueRealized(const State &s, DiscreteVariableIndex dx) const
Definition: SubsystemGuts.h:166
virtual int realizeSubsystemVelocityImpl(const State &s) const
Definition: SubsystemGuts.h:313
SimTK::String is a plug-compatible std::string replacement (plus some additional functionality) inten...
Definition: String.h:62
virtual int realizeSubsystemInstanceImpl(const State &s) const
Definition: SubsystemGuts.h:310
void setQ(State &s, const Vector &q) const
Definition: SubsystemGuts.h:125
Abstract base class representing an arbitrary value of self-describing type.
Definition: Value.h:41
This unique integer type is for indexing global "uDotErr-like" arrays, that is, arrays that inherentl...
This unique integer type is for selecting discrete variables.
This unique integer type is for indexing global "z-like" arrays, that is, arrays that inherently have...
const AbstractValue & getDiscreteVarUpdateValue(SubsystemIndex, DiscreteVariableIndex) const
For an auto-updating discrete variable, return the current value of its associated update cache entry...
This is the base class that serves as the parent of all SimTK System objects; most commonly Simbody's...
Definition: System.h:96
CacheEntryIndex getDiscreteVarUpdateIndex(const State &s, DiscreteVariableIndex dx) const
Definition: SubsystemGuts.h:160
Provide a unique integer type for identifying Subsystems.
This unique integer type is for selecting non-shared cache entries.
Real getDiscreteVarLastUpdateTime(const State &s, DiscreteVariableIndex dx) const
Definition: SubsystemGuts.h:158
Results returned by the handleEvent() method.
Definition: Event.h:341
This is the header which should be included in user programs that would like to make use of all the S...
virtual int realizeSubsystemAccelerationImpl(const State &s) const
Definition: SubsystemGuts.h:315
Unique integer type for Subsystem-local, per-stage event indexing.
This unique integer type is for indexing global "u-like" arrays, that is, arrays that inherently have...
void markDiscreteVarUpdateValueRealized(SubsystemIndex, DiscreteVariableIndex) const
Mark the update value for this auto-update discrete variable as up-to-date with respect to the state ...
Includes internal headers providing declarations for the basic SimTK Core classes.
Options for the handleEvent() method.
Definition: Event.h:265
This is the base handle class for all Measures whose value type is known, including all the Simbody b...
Definition: Measure.h:261
This is a class to represent unique IDs for events in a type-safe way.