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
00048 #include <cassert>
00049
00068 #define SimTK_MEASURE_HANDLE_PREAMBLE_BASE(MH,PH) \
00069 class Implementation; \
00070 explicit MH(Implementation* imp) : PH(imp) {} \
00071 MH(Subsystem& sub, Implementation* imp, const SetHandle& sh) \
00072 : PH(sub,imp,sh) {} \
00073 MH& operator=(const MH& src) {PH::operator=(src); return *this;}\
00074 MH& shallowAssign(const MH& src) {PH::shallowAssign(src); return *this;}\
00075 MH& deepAssign(const MH& src) {PH::deepAssign(src); return *this;}
00076
00077
00078
00079
00080 #define SimTK_MEASURE_HANDLE_PREAMBLE(MH,PH) \
00081 SimTK_MEASURE_HANDLE_PREAMBLE_BASE(MH,PH) \
00082 MH() : PH(new Implementation()) {} \
00083 explicit MH(Subsystem& sub) \
00084 : PH(sub,new Implementation(), SetHandle()) {}
00085
00086
00087
00088 #define SimTK_MEASURE_HANDLE_PREAMBLE_ABSTRACT(MH,PH) \
00089 SimTK_MEASURE_HANDLE_PREAMBLE_BASE(MH,PH) \
00090 MH() : PH() {} \
00091 explicit MH(Subsystem& sub) : PH(sub) {}
00092
00114 #define SimTK_MEASURE_HANDLE_POSTSCRIPT(MH,PH) \
00115 static bool isA(const AbstractMeasure& m) \
00116 { return dynamic_cast<const Implementation*>(&m.getImpl()) != 0; } \
00117 static const MH& getAs(const AbstractMeasure& m) \
00118 { assert(isA(m)); return static_cast<const MH&>(m); } \
00119 static MH& updAs(AbstractMeasure& m) \
00120 { assert(isA(m)); return static_cast<MH&>(m); } \
00121 const Implementation& getImpl() const \
00122 { return dynamic_cast<const Implementation&> \
00123 (AbstractMeasure::getImpl());} \
00124 Implementation& updImpl() \
00125 { return dynamic_cast<Implementation&>(AbstractMeasure::updImpl());}
00126
00127 namespace SimTK {
00128
00129 class State;
00130 class Subsystem;
00131 class System;
00132 class EventIndex;
00133
00135 SimTK_DEFINE_UNIQUE_INDEX_TYPE(MeasureIndex);
00136
00138
00140
00156 class SimTK_SimTKCOMMON_EXPORT AbstractMeasure {
00157 protected:
00158
00159
00160
00161 class SetHandle {};
00162
00163 public:
00164 class Implementation;
00165
00169 explicit AbstractMeasure(Implementation* g=0);
00170
00175 AbstractMeasure(Subsystem&, Implementation* g, const SetHandle&);
00176
00179 AbstractMeasure(const AbstractMeasure&);
00180
00184 AbstractMeasure& operator=(const AbstractMeasure& source)
00185 { return shallowAssign(source); }
00186
00189 ~AbstractMeasure();
00190
00196 AbstractMeasure& shallowAssign(const AbstractMeasure&);
00197
00202 AbstractMeasure& deepAssign(const AbstractMeasure& source);
00203
00211 int getNumTimeDerivatives() const;
00212
00221 Stage getDependsOnStage(int derivOrder=0) const;
00222
00223
00225 bool isSameMeasure(const AbstractMeasure& other) const
00226 { return impl && impl==other.impl;}
00227
00228 bool isEmptyHandle() const {return !hasImpl();}
00229
00231 bool isInSubsystem() const;
00235 const Subsystem& getSubsystem() const;
00239 MeasureIndex getSubsystemMeasureIndex() const;
00240
00241
00242
00243
00244
00245 const Implementation& getImpl() const {assert(impl); return *impl;}
00246 Implementation& updImpl() {assert(impl); return *impl;}
00247 bool hasImpl() const {return impl!=0;}
00248
00249 int getRefCount() const;
00250 private:
00251
00252
00253
00254 Implementation* impl;
00255
00256 friend class Implementation;
00257 };
00258
00259
00261
00263
00267 template <class T>
00268 class Measure_ : public AbstractMeasure {
00269 public:
00272 SimTK_MEASURE_HANDLE_PREAMBLE_ABSTRACT(Measure_, AbstractMeasure);
00273
00281 inline const T& getValue(const State& s, int derivOrder=0) const
00282 { return getImpl().getValue(s,derivOrder); }
00283
00284
00285
00286
00287
00288 class Zero;
00289 class One;
00290 class Constant;
00291 class Time;
00292 class Variable;
00293 class SampleAndHold;
00294
00295
00296 class Plus;
00297 class Minus;
00298 class Scale;
00299 class Differentiate;
00300
00301
00302
00303 class Minimum;
00304 class Maximum;
00305
00306
00307 class Integrate;
00308 class Sinusoid;
00309
00310 SimTK_MEASURE_HANDLE_POSTSCRIPT(Measure_, AbstractMeasure);
00311 };
00312
00315 typedef Measure_<Real> Measure;
00316
00317
00319
00321
00328 template <class T>
00329 class Measure_<T>::Constant : public Measure_<T> {
00330 public:
00331 SimTK_MEASURE_HANDLE_PREAMBLE(Constant, Measure_<T>);
00332
00333 explicit Constant(const T& value)
00334 : Measure_<T>(new Implementation(value)) {}
00335
00336 Constant(Subsystem& sub, const T& value)
00337 : Measure_<T>(sub, new Implementation(value), SetHandle()) {}
00338
00341 Constant& setValue(const T& value)
00342 { updImpl().setValue(value); return *this; }
00343
00344 SimTK_MEASURE_HANDLE_POSTSCRIPT(Constant, Measure_<T>);
00345 };
00346
00348
00350
00355 template <class T>
00356 class Measure_<T>::Zero : public Measure_<T>::Constant {
00357 public:
00358 SimTK_MEASURE_HANDLE_PREAMBLE(Zero, Measure_<T>::Constant);
00359
00360 SimTK_MEASURE_HANDLE_POSTSCRIPT(Zero, Measure_<T>::Constant);
00361 private:
00362 Zero& setValue(const T&)
00363 { return *reinterpret_cast<Zero*>(0);}
00364 };
00365
00367
00369
00374 template <class T>
00375 class Measure_<T>::One : public Measure_<T>::Constant {
00376 public:
00377 SimTK_MEASURE_HANDLE_PREAMBLE(One, Measure_<T>::Constant);
00378
00379 SimTK_MEASURE_HANDLE_POSTSCRIPT(One, Measure_<T>::Constant);
00380 private:
00381 One& setValue(const T&)
00382 { return *reinterpret_cast<One*>(0);}
00383 };
00384
00386
00388
00392 template <class T>
00393 class Measure_<T>::Time : public Measure_<T> {
00394 public:
00395 SimTK_MEASURE_HANDLE_PREAMBLE(Time, Measure_<T>);
00396
00397 SimTK_MEASURE_HANDLE_POSTSCRIPT(Time, Measure_<T>);
00398 };
00399
00401
00403
00408 template <class T>
00409 class Measure_<T>::Variable : public Measure_<T> {
00410 public:
00411 SimTK_MEASURE_HANDLE_PREAMBLE(Variable, Measure_<T>);
00412
00413
00414
00415
00416 Variable(Subsystem& sub, Stage invalidates, const T& defaultValue)
00417 : Measure_<T>(sub, new Implementation(invalidates, defaultValue),
00418 SetHandle()) {}
00419
00422 Variable& setDefaultValue(const T& defaultValue)
00423 { updImpl().setDefaultValue(defaultValue); return *this; }
00424
00425 const T& getDefaultValue() const
00426 { return getImpl().getDefaultValue(); }
00427
00428 void setValue(State& state, const T& value) const
00429 { getImpl().setValue(state, value); }
00430
00431 SimTK_MEASURE_HANDLE_POSTSCRIPT(Variable, Measure_<T>);
00432 };
00433
00434
00436
00438
00447 template <class T>
00448 class Measure_<T>::Sinusoid : public Measure_<T> {
00449 public:
00450 SimTK_MEASURE_HANDLE_PREAMBLE(Sinusoid, Measure_<T>);
00451
00452 Sinusoid(Subsystem& sub,
00453 const T& amplitude,
00454 const T& frequency,
00455 const T& phase=T(0))
00456 : Measure_<T>(sub, new Implementation(amplitude,frequency,phase), SetHandle()) {}
00457
00458 SimTK_MEASURE_HANDLE_POSTSCRIPT(Sinusoid, Measure_<T>);
00459 };
00460
00462
00464
00468 template <class T>
00469 class Measure_<T>::Plus : public Measure_<T> {
00470 public:
00471 SimTK_MEASURE_HANDLE_PREAMBLE(Plus, Measure_<T>);
00472
00473 Plus(Subsystem& sub, const Measure_<T>& left, const Measure_<T>& right)
00474 : Measure_<T>(sub,
00475 new Implementation(left, right), SetHandle())
00476 { SimTK_ERRCHK_ALWAYS
00477 ( this->getSubsystem().isSameSubsystem(left.getSubsystem())
00478 && this->getSubsystem().isSameSubsystem(right.getSubsystem()),
00479 "Measure_<T>::Plus::ctor()",
00480 "Arguments must be in the same Subsystem as this Measure.");
00481 }
00482
00483 SimTK_MEASURE_HANDLE_POSTSCRIPT(Plus, Measure_<T>);
00484 };
00485
00487
00489
00493 template <class T>
00494 class Measure_<T>::Minus : public Measure_<T> {
00495 public:
00496 SimTK_MEASURE_HANDLE_PREAMBLE(Minus, Measure_<T>);
00497
00498 Minus(Subsystem& sub, const Measure_<T>& left, const Measure_<T>& right)
00499 : Measure_<T>(sub,
00500 new Implementation(left, right), SetHandle())
00501 { SimTK_ERRCHK_ALWAYS
00502 ( this->getSubsystem().isSameSubsystem(left.getSubsystem())
00503 && this->getSubsystem().isSameSubsystem(right.getSubsystem()),
00504 "Measure_<T>::Minus::ctor()",
00505 "Arguments must be in the same Subsystem as this Measure.");
00506 }
00507
00508 SimTK_MEASURE_HANDLE_POSTSCRIPT(Minus, Measure_<T>);
00509 };
00510
00512
00514
00518 template <class T>
00519 class Measure_<T>::Scale : public Measure_<T> {
00520 public:
00521 SimTK_MEASURE_HANDLE_PREAMBLE(Scale, Measure_<T>);
00522
00523 Scale(Subsystem& sub, Real factor, const Measure_<T>& operand)
00524 : Measure_<T>(sub,
00525 new Implementation(factor, operand), SetHandle())
00526 { SimTK_ERRCHK_ALWAYS
00527 (this->getSubsystem().isSameSubsystem(operand.getSubsystem()),
00528 "Measure_<T>::Scale::ctor()",
00529 "Argument must be in the same Subsystem as this Measure.");
00530 }
00531
00532 SimTK_MEASURE_HANDLE_POSTSCRIPT(Scale, Measure_<T>);
00533 };
00534
00536
00538
00539 template <class T>
00540 class Measure_<T>::Integrate : public Measure_<T> {
00541 public:
00542 SimTK_MEASURE_HANDLE_PREAMBLE(Integrate, Measure_<T>);
00543
00544 Integrate(Subsystem& sub, const Measure_<T>& deriv, const Measure_<T>& ic)
00545 : Measure_<T>(sub, new Implementation(deriv,ic), SetHandle()) {}
00546
00547 void setValue(State& s, const T& value) const
00548 { return getImpl().setValue(s, value); }
00549 const Measure_<T>& getDerivativeMeasure() const
00550 { return getImpl().getDerivativeMeasure(); }
00551 const Measure_<T>& getInitialConditionMeasure() const
00552 { return getImpl().getInitialConditionMeasure(); }
00553
00554 Integrate& setDerivativeMeasure(const Measure_<T>& d)
00555 { updImpl().setDerivativeMeasure(d); return *this; }
00556 Integrate& setInitialConditionMeasure(const Measure_<T>& ic)
00557 { updImpl().setInitialConditionMeasure(ic); return *this; }
00558
00559 SimTK_MEASURE_HANDLE_POSTSCRIPT(Integrate, Measure_<T>);
00560 };
00561
00563
00565
00590 template <class T>
00591 class Measure_<T>::Differentiate : public Measure_<T> {
00592 public:
00593 SimTK_MEASURE_HANDLE_PREAMBLE(Differentiate, Measure_<T>);
00594
00599 Differentiate(Subsystem& subsystem, const Measure_<T>& operand)
00600 : Measure_<T>(subsystem, new Implementation(operand), SetHandle()) {}
00601
00606 bool isUsingApproximation() const
00607 { return getImpl().isUsingApproximation(); }
00608
00611 const Measure_<T>& getOperandMeasure() const
00612 { return getImpl().getOperandMeasure(); }
00613
00617 Differentiate& setOperandMeasure(const Measure_<T>& operand)
00618 { updImpl().setOperandMeasure(operand); return *this; }
00619
00623 void setForceUseApproximation(bool mustApproximate)
00624 { updImpl().setForceUseApproximation(mustApproximate); }
00625
00630 bool getForceUseApproximation() const
00631 { return getImpl().getForceUseApproximation(); }
00632
00633 SimTK_MEASURE_HANDLE_POSTSCRIPT(Differentiate, Measure_<T>);
00634 };
00635
00637
00639
00674 template <class T>
00675 class Measure_<T>::Minimum : public Measure_<T> {
00676 public:
00677 SimTK_MEASURE_HANDLE_PREAMBLE(Minimum, Measure_<T>);
00678
00679 Minimum(Subsystem& sub, const Measure_<T>& source, const Measure_<T>& sourceDot)
00680 : Measure_<T>(sub, new Implementation(source, sourceDot), SetHandle()) {}
00681
00682 void setValue(State& s, const T& value) const
00683 { return getImpl().setValue(s, value); }
00684 const Measure_<T>& getSourceMeasure() const
00685 { return getImpl().getSourceMeasure(); }
00686 const Measure_<T>& getSourceDerivativeMeasure() const
00687 { return getImpl().getSourceDerivativeMeasure(); }
00688
00689 Minimum& setSourceMeasure(const Measure_<T>& s)
00690 { updImpl().setSourceMeasure(s); return *this; }
00691 Minimum& setSourceDerivativeMeasure(const Measure_<T>& sdot)
00692 { updImpl().setSourceDerivativeMeasure(sdot); return *this; }
00693
00694 SimTK_MEASURE_HANDLE_POSTSCRIPT(Minimum, Measure_<T>);
00695 };
00696
00712 template <class T>
00713 class Measure_<T>::SampleAndHold : public Measure_<T> {
00714 public:
00715 SimTK_MEASURE_HANDLE_PREAMBLE(SampleAndHold, Measure_<T>);
00716
00717 SampleAndHold(Subsystem& sub, const Measure_<T>& source, EventIndex e);
00718
00721 void setValue(State& s, const T& value) const;
00722
00724 void sample(State& s) const;
00725
00726 const Measure_<T>& getSource() const;
00727 EventIndex getEvent() const;
00728
00729 SampleAndHold& setSource(const Measure_<T>& s);
00730 SampleAndHold& setEvent(EventIndex);
00731
00732 SimTK_MEASURE_HANDLE_POSTSCRIPT(SampleAndHold, Measure_<T>);
00733 };
00734
00735 }
00736
00737 #endif // SimTK_SimTKCOMMON_MEASURE_H_