Simbody  3.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Subsystem.h
Go to the documentation of this file.
1 #ifndef SimTK_SimTKCOMMON_SUBSYSTEM_H_
2 #define SimTK_SimTKCOMMON_SUBSYSTEM_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"
31 
32 #include <cassert>
33 
34 namespace SimTK {
35 
36 class System;
37 
38 
62 public:
63  class Guts; // local; name is Subsystem::Guts
64  friend class Guts;
65 private:
66  // This is the only data member in this class. Also, any class derived from
67  // Subsystem must have *NO* data members at all (data goes in the Guts class).
68  Guts* guts;
69 public:
70  Subsystem() : guts(0) { } // an empty handle
71  Subsystem(const Subsystem&);
72  Subsystem& operator=(const Subsystem&);
73  ~Subsystem();
74 
75  const String& getName() const;
76  const String& getVersion() const;
77 
78  // These call the corresponding State method, supplying this Subsystem's
79  // SubsystemIndex. The returned indices are local to this Subsystem.
80  QIndex allocateQ(State&, const Vector& qInit) const;
81  UIndex allocateU(State&, const Vector& uInit) const;
82  ZIndex allocateZ(State&, const Vector& zInit) const;
83 
84  DiscreteVariableIndex allocateDiscreteVariable
85  (State&, Stage invalidates, AbstractValue* v) const;
86  DiscreteVariableIndex allocateAutoUpdateDiscreteVariable
87  (State&, Stage invalidates, AbstractValue* v, Stage updateDependsOn) const;
88 
89  CacheEntryIndex allocateCacheEntry
90  (const State&, Stage dependsOn, Stage computedBy, AbstractValue* v) const;
91  CacheEntryIndex allocateCacheEntry
92  (const State& state, Stage g, AbstractValue* v) const
93  { return allocateCacheEntry(state, g, g, v); }
94  CacheEntryIndex allocateLazyCacheEntry
95  (const State& state, Stage earliest, AbstractValue* v) const
96  { return allocateCacheEntry(state, earliest, Stage::Infinity, v); }
97 
98  QErrIndex allocateQErr (const State&, int nqerr) const;
99  UErrIndex allocateUErr (const State&, int nuerr) const;
100  UDotErrIndex allocateUDotErr (const State&, int nudoterr) const;
101  EventTriggerByStageIndex allocateEventTriggersByStage
102  (const State&, Stage, int ntriggers) const;
103 
104  // These return views on State shared global resources. The views
105  // are private to this subsystem, but the global resources themselves
106  // are not allocated until the *System* advances to stage Model.
107  // Note that there is no subsystem equivalent of the State's "y"
108  // vector because in general a subsystem's state variables will
109  // not be contiguous. However, a subsystem's q's, u's, and z's
110  // will all be contiguous within those arrays.
111  const Vector& getQ(const State&) const;
112  const Vector& getU(const State&) const;
113  const Vector& getZ(const State&) const;
114  const Vector& getQDot(const State&) const;
115  const Vector& getUDot(const State&) const;
116  const Vector& getZDot(const State&) const;
117  const Vector& getQDotDot(const State&) const;
118  const Vector& getQErr(const State&) const;
119  const Vector& getUErr(const State&) const;
120  const Vector& getUDotErr(const State&) const;
121  const Vector& getMultipliers(const State&) const;
122  const Vector& getEventTriggersByStage(const State&, Stage) const;
123 
124  // These return writable access to this subsystem's partition in the
125  // State pool of continuous variables. These can be called at Stage::Model
126  // or higher, and if necesary they invalidate the Position (q), Velocity (u),
127  // or Dynamics (z) stage respectively.
128  Vector& updQ(State&) const; // invalidates Stage::Position
129  Vector& updU(State&) const; // invalidates Stage::Velocity
130  Vector& updZ(State&) const; // invalidates Stage::Dynamics
131 
132  // For convenience.
133  void setQ(State& s, const Vector& q) const {
134  assert(q.size() == getNQ(s));
135  updQ(s) = q;
136  }
137  void setU(State& s, const Vector& u) const {
138  assert(u.size() == getNU(s));
139  updU(s) = u;
140  }
141  void setZ(State& s, const Vector& z) const {
142  assert(z.size() == getNZ(s));
143  updZ(s) = z;
144  }
145 
146  // These update the State cache which is mutable; hence, const State. They
147  // can be called only if the previous stage has already been realized, e.g.,
148  // updQDot() is allowed only while realizing the Velocity stage, requiring
149  // that Position stage has already been realized.
150  Vector& updQDot(const State&) const;
151  Vector& updUDot(const State&) const;
152  Vector& updZDot(const State&) const;
153  Vector& updQDotDot(const State&) const;
154  Vector& updQErr(const State&) const;
155  Vector& updUErr(const State&) const;
156  Vector& updUDotErr(const State&) const;
157  Vector& updMultipliers(const State&) const;
158  Vector& updEventTriggersByStage(const State&, Stage) const;
159 
160  // These pull out the State entries which belong exclusively to
161  // this Subsystem. These variables and cache entries are available
162  // as soon as this subsystem is at stage Model.
163  Stage getStage(const State&) const;
164  const AbstractValue& getDiscreteVariable(const State& s, DiscreteVariableIndex dx) const;
165 
167  { return s.getDiscreteVarLastUpdateTime(getMySubsystemIndex(),dx); }
169  { return s.getDiscreteVarUpdateIndex(getMySubsystemIndex(),dx); }
171  { return s.getDiscreteVarUpdateValue(getMySubsystemIndex(),dx); }
173  { return s.updDiscreteVarUpdateValue(getMySubsystemIndex(),dx); }
175  { return s.isDiscreteVarUpdateValueRealized(getMySubsystemIndex(),dx); }
177  { return s.markDiscreteVarUpdateValueRealized(getMySubsystemIndex(),dx); }
178 
179  // State is *not* mutable here -- must have write access to change state variables.
180  AbstractValue& updDiscreteVariable(State&, DiscreteVariableIndex) const;
181 
182  const AbstractValue& getCacheEntry(const State&, CacheEntryIndex) const;
183  // State is mutable here.
184  AbstractValue& updCacheEntry(const State&, CacheEntryIndex) const;
185 
186  bool isCacheValueRealized(const State&, CacheEntryIndex) const;
187  void markCacheValueRealized(const State&, CacheEntryIndex) const;
188  void markCacheValueNotRealized(const State&, CacheEntryIndex) const;
189 
190  // Dimensions. These are valid at System Stage::Model while access to the
191  // various arrays may have stricter requirements. Hence it is better to use
192  // these routines than to get a reference to a Vector above and ask for
193  // its size().
194 
195  SystemQIndex getQStart (const State&) const;
196  int getNQ (const State&) const;
197  SystemUIndex getUStart (const State&) const;
198  int getNU (const State&) const;
199  SystemZIndex getZStart (const State&) const;
200  int getNZ (const State&) const;
201  SystemQErrIndex getQErrStart (const State&) const;
202  int getNQErr (const State&) const;
203  SystemUErrIndex getUErrStart (const State&) const;
204  int getNUErr (const State&) const;
205  SystemUDotErrIndex getUDotErrStart(const State&) const;
206  int getNUDotErr (const State&) const;
207  SystemMultiplierIndex getMultipliersStart (const State&) const;
208  int getNMultipliers (const State&) const;
209  SystemEventTriggerByStageIndex getEventTriggerStartByStage(const State&, Stage) const;
210  int getNEventTriggersByStage (const State&, Stage) const;
211 
212  bool isInSystem() const;
213  bool isInSameSystem(const Subsystem& otherSubsystem) const;
214 
215  const System& getSystem() const;
216  System& updSystem();
217 
218  SubsystemIndex getMySubsystemIndex() const;
219 
220  // Is this handle the owner of this rep? This is true if the
221  // handle is empty or if its rep points back here.
222  bool isOwnerHandle() const;
223  bool isEmptyHandle() const;
224 
225  // There can be multiple handles on the same Subsystem.
226  bool isSameSubsystem(const Subsystem& otherSubsystem) const;
227 
228  bool subsystemTopologyHasBeenRealized() const;
229  void invalidateSubsystemTopologyCache() const;
230 
231  // Add a new Measure to this Subsystem. This method is generally used by Measure
232  // constructors to install a newly-constructed Measure into its Subsystem.
233  MeasureIndex adoptMeasure(AbstractMeasure&);
234 
235  AbstractMeasure getMeasure(MeasureIndex) const;
236  template <class T> Measure_<T> getMeasure_(MeasureIndex mx) const
237  { return Measure_<T>::getAs(getMeasure(mx));}
238 
239  // dynamic_cast the returned reference to a reference to your concrete Guts
240  // class.
241  const Subsystem::Guts& getSubsystemGuts() const {assert(guts); return *guts;}
242  Subsystem::Guts& updSubsystemGuts() {assert(guts); return *guts;}
243 
244  // Put new Guts into this *empty* handle and take over ownership.
245  // If this handle is already in use, this routine will throw
246  // an exception.
247  void adoptSubsystemGuts(Subsystem::Guts* g);
248  void setSystem(System&, SubsystemIndex);
249 
250  explicit Subsystem(Subsystem::Guts* g) : guts(g) { }
251  bool hasGuts() const {return guts!=0;}
252 };
253 
254 } // namespace SimTK
255 
256 #endif // SimTK_SimTKCOMMON_SUBSYSTEM_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...
Unique integer type for Subsystem-local u indexing.
bool isDiscreteVarUpdateValueRealized(const State &s, DiscreteVariableIndex dx) const
Definition: Subsystem.h:174
Real getDiscreteVarLastUpdateTime(const State &s, DiscreteVariableIndex dx) const
Definition: Subsystem.h:166
Unique integer type for Subsystem-local uErr indexing.
Real getDiscreteVarLastUpdateTime(SubsystemIndex, DiscreteVariableIndex) const
Return the time of last update for this discrete variable.
CacheEntryIndex getDiscreteVarUpdateIndex(const State &s, DiscreteVariableIndex dx) const
Definition: Subsystem.h:168
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
int size() const
Definition: BigMatrix.h:1411
void markDiscreteVarUpdateValueRealized(const State &s, DiscreteVariableIndex dx) const
Definition: Subsystem.h:176
CacheEntryIndex getDiscreteVarUpdateIndex(SubsystemIndex, DiscreteVariableIndex) const
For an auto-updating discrete variable, return the CacheEntryIndex for its associated update cache en...
void setU(State &s, const Vector &u) const
Definition: Subsystem.h:137
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
const Subsystem::Guts & getSubsystemGuts() const
Definition: Subsystem.h:241
This file declares the base class AbstractMeasure for all derived Measure handle classes, and the handle classes for built-in Measures.
Subsystem::Guts & updSubsystemGuts()
Definition: Subsystem.h:242
const AbstractValue & getDiscreteVarUpdateValue(const State &s, DiscreteVariableIndex dx) const
Definition: Subsystem.h:170
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.
void setQ(State &s, const Vector &q) const
Definition: Subsystem.h:133
This unique integer type is for indexing global "uErr-like" arrays, that is, arrays that inherently h...
Unique integer type for Subsystem-local q indexing.
Subsystem(Subsystem::Guts *g)
Definition: Subsystem.h:250
AbstractValue & updDiscreteVarUpdateValue(const State &s, DiscreteVariableIndex dx) const
Definition: Subsystem.h:172
The abstract parent of all Subsystem "Guts" implementation classes.
Definition: SubsystemGuts.h:42
Higher than any legitimate Stage.
Definition: Stage.h:63
This unique integer type is for identifying a triggered event within a particular Stage of the full S...
bool hasGuts() const
Definition: Subsystem.h:251
SimTK::String is a plug-compatible std::string replacement (plus some additional functionality) inten...
Definition: String.h:62
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...
Measure_< T > getMeasure_(MeasureIndex mx) const
Definition: Subsystem.h:236
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
Provide a unique integer type for identifying Subsystems.
Subsystem()
Definition: Subsystem.h:70
This unique integer type is for selecting non-shared cache entries.
This is the header which should be included in user programs that would like to make use of all the S...
Unique integer type for Subsystem-local, per-stage event indexing.
void setZ(State &s, const Vector &z) const
Definition: Subsystem.h:141
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.
This is the base handle class for all Measures whose value type is known, including all the Simbody b...
Definition: Measure.h:261