Simbody  3.4 (development)
Measure.h
Go to the documentation of this file.
00001 #ifndef SimTK_SimTKCOMMON_MEASURE_H_
00002 #define SimTK_SimTKCOMMON_MEASURE_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) 2008-13 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 
00037 #include "SimTKcommon/basics.h"
00038 #include "SimTKcommon/Simmatrix.h"
00039 
00040 #include <cassert>
00041 
00062 // Helper macro shared by SimTK_MEASURE_HANDLE_PREAMBLE and
00063 // SimTK_MEASURE_HANDLE_PREAMBLE_ABSTRACT.
00064 #define SimTK_MEASURE_HANDLE_PREAMBLE_BASE(MH,PH) \
00065     class Implementation;                                           \
00066     explicit MH(Implementation* imp) : PH(imp) {}                   \
00067     MH(SimTK::Subsystem& sub, Implementation* imp,                  \
00068        const SimTK::AbstractMeasure::SetHandle& sh)                 \
00069     :   PH(sub,imp,sh) {}                                           \
00070     MH& operator=(const MH& src) {PH::operator=(src); return *this;}\
00071     MH& shallowAssign(const MH& src) {PH::shallowAssign(src); return *this;}\
00072     MH& deepAssign(const MH& src) {PH::deepAssign(src); return *this;}
00073 
00074 
00075 // The default constructor for concrete classes should instantiate
00076 // a default-constructed Implementation object if no Implementation object
00077 // is provided.
00078 #define SimTK_MEASURE_HANDLE_PREAMBLE(MH,PH)    \
00079     SimTK_MEASURE_HANDLE_PREAMBLE_BASE(MH,PH)   \
00080     MH() : PH(new Implementation()) {}          \
00081     explicit MH(SimTK::Subsystem& sub)          \
00082     : PH(sub,new Implementation(), typename PH::SetHandle()) {}
00083 
00084 
00085 
00086 // The default constructor for a still-abstract derived class can't
00087 // instantiate an Implementation.
00088 #define SimTK_MEASURE_HANDLE_PREAMBLE_ABSTRACT(MH,PH)   \
00089     SimTK_MEASURE_HANDLE_PREAMBLE_BASE(MH,PH)           \
00090     MH() : PH() {}
00091 
00111 #define SimTK_MEASURE_HANDLE_POSTSCRIPT(MH,PH) \
00112     static bool isA(const SimTK::AbstractMeasure& m)                        \
00113     {   return dynamic_cast<const Implementation*>(&m.getImpl()) != 0; }    \
00114     static const MH& getAs(const SimTK::AbstractMeasure& m)                 \
00115     {   assert(isA(m)); return static_cast<const MH&>(m); }                 \
00116     static MH& updAs(SimTK::AbstractMeasure& m)                             \
00117     {   assert(isA(m)); return static_cast<MH&>(m); }                       \
00118     const Implementation& getImpl() const                                   \
00119     {   return SimTK_DYNAMIC_CAST_DEBUG<const Implementation&>              \
00120                     (SimTK::AbstractMeasure::getImpl());}                   \
00121     Implementation& updImpl()                                               \
00122     {   return SimTK_DYNAMIC_CAST_DEBUG<Implementation&>                    \
00123                     (SimTK::AbstractMeasure::updImpl());} 
00124 
00125 namespace SimTK {
00126 
00127 class State;
00128 class Subsystem;
00129 class System;
00130 class EventId;
00131 
00133 SimTK_DEFINE_UNIQUE_INDEX_TYPE(MeasureIndex);
00134 
00135 //==============================================================================
00136 //                            ABSTRACT MEASURE
00137 //==============================================================================
00151 class SimTK_SimTKCOMMON_EXPORT AbstractMeasure {
00152 protected:
00156     class SetHandle {};
00157 
00158 public:
00159     class Implementation; // local; name is AbstractMeasure::Implementation
00160 
00164     explicit AbstractMeasure(Implementation* g=0);
00165 
00170     AbstractMeasure(Subsystem&, Implementation* g, const SetHandle&);
00171 
00174     AbstractMeasure(const AbstractMeasure&);
00175 
00179     AbstractMeasure& operator=(const AbstractMeasure& source)
00180     {   return shallowAssign(source); }
00181 
00184     ~AbstractMeasure();
00185 
00191     AbstractMeasure& shallowAssign(const AbstractMeasure&);
00192 
00197     AbstractMeasure& deepAssign(const AbstractMeasure& source);
00198 
00206     int getNumTimeDerivatives() const;
00207 
00216     Stage getDependsOnStage(int derivOrder=0) const;
00217 
00218 
00220     bool isSameMeasure(const AbstractMeasure& other) const
00221     {   return impl && impl==other.impl;}
00222 
00223     bool isEmptyHandle() const {return !hasImpl();}
00224 
00226     bool isInSubsystem() const;
00230     const Subsystem& getSubsystem()  const;
00234     MeasureIndex getSubsystemMeasureIndex() const;
00235 
00236     // Internal use only
00237 
00238     // dynamic_cast the returned reference to a reference to your concrete
00239     // Implementation class.
00240     const Implementation& getImpl() const {assert(impl); return *impl;}
00241     Implementation&       updImpl()       {assert(impl); return *impl;}
00242     bool                  hasImpl() const {return impl!=0;}
00243 
00244     int getRefCount() const;
00245 private:
00246     // This is the only data member in this class. Also, any class derived 
00247     // from AbstractMeasure must have *NO* data members at all (data goes 
00248     // in the Implementation class).
00249     Implementation* impl;
00250 
00251 friend class Implementation;
00252 };
00253 
00254 
00255 //==============================================================================
00256 //                               MEASURE <T>
00257 //==============================================================================
00260 template <class T>
00261 class Measure_ : public AbstractMeasure {
00262 public:
00265     SimTK_MEASURE_HANDLE_PREAMBLE_ABSTRACT(Measure_, AbstractMeasure);
00266 
00274     const T& getValue(const State& s, int derivOrder=0) const 
00275     {   return getImpl().getValue(s,derivOrder); }
00276 
00283     Measure_& setDefaultValue(const T& defaultValue) 
00284     {   updImpl().setDefaultValue(defaultValue); return *this; }
00285 
00288     const T& getDefaultValue() const
00289     {   return getImpl().getDefaultValue(); }
00290 
00291     // These are built-in Measures with local class names. 
00292 
00293     // Templatized measures may have restrictions on the allowable template
00294     // type and may be specialized for particular types.
00295     class Zero;         // T is any numerical type
00296     class One;          // T is any numerical type
00297     class Constant;     // T is any assignable type
00298     class Time;         // T is any type for which T(t) makes sense.
00299     class Variable;     // T is any assignable type (state)
00300     class Result;       // T is any assignable type (cache)
00301     class SampleAndHold;// T is any assignable type
00302     class Delay;        // T is any assignable type
00303 
00304     // This requires any numerical type.
00305     class Plus;
00306     class Minus;
00307     class Scale;
00308     class Differentiate;
00309 
00310     // These find extreme values *in time*, not among inputs at the same
00311     // time. They perform elementwise on aggregate types.
00312     class Extreme;  // base class for min/max/minabs/maxabs
00313     class Minimum;  // most positive value
00314     class Maximum;  // most negative value
00315     class MinAbs;   // the signed quantity whose absolute value was min
00316     class MaxAbs;   // the signed quantity whose absolute value was max
00317 
00318     // These accept floating point numerical template arguments only.
00319     class Integrate;
00320     class Sinusoid;
00321 
00322     SimTK_MEASURE_HANDLE_POSTSCRIPT(Measure_, AbstractMeasure);
00323 };
00324 
00328 typedef Measure_<Real> Measure;
00329 
00330 
00331 //==============================================================================
00332 //                                CONSTANT
00333 //==============================================================================
00338 template <class T>
00339 class Measure_<T>::Constant : public Measure_<T> {
00340 public:
00341     SimTK_MEASURE_HANDLE_PREAMBLE(Constant, Measure_<T>);
00342 
00345     explicit Constant(const T& value)
00346     :   Measure_<T>(new Implementation(value)) {}
00347 
00350     Constant(Subsystem& sub, const T& value)
00351     :   Measure_<T>(sub, new Implementation(value), 
00352                     AbstractMeasure::SetHandle()) {}
00353 
00356     Constant& setValue(const T& value) 
00357     {   updImpl().setValue(value); return *this; }
00358 
00359     SimTK_MEASURE_HANDLE_POSTSCRIPT(Constant, Measure_<T>);
00360 };
00361 
00362 //==============================================================================
00363 //                                   ZERO
00364 //==============================================================================
00368 template <class T>
00369 class Measure_<T>::Zero : public Measure_<T>::Constant {
00370 public:
00371     Zero();
00372     explicit Zero(Subsystem& sub);
00373 };
00374 
00375 template <>
00376 class Measure_< Vector >::Zero : public Measure_< Vector >::Constant {
00377 public:
00378     explicit Zero(int size);
00379     Zero(Subsystem& sub, int size);
00380 };
00381 
00382 //==============================================================================
00383 //                                    ONE
00384 //==============================================================================
00388 template <class T>
00389 class Measure_<T>::One : public Measure_<T>::Constant {
00390 public:
00391     One();
00392     explicit One(Subsystem& sub);
00393 };
00394 
00395 template <>
00396 class Measure_< Vector >::One : public Measure_< Vector >::Constant {
00397 public:
00398     explicit One(int size);
00399     One(Subsystem& sub, int size);
00400 };
00401 
00402 //==============================================================================
00403 //                                   TIME
00404 //==============================================================================
00406 template <class T>
00407 class Measure_<T>::Time : public Measure_<T> {
00408 public:
00409     SimTK_MEASURE_HANDLE_PREAMBLE(Time, Measure_<T>);
00410 
00411     SimTK_MEASURE_HANDLE_POSTSCRIPT(Time, Measure_<T>);
00412 };
00413 
00414 //==============================================================================
00415 //                                 VARIABLE
00416 //==============================================================================
00419 template <class T>
00420 class Measure_<T>::Variable : public Measure_<T> {
00421 public:
00422     SimTK_MEASURE_HANDLE_PREAMBLE(Variable, Measure_<T>);
00423 
00424     // TODO: should not require invalidated Stage here. Instead, 
00425     // should have a unique "generation" counter for this variable
00426     // and allow subsequent users to check it.
00427     Variable(Subsystem& sub, Stage invalidates, const T& defaultValue)
00428     :   Measure_<T>(sub, new Implementation(invalidates, defaultValue), 
00429                     AbstractMeasure::SetHandle()) {}
00430 
00431 
00432     void setValue(State& state, const T& value) const
00433     {   getImpl().setValue(state, value); }
00434 
00435     SimTK_MEASURE_HANDLE_POSTSCRIPT(Variable, Measure_<T>);
00436 };
00437 
00438 //==============================================================================
00439 //                                 RESULT
00440 //==============================================================================
00454 template <class T>
00455 class Measure_<T>::Result : public Measure_<T> {
00456 public:
00457     SimTK_MEASURE_HANDLE_PREAMBLE(Result, Measure_<T>);
00458 
00459     // TODO: should not require invalidated Stage here. Instead, 
00460     // should have a unique "generation" counter for this cache entry
00461     // and allow subsequent users of the value to check it.
00462 
00477     Result(Subsystem& sub, Stage dependsOn, Stage invalidated)
00478     :   Measure_<T>(sub, new Implementation(dependsOn, invalidated), 
00479                     AbstractMeasure::SetHandle()) {}
00480 
00482     Stage getDependsOnStage() const {return getImpl().getDependsOnStage();}
00484     Stage getInvalidatedStage() const {return getImpl().getInvalidatedStage();}
00492     Result& setDependsOnStage(Stage dependsOn) 
00493     {   updImpl().setDependsOnStage(dependsOn); return *this; }
00499     Result& setInvalidatedStage(Stage invalidated) 
00500     {   updImpl().setInvalidatedStage(invalidated); return *this; }
00501 
00514     Result& setIsPresumedValidAtDependsOnStage(bool presume)
00515     {   updImpl().setIsPresumedValidAtDependsOnStage(presume); return *this; }
00516 
00519     bool getIsPresumedValidAtDependsOnStage() const
00520     {   return getImpl().getIsPresumedValidAtDependsOnStage(); }
00521 
00522 
00528     T& updValue(const State& state) const
00529     {   return getImpl().updValue(state); }
00530 
00537     void markAsValid(const State& state) const {getImpl().markAsValid(state);}
00538 
00542     bool isValid(const State& state) const {return getImpl().isValid(state);}
00543 
00551     void markAsNotValid(const State& state) const 
00552     {   getImpl().markAsNotValid(state); }
00553 
00557     void setValue(const State& state, const T& value) const
00558     {   updValue(state) = value; markAsValid(state); }
00559 
00560     SimTK_MEASURE_HANDLE_POSTSCRIPT(Result, Measure_<T>);
00561 };
00562 
00563 //==============================================================================
00564 //                                 SINUSOID
00565 //==============================================================================
00572 template <class T>
00573 class Measure_<T>::Sinusoid : public Measure_<T> {
00574 public:
00575     SimTK_MEASURE_HANDLE_PREAMBLE(Sinusoid, Measure_<T>);
00576 
00577     Sinusoid(Subsystem& sub,
00578              const T& amplitude, 
00579              const T& frequency,
00580              const T& phase=T(0))
00581     :   Measure_<T>(sub, new Implementation(amplitude,frequency,phase), 
00582                     AbstractMeasure::SetHandle()) {}
00583 
00584     SimTK_MEASURE_HANDLE_POSTSCRIPT(Sinusoid, Measure_<T>);
00585 };
00586 
00587 //==============================================================================
00588 //                                   PLUS
00589 //==============================================================================
00594 template <class T>
00595 class Measure_<T>::Plus : public Measure_<T> {
00596 public:
00597     SimTK_MEASURE_HANDLE_PREAMBLE(Plus, Measure_<T>);
00598 
00599     Plus(Subsystem& sub, const Measure_<T>& left, const Measure_<T>& right)
00600     :   Measure_<T>(sub, new Implementation(left, right), 
00601                     AbstractMeasure::SetHandle())
00602     {   SimTK_ERRCHK_ALWAYS
00603            (   this->getSubsystem().isSameSubsystem(left.getSubsystem())
00604             && this->getSubsystem().isSameSubsystem(right.getSubsystem()),
00605             "Measure_<T>::Plus::ctor()",
00606             "Arguments must be in the same Subsystem as this Measure.");
00607     }
00608 
00609     SimTK_MEASURE_HANDLE_POSTSCRIPT(Plus, Measure_<T>);
00610 };
00611 
00612 //==============================================================================
00613 //                                   MINUS
00614 //==============================================================================
00619 template <class T>
00620 class Measure_<T>::Minus : public Measure_<T> {
00621 public:
00622     SimTK_MEASURE_HANDLE_PREAMBLE(Minus, Measure_<T>);
00623 
00624     Minus(Subsystem& sub, const Measure_<T>& left, const Measure_<T>& right)
00625     :   Measure_<T>(sub, new Implementation(left, right), 
00626                     AbstractMeasure::SetHandle())
00627     {   SimTK_ERRCHK_ALWAYS
00628            (   this->getSubsystem().isSameSubsystem(left.getSubsystem())
00629             && this->getSubsystem().isSameSubsystem(right.getSubsystem()),
00630             "Measure_<T>::Minus::ctor()",
00631             "Arguments must be in the same Subsystem as this Measure.");
00632     }
00633 
00634     SimTK_MEASURE_HANDLE_POSTSCRIPT(Minus, Measure_<T>);
00635 };
00636 
00637 //==============================================================================
00638 //                                   SCALE
00639 //==============================================================================
00644 template <class T>
00645 class Measure_<T>::Scale : public Measure_<T> {
00646 public:
00647     SimTK_MEASURE_HANDLE_PREAMBLE(Scale, Measure_<T>);
00648 
00649     Scale(Subsystem& sub, Real factor, const Measure_<T>& operand)
00650     :   Measure_<T>(sub, new Implementation(factor, operand), 
00651                     AbstractMeasure::SetHandle())
00652     {   SimTK_ERRCHK_ALWAYS
00653            (this->getSubsystem().isSameSubsystem(operand.getSubsystem()),
00654             "Measure_<T>::Scale::ctor()",
00655             "Argument must be in the same Subsystem as this Measure.");
00656     }
00657 
00659     const Measure_<T>& getOperandMeasure() const 
00660     { return getImpl().getOperandMeasure(); }
00661 
00662     SimTK_MEASURE_HANDLE_POSTSCRIPT(Scale, Measure_<T>);
00663 };
00664 
00665 //==============================================================================
00666 //                                 INTEGRATE
00667 //==============================================================================
00674 template <class T>
00675 class Measure_<T>::Integrate : public Measure_<T> {
00676 public:
00677     SimTK_MEASURE_HANDLE_PREAMBLE(Integrate, Measure_<T>);
00678 
00685     Integrate(Subsystem&            subsystem, 
00686               const Measure_<T>&    deriv, 
00687               const Measure_<T>&    ic,
00688               const T&              initAlloc=T(0))
00689     :   Measure_<T>(subsystem, new Implementation(deriv,ic,initAlloc), 
00690                     AbstractMeasure::SetHandle()) {}
00691 
00694     void setValue(State& s, const T& value) const 
00695     {   return getImpl().setValue(s, value); }
00696 
00698     const Measure_<T>& getDerivativeMeasure() const 
00699 
00700     {   return getImpl().getDerivativeMeasure(); }
00703     const Measure_<T>& getInitialConditionMeasure() const 
00704     {   return getImpl().getInitialConditionMeasure(); }
00705 
00706     Integrate& setDerivativeMeasure(const Measure_<T>& d)
00707     {   updImpl().setDerivativeMeasure(d); return *this; }
00708     Integrate& setInitialConditionMeasure(const Measure_<T>& ic)
00709     {   updImpl().setInitialConditionMeasure(ic); return *this; }
00710 
00711     SimTK_MEASURE_HANDLE_POSTSCRIPT(Integrate, Measure_<T>);
00712 };
00713 
00714 //==============================================================================
00715 //                               DIFFERENTIATE
00716 //==============================================================================
00741 template <class T>
00742 class Measure_<T>::Differentiate : public Measure_<T> {
00743 public:
00744     SimTK_MEASURE_HANDLE_PREAMBLE(Differentiate, Measure_<T>);
00745 
00750     Differentiate(Subsystem& subsystem, const Measure_<T>& operand)
00751     :   Measure_<T>(subsystem, new Implementation(operand), 
00752                     AbstractMeasure::SetHandle()) {}
00753 
00758     bool isUsingApproximation() const 
00759     {   return getImpl().isUsingApproximation(); }
00760 
00763     const Measure_<T>& getOperandMeasure() const 
00764     {   return getImpl().getOperandMeasure(); }
00765 
00769     Differentiate& setOperandMeasure(const Measure_<T>& operand)
00770     {   updImpl().setOperandMeasure(operand); return *this; }
00771 
00775     void setForceUseApproximation(bool mustApproximate)
00776     {   updImpl().setForceUseApproximation(mustApproximate); }
00777 
00782     bool getForceUseApproximation() const 
00783     {   return getImpl().getForceUseApproximation(); }
00784 
00785     SimTK_MEASURE_HANDLE_POSTSCRIPT(Differentiate, Measure_<T>);
00786 };
00787 
00788 //==============================================================================
00789 //                 EXTREME, MINIMUM, MAXIMUM, MINABS, MAXABS
00790 //==============================================================================
00834 template <class T>
00835 class Measure_<T>::Extreme : public Measure_<T> {
00836 public:
00837     SimTK_MEASURE_HANDLE_PREAMBLE(Extreme, Measure_<T>);
00838 
00839     enum Operation {
00840         MaxAbs, // default
00841         Maximum,
00842         MinAbs,
00843         Minimum
00844     };
00845 
00849     Extreme(Subsystem& sub, const Measure_<T>& operand, Operation op=MaxAbs)
00850     :   Measure_<T>(sub, new Implementation(operand, op), 
00851                     AbstractMeasure::SetHandle()) {}
00852 
00854     Extreme& setOperation(Operation op)
00855     {   updImpl().setOperation(op); return *this; }
00856 
00858     Operation getOperation() const {return getImpl().getOperation();}
00859 
00865     Real getTimeOfExtremeValue(const State& state) const
00866     {   return getImpl().getTimeOfExtremeValue(state); }
00867 
00868     void setValue(State& s, const T& value) const 
00869     {   return getImpl().setValue(s, value); }
00870 
00871     const Measure_<T>& getOperandMeasure() const 
00872     {   return getImpl().getOperandMeasure(); }
00873 
00874     Extreme& setOperandMeasure(const Measure_<T>& s)
00875     {   updImpl().setOperandMeasure(s); return *this; }
00876 
00877     SimTK_MEASURE_HANDLE_POSTSCRIPT(Extreme, Measure_<T>);
00878 };
00879 
00882 template <class T>
00883 class Measure_<T>::Minimum : public Measure_<T>::Extreme {
00884     typedef typename Measure_<T>::Extreme Super;
00885 public:
00886     Minimum(Subsystem& sub, const Measure_<T>& operand)
00887     :   Super(sub, operand, Super::Minimum) {}
00888 };
00889 
00892 template <class T>
00893 class Measure_<T>::Maximum : public Measure_<T>::Extreme {
00894     typedef typename Measure_<T>::Extreme Super;
00895 public:
00896     Maximum(Subsystem& sub, const Measure_<T>& operand)
00897     :   Super(sub, operand, Super::Maximum) {}
00898 };
00899 
00902 template <class T>
00903 class Measure_<T>::MaxAbs : public Measure_<T>::Extreme {
00904     typedef typename Measure_<T>::Extreme Super;
00905 public:
00906     MaxAbs(Subsystem& sub, const Measure_<T>& operand)
00907     :   Super(sub, operand, Super::MaxAbs) {}
00908 };
00909 
00913 template <class T>
00914 class Measure_<T>::MinAbs : public Measure_<T>::Extreme {
00915     typedef typename Measure_<T>::Extreme Super;
00916 public:
00917     MinAbs(Subsystem& sub, const Measure_<T>& operand)
00918     :   Super(sub, operand, Super::MinAbs) {}
00919 };
00920 
00921 //==============================================================================
00922 //                                 DELAY
00923 //==============================================================================
00970 template <class T>
00971 class Measure_<T>::Delay : public Measure_<T> {
00972 public:
00974     SimTK_MEASURE_HANDLE_PREAMBLE(Delay, Measure_<T>);
00979     Delay(Subsystem& sub, const Measure_<T>& source, Real delay)
00980     :   Measure_<T>(sub, new Implementation(source, delay), 
00981                     AbstractMeasure::SetHandle()) {}
00982 
00988     Delay& setUseLinearInterpolationOnly(bool linearOnly)
00989     {   updImpl().setUseLinearInterpolationOnly(linearOnly); return *this; }
00990 
01004     Delay& setCanUseCurrentValue(bool canUseCurrentValue)
01005     {   updImpl().setCanUseCurrentValue(canUseCurrentValue); return *this; }
01006 
01008     Delay& setSourceMeasure(const Measure_<T>& source)
01009     {   updImpl().setSourceMeasure(source); return *this; }
01010 
01012     Delay& setDelay(Real delay)
01013     {   updImpl().setDelay(delay); return *this; }
01014 
01016     bool getUseLinearInterpolationOnly() const
01017     {   return getImpl().getUseLinearInterpolationOnly(); }
01018 
01020     bool getCanUseCurrentValue() const
01021     {   return getImpl().getCanUseCurrentValue(); }
01022 
01024     const Measure_<T>& getSourceMeasure() const
01025     {   return getImpl().getSourceMeasure(); }
01026 
01029     Real getDelay() const
01030     {   return getImpl().getDelay(); }
01031 
01033     SimTK_MEASURE_HANDLE_POSTSCRIPT(Delay, Measure_<T>);
01035 };
01036 
01037 //==============================================================================
01038 //                              SAMPLE AND HOLD
01039 //==============================================================================
01054 template <class T>
01055 class Measure_<T>::SampleAndHold : public Measure_<T> {
01056 public:
01057     SimTK_MEASURE_HANDLE_PREAMBLE(SampleAndHold, Measure_<T>);
01058 
01059     SampleAndHold(Subsystem& sub, const Measure_<T>& source, EventId e);
01060 
01063     void setValue(State& s, const T& value) const;
01064 
01066     void sample(State& s) const;
01067 
01068     const Measure_<T>& getSource() const;
01069     EventId            getEventId() const;
01070 
01071     SampleAndHold& setSource(const Measure_<T>& s);
01072     SampleAndHold& setEventId(EventId);
01073 
01074     SimTK_MEASURE_HANDLE_POSTSCRIPT(SampleAndHold, Measure_<T>);
01075 };
01076 
01077 } // namespace SimTK
01078 
01079 #endif // SimTK_SimTKCOMMON_MEASURE_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines