1 #ifndef OPENSIM_FIRST_ORDER_MUSCLE_ACTIVATION_DYNAMICS_H_ 2 #define OPENSIM_FIRST_ORDER_MUSCLE_ACTIVATION_DYNAMICS_H_ 3 /* -------------------------------------------------------------------------- * 4 * OpenSim: FirstOrderMuscleActivationDynamics.h * 5 * -------------------------------------------------------------------------- * 6 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation. * 7 * See http://opensim.stanford.edu and the NOTICE file for more information. * 8 * OpenSim is developed at Stanford University and supported by the US * 9 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA * 10 * through the Warrior Web program. * 11 * * 12 * Copyright (c) 2005-2017 Stanford University and the Authors * 13 * Author(s): Thomas Uchida, Matthew Millard, Ajay Seth * 14 * * 15 * Licensed under the Apache License, Version 2.0 (the "License"); you may * 16 * not use this file except in compliance with the License. You may obtain a * 17 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. * 18 * * 19 * Unless required by applicable law or agreed to in writing, software * 20 * distributed under the License is distributed on an "AS IS" BASIS, * 21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 22 * See the License for the specific language governing permissions and * 23 * limitations under the License. * 24 * -------------------------------------------------------------------------- */ 25 26 #include <OpenSim/Actuators/osimActuatorsDLL.h> 27 #include <OpenSim/Actuators/MuscleActivationDynamics.h> 28 29 namespace OpenSim { 30 /** Computes muscle activation using a modified version of the first-order 31 dynamic models used by Thelen (2003) and Winters (1995). The time derivative 32 of activation (\f$da/dt\f$) is calculated as follows: 33 \f[ \frac{da}{dt} = \frac{u-a}{\tau(u,a)} \f] 34 where \f$u\f$ is excitation, \f$a\f$ is activation, and \f$\tau(u,a)\f$ is 35 an excitation- and activation-dependent time constant: 36 \f[ \tau(u,a) = \tau_{\rm{act}} (0.5 + 1.5a) \quad {\rm{if}}\ u > a \f] 37 \f[ \tau(u,a) = \tau_{\rm{deact}} / (0.5 + 1.5a) \quad {\rm{otherwise}} \f] 38 Typical values for activation (\f$\tau_{\rm{act}}\f$) and deactivation 39 (\f$\tau_{\rm{deact}}\f$) time constants are 10 ms and 40 ms, respectively. 40 41 Three properties are inherited from the base MuscleActivationDynamics class: 42 \c minimum_activation, \c maximum_activation, and \c default_activation. 43 Note that equilibrium muscle models typically have a numerical singularity 44 in their state equations when activation is zero, so care should be taken 45 when setting \c minimum_activation to zero. Minimum activation values 46 between 0.01 and 0.1 are typically used with equilibrium muscle models. 47 48 <b>Properties</b> 49 \li \c activation_time_constant: Activation time constant (in seconds). 50 \li \c deactivation_time_constant: Deactivation time constant (in seconds). 51 52 <b>Conditions</b> 53 \verbatim 54 activation_time_constant > 0 55 deactivation_time_constant > 0 56 \endverbatim 57 58 <b>Default %Property Values</b> 59 \verbatim 60 activation_time_constant ...... 0.010 61 deactivation_time_constant .... 0.040 62 minimum_activation ............ 0.01 63 maximum_activation ............ 1 64 default_activation ............ 0.5 65 \endverbatim 66 67 <b>References</b> 68 \li Thelen, D.G. (2003) Adjustment of muscle mechanics model parameters to 69 simulate dynamic contractions in older adults. ASME Journal of 70 Biomechanical Engineering 125(1):70--77. 71 \li Winters, J.M. (1995) An improved muscle-reflex actuator for use in 72 large-scale neuromusculoskeletal models. Annals of Biomedical 73 Engineering 23(4):359--374. 74 75 @author Thomas Uchida, Matthew Millard, Ajay Seth 76 **/ 77 78 class OSIMACTUATORS_API FirstOrderMuscleActivationDynamics : 79 public MuscleActivationDynamics { 80 OpenSim_DECLARE_CONCRETE_OBJECT(FirstOrderMuscleActivationDynamics, 81 MuscleActivationDynamics); 82 public: 83 84 //============================================================================== 85 // PROPERTIES 86 //============================================================================== 87 OpenSim_DECLARE_PROPERTY(activation_time_constant, double, 88 "Activation time constant (in seconds)"); 89 OpenSim_DECLARE_PROPERTY(deactivation_time_constant, double, 90 "Deactivation time constant (in seconds)"); 91 92 //============================================================================== 93 // PUBLIC METHODS 94 //============================================================================== 95 /** @name Constructors **/ 96 //@{ 97 98 /** Creates a first-order activation dynamic model with the default property 99 values and assigns it a default name. An %ExcitationGetter must be 100 created for obtaining muscle excitation. **/ 101 FirstOrderMuscleActivationDynamics(); 102 103 /** Creates a first-order activation dynamic model with the default property 104 values, the specified name, and the specified %ExcitationGetter. Takes 105 ownership of the %ExcitationGetter object. **/ 106 FirstOrderMuscleActivationDynamics(const std::string& name, 107 ExcitationGetter* getter); 108 //@} 109 110 //-------------------------------------------------------------------------- 111 // ACCESSORS AND MUTATORS 112 //-------------------------------------------------------------------------- 113 /** @name Accessors and Mutators **/ 114 //@{ 115 116 /** Get the activation time constant. **/ 117 double getActivationTimeConstant() const; 118 /** %Set the activation time constant to a value greater than zero. **/ 119 void setActivationTimeConstant(double activationTimeConstant); 120 121 /** Get the deactivation time constant. **/ 122 double getDeactivationTimeConstant() const; 123 /** %Set the deactivation time constant to a value greater than zero. **/ 124 void setDeactivationTimeConstant(double deactivationTimeConstant); 125 126 //@} 127 128 //-------------------------------------------------------------------------- 129 // MODELCOMPONENT INTERFACE REQUIREMENTS 130 //-------------------------------------------------------------------------- 131 /** @name ModelComponent Interface Requirements **/ 132 //@{ 133 134 /** Adds activation to the state. **/ 135 void extendAddToSystem(SimTK::MultibodySystem& system) const override; 136 137 /** Initializes the activation state variable to \c default_activation. **/ 138 void extendInitStateFromProperties(SimTK::State& s) const override; 139 140 /** Sets \c default_activation to the current value of the activation state 141 variable. **/ 142 void extendSetPropertiesFromState(const SimTK::State& s) override; 143 144 /** Calculates the time derivative of activation using a first-order dynamic 145 model. Respects the lower bound on activation while preserving the 146 expected steady-state value. **/ 147 void computeStateVariableDerivatives(const SimTK::State& s) const override; 148 149 //@} 150 151 //-------------------------------------------------------------------------- 152 // STATE-DEPENDENT METHODS 153 //-------------------------------------------------------------------------- 154 /** Get the current activation from the state. **/ 155 double getActivation(const SimTK::State& s) const override; 156 157 /** %Set activation state variable to the value provided. **/ 158 void setActivation(SimTK::State& s, double activation) const override; 159 160 //============================================================================== 161 // PRIVATE METHODS 162 //============================================================================== 163 private: 164 void setNull(); 165 void constructProperties(); 166 167 /** Implementation of a first-order activation dynamic model that respects 168 the lower bound on activation while preserving the expected steady-state 169 value. **/ 170 double calcActivationDerivative(double excitation, double activation) const; 171 172 static const std::string STATE_NAME_ACTIVATION; 173 174 }; // end of class FirstOrderMuscleActivationDynamics 175 } // end of namespace OpenSim 176 177 #endif //OPENSIM_FIRST_ORDER_MUSCLE_ACTIVATION_DYNAMICS_H_ 178