00001 #ifndef SimTK_SIMBODY_MOTION_H_
00002 #define SimTK_SIMBODY_MOTION_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
00039 #include "SimTKcommon.h"
00040 #include "simbody/internal/common.h"
00041
00042 namespace SimTK {
00043
00044 class SimbodyMatterSubsystem;
00045 class MobilizedBody;
00046 class Motion;
00047 class MotionImpl;
00048
00049
00050
00051
00052 #ifndef SimTK_SIMBODY_DEFINING_MOTION
00053 extern template class PIMPLHandle<Motion, MotionImpl, true>;
00054 #endif
00055
00093 class SimTK_SIMBODY_EXPORT Motion : public PIMPLHandle<Motion, MotionImpl, true> {
00094 public:
00097 enum Level {
00098 Acceleration = 0,
00099 Velocity = 1,
00100 Position = 2
00101 };
00105 static const char* nameOfLevel(Level);
00106
00111 enum Method {
00112 Zero = 0,
00113 Discrete = 1,
00114 Prescribed = 2,
00115 Free = 3,
00116 Fast = 4
00117 };
00121 static const char* nameOfMethod(Method);
00122
00123 Motion() { }
00124 explicit Motion(MotionImpl* r) : HandleBase(r) { }
00125
00127 const MobilizedBody& getMobilizedBody() const;
00128
00129 Level getLevel(const State&) const;
00130 Method getLevelMethod(const State&) const;
00131
00132
00133
00134 void calcAllMethods(const State& s, Method& qMethod, Method& uMethod, Method& udotMethod) const {
00135 const Level level = getLevel(s);
00136 const Method levelMethod = getLevelMethod(s);
00137 Method method[3];
00138 method[level] = levelMethod;
00139
00140 switch (level) {
00141 case Position:
00142 method[Velocity]=method[Acceleration]=
00143 (levelMethod==Prescribed ? Prescribed : Zero);
00144 break;
00145 case Velocity:
00146 method[Acceleration] = (levelMethod==Prescribed ? Prescribed : Zero);
00147 method[Position] = (levelMethod==Zero ? Discrete : Free);
00148 break;
00149 case Acceleration:
00150 method[Velocity] = (levelMethod==Zero ? Discrete : Free);
00151 method[Position] = Free;
00152 break;
00153 default:
00154 assert(!"unrecognized level");
00155 }
00156
00157 qMethod = method[Position];
00158 uMethod = method[Velocity];
00159 udotMethod = method[Acceleration];
00160 }
00161
00162 class Steady;
00163 class Linear;
00164 class Sinusoid;
00165 class Polynomial;
00166 class Composite;
00167 class Custom;
00168
00169 class SteadyImpl;
00170 class LinearImpl;
00171 class SinusoidImpl;
00172 class PolynomialImpl;
00173 class CompositeImpl;
00174 class CustomImpl;
00175 };
00176
00181 class SimTK_SIMBODY_EXPORT Motion::Sinusoid : public Motion {
00182 public:
00200 Sinusoid(MobilizedBody& mobod, Motion::Level level,
00201 Real amplitude, Real rate, Real phase);
00202
00203 SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(Sinusoid, SinusoidImpl, Motion);
00204 };
00205
00209 class SimTK_SIMBODY_EXPORT Motion::Steady : public Motion {
00210 public:
00217 Steady(MobilizedBody& mobod, Real u);
00226 template <int N> SimTK_SIMBODY_EXPORT
00227 Steady(MobilizedBody& mobod, const Vec<N>& u);
00228
00229 Steady& setDefaultRate(Real u);
00230 Steady& setOneDefaultRate(UIndex, Real u);
00231 template <int N> SimTK_SIMBODY_EXPORT
00232 Steady& setDefaultRates(const Vec<N>& u);
00233
00234 Real getDefaultRate(UIndex=UIndex(0)) const;
00235
00236 void setRate(State&, Real u) const;
00237 void setOneRate(State&, UIndex, Real u) const;
00238
00239 SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(Steady, SteadyImpl, Motion);
00240 };
00241
00242
00275 class SimTK_SIMBODY_EXPORT Motion::Custom : public Motion {
00276 public:
00277 class Implementation;
00287 Custom(MobilizedBody& mobod, Implementation* implementation);
00288 SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(Custom, CustomImpl, Motion);
00289 protected:
00290 const Implementation& getImplementation() const;
00291 Implementation& updImplementation();
00292 };
00293
00297 class SimTK_SIMBODY_EXPORT Motion::Custom::Implementation {
00298 public:
00300 virtual ~Implementation() { }
00301
00303 virtual Implementation* clone() const {
00304 SimTK_ERRCHK_ALWAYS(!"unimplemented",
00305 "Motion::Custom::Implementation::clone()",
00306 "Concrete Implementation did not supply a clone() method, "
00307 "but a copy operation was attempted.");
00308
00309 return 0;
00310 }
00311
00322 virtual Motion::Level getLevel(const State&) const = 0;
00323
00324 virtual Motion::Method getLevelMethod(const State&) const {
00325 return Motion::Prescribed;
00326 }
00327
00334
00335
00336
00337
00338
00339 virtual void calcPrescribedPosition(const State& s, int nq, Real* q) const;
00340
00352 virtual void calcPrescribedPositionDot(const State& s, int nq, Real* qdot) const;
00353
00366 virtual void calcPrescribedPositionDotDot(const State& s, int nq, Real* qdotdot) const;
00368
00375
00376
00377
00378
00379
00380
00381
00382 virtual void calcPrescribedVelocity(const State& s, int nu, Real* u) const;
00383
00394 virtual void calcPrescribedVelocityDot(const State& s, int nu, Real* udot) const;
00396
00404
00405
00406
00407
00408
00409
00410 virtual void calcPrescribedAcceleration(const State& s, int nu, Real* udot) const;
00412
00421 virtual void realizeTopology (State& state) const {}
00422 virtual void realizeModel (State& state) const {}
00423 virtual void realizeInstance (const State& state) const {}
00424 virtual void realizeTime (const State& state) const {}
00425 virtual void realizePosition (const State& state) const {}
00426 virtual void realizeVelocity (const State& state) const {}
00427 virtual void realizeDynamics (const State& state) const {}
00428 virtual void realizeAcceleration(const State& state) const {}
00429 virtual void realizeReport (const State& state) const {}
00431 };
00432
00433 }
00434
00435 #endif // SimTK_SIMBODY_MOTION_H_