00001 #ifndef SimTK_SimTKCOMMON_MEASURE_H_
00002 #define SimTK_SimTKCOMMON_MEASURE_H_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00045 #include "SimTKcommon/basics.h"
00046 #include "SimTKcommon/Simmatrix.h"
00047
00066 #define SimTK_MEASURE_HANDLE_PREAMBLE(MH,PH) \
00067 class Implementation; \
00068 explicit MH(Implementation* imp=0) : PH(imp) {} \
00069 MH(Subsystem& sub, Implementation* imp, const SetHandle& sh) : PH(sub,imp,sh) {}
00070
00092 #define SimTK_MEASURE_HANDLE_POSTSCRIPT(MH,PH) \
00093 static bool isA(const Measure& m) \
00094 { return dynamic_cast<const Implementation*>(&m.getImpl()) != 0; } \
00095 static const MH& getAs(const Measure& m) \
00096 { assert(isA(m)); return static_cast<const MH&>(m); } \
00097 static MH& updAs(Measure& m) \
00098 { assert(isA(m)); return static_cast<MH&>(m); } \
00099 const Implementation& getImpl() const \
00100 { return dynamic_cast<const Implementation&>(Measure::getImpl());} \
00101 Implementation& updImpl() \
00102 { return dynamic_cast<Implementation&>(Measure::updImpl());}
00103
00104 namespace SimTK {
00105
00106 class State;
00107 class Subsystem;
00108 class System;
00109 class EventIndex;
00110
00112 SimTK_DEFINE_UNIQUE_INDEX_TYPE(MeasureIndex);
00113
00115
00117
00132 class SimTK_SimTKCOMMON_EXPORT Measure {
00133 protected:
00134
00135
00136 class SetHandle {};
00137
00138 public:
00139 class Implementation;
00140
00141 explicit Measure(Implementation* g=0);
00142 Measure(Subsystem&, Implementation* g, const SetHandle&);
00143 Measure(const Measure&);
00144 Measure& operator=(const Measure&);
00145 ~Measure();
00146
00147
00148 Stage getValueDependence(const State&) const;
00149
00150
00151 bool isSameMeasure(const Measure& other) const
00152 { return impl && impl==other.impl;}
00153
00154 bool isInSubsystem() const;
00155 const Subsystem& getSubsystem() const;
00156 MeasureIndex getSubsystemMeasureIndex() const;
00157
00158
00159
00160
00161
00162 const Implementation& getImpl() const {assert(impl); return *impl;}
00163 Implementation& updImpl() {assert(impl); return *impl;}
00164
00165 bool hasImpl() const {return impl!=0;}
00166
00167 public:
00168
00169
00170
00171
00172 template <class T> class Constant_;
00173 template <class T> class SampleAndHold_;
00174
00175
00176
00177 template <class T> class Minimum_;
00178 template <class T> class Maximum_;
00179
00180
00181 template <class T> class Integrate_;
00182 template <class T> class Sinusoid_;
00183
00184
00185
00186
00187 typedef Constant_<Real> Constant;
00188 typedef Integrate_<Real> Integrate;
00189 typedef Sinusoid_<Real> Sinusoid;
00190
00191
00192 private:
00193
00194
00195 Implementation* impl;
00196
00197 friend class Implementation;
00198 };
00199
00200
00202
00204
00208 template <class T>
00209 class Measure_ : public Measure {
00210 public:
00211 SimTK_MEASURE_HANDLE_PREAMBLE(Measure_, Measure);
00212
00213 const T& getValue(const State& s) const {return getImpl().getValue(s);}
00214
00215 SimTK_MEASURE_HANDLE_POSTSCRIPT(Measure_, Measure);
00216 };
00217
00218
00220
00222
00228 template <class T>
00229 class Measure::Constant_ : public Measure_<T> {
00230 public:
00231 SimTK_MEASURE_HANDLE_PREAMBLE(Constant_, Measure_<T>);
00232
00233 Constant_(Subsystem& sub, const T& value)
00234 : Measure_<T>(sub, new Implementation(value), SetHandle()) {}
00235
00237 Constant_& setValue(const T& value) {updImpl().setValue(value); return *this;}
00238
00239 SimTK_MEASURE_HANDLE_POSTSCRIPT(Constant_, Measure_<T>);
00240 };
00241
00242
00244
00246
00252 template <class T>
00253 class Measure::Sinusoid_ : public Measure_<T> {
00254 public:
00255 SimTK_MEASURE_HANDLE_PREAMBLE(Sinusoid_, Measure_<T>);
00256
00257 Sinusoid_(Subsystem& sub,
00258 const T& amplitude,
00259 const T& frequency,
00260 const T& phase=T(0))
00261 : Measure_<T>(sub, new Implementation(amplitude,frequency,phase), SetHandle()) {}
00262
00263 SimTK_MEASURE_HANDLE_POSTSCRIPT(Sinusoid_, Measure_<T>);
00264 };
00265
00266
00268
00270
00271 template <class T>
00272 class Measure::Integrate_ : public Measure_<T> {
00273 public:
00274 SimTK_MEASURE_HANDLE_PREAMBLE(Integrate_, Measure_<T>);
00275
00276 Integrate_(Subsystem& sub, const Measure_<T>& deriv, const Measure_<T>& ic)
00277 : Measure_<T>(sub, new Implementation(deriv,ic), SetHandle()) {}
00278
00279 void setValue(State& s, const T& value) const {return getImpl().setValue(s, value);}
00280 const Measure_<T>& getDerivativeMeasure() const {return getImpl().getDerivativeMeasure();}
00281 const Measure_<T>& getInitialConditionMeasure() const {return getImpl().getInitialConditionMeasure();}
00282
00283 Integrate_& setDerivativeMeasure(const Measure_<T>& d)
00284 { updImpl().setDerivativeMeasure(d); return *this; }
00285 Integrate_& setInitialConditionMeasure(const Measure_<T>& ic)
00286 { updImpl().setInitialConditionMeasure(ic); return *this; }
00287
00288 SimTK_MEASURE_HANDLE_POSTSCRIPT(Integrate_, Measure_<T>);
00289 };
00290
00291
00293
00295
00330 template <class T>
00331 class Measure::Minimum_ : public Measure_<T> {
00332 public:
00333 SimTK_MEASURE_HANDLE_PREAMBLE(Minimum_, Measure_<T>);
00334
00335 Minimum_(Subsystem& sub, const Measure_<T>& source, const Measure_<T>& sourceDot)
00336 : Measure_<T>(sub, new Implementation(source, sourceDot), SetHandle()) {}
00337
00338 void setValue(State& s, const T& value) const {return getImpl().setValue(s, value);}
00339 const Measure_<T>& getSourceMeasure() const {return getImpl().getSourceMeasure();}
00340 const Measure_<T>& getSourceDerivativeMeasure() const {return getImpl().getSourceDerivativeMeasure();}
00341
00342 Minimum_& setSourceMeasure(const Measure_<T>& s)
00343 { updImpl().setSourceMeasure(s); return *this; }
00344 Minimum_& setSourceDerivativeMeasure(const Measure_<T>& sdot)
00345 { updImpl().setSourceDerivativeMeasure(sdot); return *this; }
00346
00347 SimTK_MEASURE_HANDLE_POSTSCRIPT(Minimum_, Measure_<T>);
00348 };
00349
00364 template <class T>
00365 class Measure::SampleAndHold_ : public Measure_<T> {
00366 public:
00367 SimTK_MEASURE_HANDLE_PREAMBLE(SampleAndHold_, Measure_<T>);
00368
00369 SampleAndHold_(Subsystem& sub, const Measure_<T>& source, EventIndex e);
00370
00373 void setValue(State& s, const T& value) const;
00374
00376 void sample(State& s) const;
00377
00378 const Measure_<T>& getSource() const;
00379 EventIndex getEvent() const;
00380
00381 SampleAndHold_& setSource(const Measure_<T>& s);
00382 SampleAndHold_& setEvent(EventIndex);
00383
00384 SimTK_MEASURE_HANDLE_POSTSCRIPT(SampleAndHold_, Measure_<T>);
00385 };
00386
00387 }
00388
00389 #endif // SimTK_SimTKCOMMON_MEASURE_H_