Simbody
|
00001 #ifndef SimTK_SIMBODY_MOTION_H_ 00002 #define SimTK_SIMBODY_MOTION_H_ 00003 /* -------------------------------------------------------------------------- * 00004 * SimTK Core: SimTK Simbody(tm) * 00005 * -------------------------------------------------------------------------- * 00006 * This is part of the SimTK Core biosimulation toolkit originating from * 00007 * Simbios, the NIH National Center for Physics-Based Simulation of * 00008 * Biological Structures at Stanford, funded under the NIH Roadmap for * 00009 * Medical Research, grant U54 GM072970. See https://simtk.org. * 00010 * * 00011 * Portions copyright (c) 2009 Stanford University and the Authors. * 00012 * Authors: Michael Sherman * 00013 * Contributors: * 00014 * * 00015 * Permission is hereby granted, free of charge, to any person obtaining a * 00016 * copy of this software and associated documentation files (the "Software"), * 00017 * to deal in the Software without restriction, including without limitation * 00018 * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 00019 * and/or sell copies of the Software, and to permit persons to whom the * 00020 * Software is furnished to do so, subject to the following conditions: * 00021 * * 00022 * The above copyright notice and this permission notice shall be included in * 00023 * all copies or substantial portions of the Software. * 00024 * * 00025 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * 00026 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * 00027 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * 00028 * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 00029 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 00030 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * 00031 * USE OR OTHER DEALINGS IN THE SOFTWARE. * 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 // We only want the template instantiation to occur once. This symbol is defined 00050 // in the Simbody compilation unit that defines the Motion class but should not 00051 // be defined any other time. 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 // This implements the above table. Given the (level,method) Motion specification, 00133 // it reports the actual method to be used for each of the three levels. 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]; // acc, vel, pos 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); // instantiated in library 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); // instantiated in library 00233 00234 Real getDefaultRate(UIndex=UIndex(0)) const; 00235 00236 void setRate(State&, Real u) const; // all axes set to u 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 /*NOTREACHED*/ 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 } // namespace SimTK 00434 00435 #endif // SimTK_SIMBODY_MOTION_H_