1 #ifndef OPENSIM_UMBERGER2010_METABOLIC_POWER_PROBE_H_ 2 #define OPENSIM_UMBERGER2010_METABOLIC_POWER_PROBE_H_ 3 /* -------------------------------------------------------------------------- * 4 * OpenSim: Umberger2010MuscleMetabolicsProbe.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): Tim Dorn * 14 * Contributor(s): Thomas Uchida * 15 * * 16 * Licensed under the Apache License, Version 2.0 (the "License"); you may * 17 * not use this file except in compliance with the License. You may obtain a * 18 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. * 19 * * 20 * Unless required by applicable law or agreed to in writing, software * 21 * distributed under the License is distributed on an "AS IS" BASIS, * 22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 23 * See the License for the specific language governing permissions and * 24 * limitations under the License. * 25 * -------------------------------------------------------------------------- */ 26 27 #include "Probe.h" 28 #include <OpenSim/Common/Set.h> 29 30 namespace OpenSim { 31 32 class Model; 33 class Muscle; 34 35 // Helper classes defined below. 36 class Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameter; 37 class Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameterSet; 38 39 //============================================================================= 40 // MUSCLE METABOLIC POWER PROBE (Umberger, et al., 2010) 41 //============================================================================= 42 43 /** 44 * %Umberger2010MuscleMetabolicsProbe is a Probe ModelComponent for computing 45 * the net metabolic energy rate of a set of Muscles in the model during a 46 * simulation. 47 * 48 * <h1>%Umberger2010MuscleMetabolicsProbe Theory</h1> 49 * 50 * The discussion here is based on the following papers: 51 * 52 * <a href="http://dx.doi.org/10.1371/journal.pone.0150378"> 53 * Uchida, T. K., Hicks, J. L., Dembia, C. L., Delp, S. L. (2016). Stretching 54 * your energetic budget: how tendon compliance affects the metabolic cost of 55 * running. PLOS ONE 11(3), e0150378.</a> 56 * 57 * <a href="http://www.ncbi.nlm.nih.gov/pubmed/20356877"> 58 * Umberger, B. R. (2010). Stance and swing phase costs in human walking. 59 * J R Soc Interface 7, 1329-40.</a> 60 * 61 * <a href="http://www.ncbi.nlm.nih.gov/pubmed/12745424"> 62 * Umberger, B. R., Gerritsen, K. G. and Martin, P. E. (2003). 63 * A model of human muscle energy expenditure. 64 * Comput Methods Biomech Biomed Engin 6, 99-111.</a> 65 * 66 * <I>Note that the equations below that describe the particular implementation 67 * of %Umberger2010MuscleMetabolicsProbe may slightly differ from the equations 68 * described in the representative publications above. Note also that we define 69 * positive muscle velocity to indicate lengthening (eccentric contraction) and 70 * negative muscle velocity to indicate shortening (concentric contraction).</I> 71 * 72 * 73 * %Muscle metabolic power (or rate of metabolic energy consumption) is equal to 74 * the rate at which heat is liberated plus the rate at which work is done:\n 75 * <B>Edot = Bdot + sumOfAllMuscles(Adot + Mdot + Sdot + Wdot).</B> 76 * 77 * - Bdot is the basal heat rate (W). 78 * - Adot is the activation heat rate (W). 79 * - Mdot is the maintenance heat rate (W). 80 * - Sdot is the shortening heat rate (W). 81 * - Wdot is the mechanical work rate (W). 82 * 83 * 84 * This probe also uses muscle parameters stored in the MetabolicMuscle object for each muscle. 85 * The full set of all MetabolicMuscles (MetabolicMuscleSet) is a property of this probe: 86 * 87 * - m = The mass of the muscle (kg). 88 * - r = Ratio of slow-twitch fibers in the muscle (between 0 and 1). 89 * 90 * The recruitment model described by Bhargava et al. (2004) is used to set the 91 * slow-twitch fiber ratio used in the calculations below. The ratio specified 92 * by the user indicates the composition of the muscle; this value is used only 93 * at full excitation (i.e., when all fibers are recruited). As excitation 94 * decreases from 1 to 0, the proportion of recruited fibers that are 95 * slow-twitch fibers increases from r to 1. See 96 * <a href="http://www.ncbi.nlm.nih.gov/pubmed/14672571">Bhargava, L.J., Pandy, 97 * M.G., Anderson, F.C. (2004) A phenomenological model for estimating metabolic 98 * energy consumption in muscle contraction. J Biomech 37:81-88</a> and Uchida 99 * et al. (2016). To assume a constant ratio of slow- and fast-twitch fiber 100 * recruitment, set the 'use_Bhargava_recruitment_model' property to false. 101 * 102 * 103 * 104 * <H2><B> BASAL HEAT RATE (W) </B></H2> 105 * If <I>basal_rate_on</I> is set to true, then Bdot is calculated as follows:\n 106 * <B>Bdot = basal_coefficient * (m_body^basal_exponent) </B> 107 * - m_body = mass of the entire model 108 * - basal_coefficient and basal_exponent are defined by their respective properties.\n 109 * <I>Note that this quantity is muscle independent. Rather it is calculated on a whole body level.</I> 110 * 111 * 112 * <H2><B> ACTIVATION & MAINTENANCE HEAT RATE (W) </B></H2> 113 * If <I>activation_maintenance_rate_on</I> is set to true, then Adot+Mdot is calculated as follows:\n 114 * <B>Adot+Mdot = [128*(1-r) + 25] * A^0.6 * S </B>, <I> l_CE <= l_CE_opt </I>\n 115 * <B>Adot+Mdot = (0.4*[128*(1-r) + 25] + 0.6*[128*(1-r) + 25]*F_CE_iso) * A^0.6 * S </B>, <I> l_CE > l_CE_opt </I> 116 * - <B>A = u </B>, u > a 117 * - <B>A = (u+a)/2 </B>, u <= a 118 * 119 * - m = The mass of the muscle (kg). 120 * - l_CE = muscle fiber length at the current time. 121 * - l_CE_opt = optimal fiber length of the muscle. 122 * - F_CE_iso = normalized contractile element force-length curve. 123 * - u = muscle excitation at the current time. 124 * - a = muscle activation at the current time. 125 * - S = aerobic/anaerobic scaling factor, defined by the 'aerobic_factor' property (i.e. usually 1.0 for primarily anaerobic activities, 1.5 for primarily aerobic activities). 126 * 127 * 128 * <H2><B> SHORTENING HEAT RATE (W) </B></H2> 129 * If <I>shortening_rate_on</I> is set to true, then Sdot is calculated as follows:\n 130 * <B>Sdot = m * (-[(alphaS_slow * v_CE_norm * r) + (alphaS_fast * v_CE_norm * (1-r))] * A^2 * S) </B>, <I>l_CE <= l_CE_opt & v_CE >= 0 (concentric / isometric contraction)</I>\n 131 * <B>Sdot = m * (-[(alphaS_slow * v_CE_norm * r) + (alphaS_fast * v_CE_norm * (1-r))] * A^2 * S * F_iso) </B>, <I>l_CE > l_CE_opt & v_CE >= 0 (concentric / isometric contraction)</I>\n 132 * <B>Sdot = m * (alphaL * v_CE_norm * A * S) </B>, <I>l_CE <= l_CE_opt & v_CE < 0 (eccentric contraction)</I>\n 133 * <B>Sdot = m * (alphaL * v_CE_norm * A * S * F_CE_iso) </B>, <I>l_CE > l_CE_opt & v_CE < 0 (eccentric contraction)</I> 134 * - <B>A = u </B>, <I>u > a </I> 135 * - <B>A = (u+a)/2 </B>, <I>u <= a </I> 136 * 137 * - <B>alphaS_fast = 153 / v_CE_max </B> 138 * - <B>alphaS_slow = 100 / (v_CE_max / 2.5) </B> 139 * - <B>alphaL = 4.0 * alphaS_slow </B> 140 * 141 * - m = The mass of the muscle (kg). 142 * - l_CE = muscle fiber length at the current time. 143 * - l_CE_opt = optimal fiber length of the muscle. 144 * - F_CE_iso = force that would be developed by the contractile element of muscle under isometric conditions with the current activation and fiber length. 145 * - v_CE = muscle fiber velocity at the current time. 146 * - v_CE_max = maximum shortening velocity of the muscle. 147 * - v_CE_norm = normalized muscle fiber velocity (defined for this model as v_CE/l_CE_opt). 148 * Note that this is a different metric to the typical normalized_muscle_fiber_velocity of v_CE/v_CE_max. 149 * - S = aerobic/anaerobic scaling factor, defined by the 'aerobic_factor' property (i.e. usually 1.0 for primarily anaerobic activities, 1.5 for primarily aerobic activities). 150 * 151 * 152 * <H2><B> MECHANICAL WORK RATE (W) </B></H2> 153 * If <I>mechanical_work_rate_on</I> is set to true, then Wdot is calculated as follows:\n 154 * <B>Wdot = -(F_CE * v_CE) </B> 155 * - v_CE = muscle fiber velocity at the current time. 156 * - F_CE = force developed by the contractile element of muscle at the current time.\n 157 * 158 * If we draw a control volume around the fiber, the first law of thermodynamics 159 * suggests that negative mechanical work should be included in Wdot. As such, 160 * we revert back to the model described in Umberger et al. (2003) by default. 161 * To exclude negative mechanical work from Wdot and use a coefficient of 0.3 162 * (rather than 4.0) to calculate alpha_L, set the 163 * 'include_negative_mechanical_work' property to false. 164 * 165 * During eccentric contraction, the magnitude of the (negative) mechanical work 166 * rate can exceed that of the total (positive) heat rate, resulting in a flow 167 * of energy into the fiber. Experiments indicate that the chemical processes 168 * involved in fiber contraction cannot be reversed, and most of the energy that 169 * is absorbed during eccentric contraction (in increased cross-bridge 170 * potentials, for example) is eventually converted into heat. Thus, we increase 171 * Sdot (if necessary) to ensure Edot > 0 for each muscle. See 172 * <a href="http://www.ncbi.nlm.nih.gov/pubmed/9409483">Constable, J.K., 173 * Barclay, C.J., Gibbs, C.L. (1997) Energetics of lengthening in mouse and toad 174 * skeletal muscles. J Physiol 505:205-215</a> and Uchida et al. (2016). To 175 * allow muscles to have negative total power, set the 176 * 'forbid_negative_total_power' property to false. 177 * 178 * 179 * Note that if enforce_minimum_heat_rate_per_muscle == true AND 180 * activation_maintenance_rate_on == shortening_rate_on == true, then the total heat 181 * rate (AMdot + Sdot) will be capped to a minimum value of 1.0 W/kg (Umberger(2003), page 104). 182 * 183 * 184 * 185 * 186 * <H1>Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameter</H1> 187 * 188 * Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameter is an Object class that 189 * holds the metabolic parameters required to calculate metabolic power for a single muscle. 190 * 191 * <H2><B> Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameter Properties </B></H2> 192 * 193 * REQUIRED PROPERTIES 194 * - <B>specific_tension</B> = The specific tension of the muscle (Pascals (N/m^2)). 195 * - <B>density</B> = The density of the muscle (kg/m^3). 196 * - <B>ratio_slow_twitch_fibers</B> = Ratio of slow twitch fibers in the muscle (must be between 0 and 1). 197 * 198 * OPTIONAL PROPERTIES 199 * - <B>use_provided_muscle_mass</B> = An optional flag that allows the user to 200 * explicitly specify a muscle mass. If set to true, the 'provided_muscle_mass' 201 * property must be specified. The default setting is false, in which case, the 202 * muscle mass is calculated from the following formula: 203 * m = (Fmax/specific_tension)*density*Lm_opt, where 204 * specific_tension and density are properties defined above 205 * (note that their default values are set based on mammalian muscle, 206 * 0.25e6 N/m^2 and 1059.7 kg/m^3, respectively); 207 * Fmax and Lm_opt are the maximum isometric force and optimal 208 * fiber length, respectively, of the muscle. 209 * 210 * - <B>provided_muscle_mass</B> = The user specified muscle mass (kg). 211 * 212 * 213 * @author Tim Dorn 214 */ 215 216 class OSIMSIMULATION_API Umberger2010MuscleMetabolicsProbe : public Probe { 217 OpenSim_DECLARE_CONCRETE_OBJECT(Umberger2010MuscleMetabolicsProbe, Probe); 218 public: 219 //============================================================================== 220 // PROPERTIES 221 //============================================================================== 222 /** Enabled by default. **/ 223 OpenSim_DECLARE_PROPERTY(activation_maintenance_rate_on, 224 bool, 225 "Specify whether activation & maintenance heat rate is to be calculated (true/false)."); 226 227 /** Enabled by default. **/ 228 OpenSim_DECLARE_PROPERTY(shortening_rate_on, 229 bool, 230 "Specify whether shortening heat rate is to be calculated (true/false)."); 231 232 /** Enabled by default. **/ 233 OpenSim_DECLARE_PROPERTY(basal_rate_on, 234 bool, 235 "Specify whether basal heat rate is to be calculated (true/false)."); 236 237 /** Enabled by default. **/ 238 OpenSim_DECLARE_PROPERTY(mechanical_work_rate_on, 239 bool, 240 "Specify whether mechanical work rate is to be calculated (true/false)."); 241 242 /** Enabled by default. **/ 243 OpenSim_DECLARE_PROPERTY(enforce_minimum_heat_rate_per_muscle, 244 bool, 245 "Specify whether the total heat rate for a muscle will be clamped to a " 246 "minimum value of 1.0 W/kg (true/false)."); 247 248 /** Default value = 1.5. **/ 249 OpenSim_DECLARE_PROPERTY(aerobic_factor, 250 double, 251 "Aerobic scale factor (S=1.0 for primarily anaerobic conditions and S=1.5 " 252 "for primarily aerobic conditions. See Umberger et al., (2003)."); 253 254 /** Default value = 1.2. **/ 255 OpenSim_DECLARE_PROPERTY(basal_coefficient, 256 double, 257 "Basal metabolic coefficient."); 258 259 /** Default value = 1.0. **/ 260 OpenSim_DECLARE_PROPERTY(basal_exponent, 261 double, 262 "Basal metabolic exponent."); 263 264 /** Default value = 1.0. **/ 265 OpenSim_DECLARE_PROPERTY(muscle_effort_scaling_factor, 266 double, 267 "Scale the excitation and activation values used by the probe to " 268 "compensate for solutions with excessive coactivation (e.g., when a " 269 "suboptimal tracking strategy is used)."); 270 271 /** Enabled by default. **/ 272 OpenSim_DECLARE_PROPERTY(use_Bhargava_recruitment_model, 273 bool, 274 "Specify whether the recruitment model described by Bhargava et al. " 275 "(2004) will used to determine the slow-twitch fiber ratio " 276 "(true/false). Disable to use the model as published in Umberger " 277 "(2010)."); 278 279 /** Enabled by default. **/ 280 OpenSim_DECLARE_PROPERTY(include_negative_mechanical_work, 281 bool, 282 "Specify whether negative mechanical work will be included in Wdot and " 283 "a coefficient of 4.0 will be used to calculate alpha_L (true/false). " 284 "Disable to use the model as published in Umberger (2010)."); 285 286 /** Enabled by default. **/ 287 OpenSim_DECLARE_PROPERTY(forbid_negative_total_power, 288 bool, 289 "Specify whether the total power for each muscle must remain positive " 290 "(true/false). Disable to use the model as published in Umberger " 291 "(2010)."); 292 293 /** Default value = true **/ 294 OpenSim_DECLARE_PROPERTY(report_total_metabolics_only, 295 bool, 296 "If set to false, the individual muscle metabolics, basal rate, and " 297 "total summation will be reported. If set to true, only the total " 298 "summation will be reported."); 299 300 OpenSim_DECLARE_UNNAMED_PROPERTY( 301 Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameterSet, 302 "A set containing, for each muscle, the parameters " 303 "required to calculate muscle metabolic power."); 304 305 //============================================================================= 306 // PUBLIC METHODS 307 //============================================================================= 308 /** MuscleMap typedef */ 309 typedef std::map 310 <std::string, 311 Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameter*> 312 MuscleMap; 313 314 //-------------------------------------------------------------------------- 315 // Constructor(s) and Setup 316 //-------------------------------------------------------------------------- 317 /** Default constructor */ 318 Umberger2010MuscleMetabolicsProbe(); 319 320 /** Convenience constructor */ 321 Umberger2010MuscleMetabolicsProbe( 322 const bool activation_maintenance_rate_on, 323 const bool shortening_rate_on, 324 const bool basal_rate_on, 325 const bool work_rate_on); 326 327 328 //----------------------------------------------------------------------------- 329 // Computation 330 //----------------------------------------------------------------------------- 331 /** Compute muscle metabolic power. */ 332 virtual SimTK::Vector computeProbeInputs(const SimTK::State& state) const override; 333 334 /** Returns the number of probe inputs in the vector returned by computeProbeInputs(). */ 335 int getNumProbeInputs() const override; 336 337 /** Returns the column labels of the probe values for reporting. 338 Currently uses the Probe name as the column label, so be sure 339 to name your probe appropriately! */ 340 virtual OpenSim::Array<std::string> getProbeOutputLabels() const override; 341 342 343 //----------------------------------------------------------------------------- 344 /** @name Umberger2010MuscleMetabolicsProbe Interface 345 These accessor methods are to be used when setting up a new muscle 346 metabolic analysis from the API. The basic operation is as follows: 347 @code 348 Umberger2010MuscleMetabolicsProbe* myProbe new Umberger2010MuscleMetabolicsProbe(...); 349 model.addProbe(myProbe); 350 myProbe->addMuscle("muscleName1", ... ); 351 myProbe->addMuscle("muscleName2", ... ); 352 myProbe->addMuscle("muscleName3", ... ); 353 myProbe->useProvidedMass("muscleName1", 1.2); // muscle1 mass = 1.2 kg 354 myProbe->useCalculatedMass("muscleName2"); // muscle2 mass is based on muscle properties (below) 355 myProbe->setDensity("muscleName2", 1100.0); // muscle2 density is 1100 kg/m^3 356 myProbe->setSpecificTension("muscleName2", 0.26e6); // muscle2 specific tension is 0.26e6 Pa 357 myProbe->removeMuscle("muscleName3"); 358 myProbe->setOperation("integrate") // See OpenSim::Probe for other operations 359 @endcode 360 @note It is important to first add the metabolic probe to the model before 361 calling any other methods that may modify its properties. This is because 362 some methods (e.g. addMuscle() or useCalculatedMass) may require information 363 about the muscles to successfully execute, and this information can only be 364 obtained if the metabolic probe is already 'connected' to the model. 365 */ 366 /** Get the number of muscles being analyzed in the metabolic analysis. */ 367 const int getNumMetabolicMuscles() const; 368 369 /** Add a muscle and its parameters so that it can be included in the metabolic analysis. */ 370 void addMuscle(const std::string& muscleName, 371 double ratio_slow_twitch_fibers); 372 373 /** Add a muscle and its parameters so that it can be included in the metabolic analysis. */ 374 void addMuscle(const std::string& muscleName, 375 double ratio_slow_twitch_fibers, 376 double muscle_mass); 377 378 /** Remove a muscle from the metabolic analysis. */ 379 void removeMuscle(const std::string& muscleName); 380 381 /** %Set an existing muscle to use a provided muscle mass. */ 382 void useProvidedMass(const std::string& muscleName, double providedMass); 383 384 /** %Set an existing muscle to calculate its own mass. */ 385 void useCalculatedMass(const std::string& muscleName); 386 387 /** Get whether the muscle mass is being explicitly provided. 388 True means that it is using the property 'provided_muscle_mass' 389 False means that the muscle mass is being calculated from muscle properties. */ 390 bool isUsingProvidedMass(const std::string& muscleName); 391 392 /** Get the muscle mass used in the metabolic analysis. The value 393 returned will depend on if the muscle mass is explicitly provided 394 (i.e. isUsingProvidedMass = true), or if it is being automatically 395 calculated from muscle data already present in the model 396 (i.e. isUsingProvidedMass = true). */ 397 const double getMuscleMass(const std::string& muscleName) const; 398 399 /** Get the ratio of slow twitch fibers for an existing muscle. */ 400 const double getRatioSlowTwitchFibers(const std::string& muscleName) const; 401 402 /** %Set the ratio of slow twitch fibers for an existing muscle. */ 403 void setRatioSlowTwitchFibers(const std::string& muscleName, const double& ratio); 404 405 /** Get the density for an existing muscle (kg/m^3). */ 406 const double getDensity(const std::string& muscleName) const; 407 408 /** %Set the density for an existing muscle (kg/m^3). */ 409 void setDensity(const std::string& muscleName, const double& density); 410 411 /** Get the specific tension for an existing muscle (Pascals (N/m^2)). */ 412 const double getSpecificTension(const std::string& muscleName) const; 413 414 /** %Set the specific tension for an existing muscle (Pascals (N/m^2)). */ 415 void setSpecificTension(const std::string& muscleName, const double& specificTension); 416 417 418 419 //============================================================================== 420 // PRIVATE 421 //============================================================================== 422 private: 423 //-------------------------------------------------------------------------- 424 // Data 425 //-------------------------------------------------------------------------- 426 MuscleMap _muscleMap; 427 428 //-------------------------------------------------------------------------- 429 // ModelComponent Interface 430 //-------------------------------------------------------------------------- 431 void extendConnectToModel(Model& aModel) override; 432 void connectIndividualMetabolicMuscle 433 (Model& aModel, 434 Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameter& mm); 435 436 void setNull(); 437 void constructProperties(); 438 439 440 //-------------------------------------------------------------------------- 441 // MetabolicMuscleParameter Private Interface 442 //-------------------------------------------------------------------------- 443 // Get const MetabolicMuscleParameter from the MuscleMap using a string accessor. 444 const Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameter* 445 getMetabolicParameters(const std::string& muscleName) const; 446 447 // Get writable MetabolicMuscleParameter from the MuscleMap using a string accessor. 448 Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameter* 449 updMetabolicParameters(const std::string& muscleName); 450 451 public: 452 453 454 //============================================================================= 455 }; // END of class Umberger2010MuscleMetabolicsProbe 456 //============================================================================= 457 458 //============================================================================== 459 // Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameter 460 //============================================================================== 461 462 /** 463 * Documentation for this class has been provided with the documentation for the 464 * Umberger2010MuscleMetabolicsProbe class. 465 * 466 * @see Umberger2010MuscleMetabolicsProbe 467 */ 468 469 class OSIMSIMULATION_API 470 Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameter 471 : public Object 472 { 473 OpenSim_DECLARE_CONCRETE_OBJECT( 474 Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameter, Object); 475 public: 476 //============================================================================== 477 // PROPERTIES 478 //============================================================================== 479 OpenSim_DECLARE_PROPERTY(specific_tension, double, 480 "The specific tension of the muscle (Pascals (N/m^2))."); 481 482 OpenSim_DECLARE_PROPERTY(density, double, 483 "The density of the muscle (kg/m^3)."); 484 485 OpenSim_DECLARE_PROPERTY(ratio_slow_twitch_fibers, double, 486 "Ratio of slow twitch fibers in the muscle (must be between 0 and 1)."); 487 488 OpenSim_DECLARE_PROPERTY(use_provided_muscle_mass, bool, 489 "An optional flag that allows the user to explicitly specify a muscle mass. " 490 "If set to true, the <provided_muscle_mass> property must be specified."); 491 492 OpenSim_DECLARE_PROPERTY(provided_muscle_mass, double, 493 "The user specified muscle mass (kg)."); 494 495 //============================================================================= 496 // METHODS 497 //============================================================================= 498 //-------------------------------------------------------------------------- 499 // Constructor(s) 500 //-------------------------------------------------------------------------- 501 Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameter(); 502 503 Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameter( 504 const std::string& muscleName, 505 double ratio_slow_twitch_fibers, 506 double muscle_mass = SimTK::NaN); 507 508 //-------------------------------------------------------------------------- 509 // Muscle mass 510 //-------------------------------------------------------------------------- getMuscleMass()511 const double& getMuscleMass() const { return _muscMass; } 512 void setMuscleMass(); 513 514 //-------------------------------------------------------------------------- 515 // Internal muscle pointer 516 //-------------------------------------------------------------------------- getMuscle()517 const Muscle* getMuscle() const { return _musc.get(); } setMuscle(Muscle * m)518 void setMuscle(Muscle* m) { _musc = m; } 519 520 521 //-------------------------------------------------------------------------- 522 // Object interface 523 //-------------------------------------------------------------------------- 524 private: 525 void setNull(); 526 void constructProperties(); 527 528 //============================================================================= 529 // DATA 530 //============================================================================= 531 // These private member variables are set by the probe that owns this 532 // MetabolicMuscleParameter 533 SimTK::ReferencePtr<Muscle> _musc; // Internal pointer to the muscle that corresponds 534 // to these parameters. 535 double _muscMass; // The mass of the muscle (depends on if 536 // <use_provided_muscle_mass> is true or false. 537 538 //============================================================================= 539 }; // END of class MetabolicMuscleParameter 540 //============================================================================= 541 542 543 544 //============================================================================== 545 // MetabolicMuscleParameterSet 546 //============================================================================== 547 /** 548 * MetabolicMuscleParameterSet is an internal container class containing the set 549 * of MetabolicMuscleParameters for each muscle that is probed. 550 */ 551 class OSIMSIMULATION_API 552 Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameterSet 553 : public Set<Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameter> 554 { 555 OpenSim_DECLARE_CONCRETE_OBJECT( 556 Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameterSet, 557 Set<Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameter>); 558 559 public: Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameterSet()560 Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameterSet() 561 { } 562 563 //============================================================================= 564 }; // END of class MetabolicMuscleParameterSet 565 //============================================================================= 566 567 568 }; //namespace 569 //============================================================================= 570 //============================================================================= 571 572 573 #endif // #ifndef OPENSIM_UMBERGER2010_METABOLIC_POWER_PROBE_H_ 574