Skip to content

Commit

Permalink
Merge pull request #3685 from ComputationalBiomechanicsLab/muscle-dyn…
Browse files Browse the repository at this point in the history
…amics-info-remove-muscle-stiffness

Move muscle stiffness calculation to Muscle.h
  • Loading branch information
nickbianco authored Jan 29, 2024
2 parents 98c70b1 + 084c3ce commit 120db03
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 38 deletions.
2 changes: 0 additions & 2 deletions OpenSim/Actuators/DeGrooteFregly2016Muscle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,6 @@ void DeGrooteFregly2016Muscle::calcMuscleDynamicsInfoHelper(
mli.sinPennationAngle, mli.cosPennationAngle,
partialPennationAnglePartialFiberLength);
mdi.tendonStiffness = calcTendonStiffness(mli.normTendonLength);
mdi.muscleStiffness = calcMuscleStiffness(
mdi.tendonStiffness, mdi.fiberStiffnessAlongTendon);

const auto& partialTendonForcePartialFiberLength =
calcPartialTendonForcePartialFiberLength(mdi.tendonStiffness,
Expand Down
10 changes: 10 additions & 0 deletions OpenSim/Actuators/DeGrooteFregly2016Muscle.h
Original file line number Diff line number Diff line change
Expand Up @@ -608,10 +608,20 @@ class OSIMACTUATORS_API DeGrooteFregly2016Muscle : public Muscle {
if (get_ignore_tendon_compliance()) return fiberStiffnessAlongTendon;
// TODO Millard2012EquilibriumMuscle includes additional checks that
// the stiffness is non-negative and that the denominator is non-zero.
// Checks are omitted here to preserve continuity and smoothness for
// optimization (see #3685).
return (fiberStiffnessAlongTendon * tendonStiffness) /
(fiberStiffnessAlongTendon + tendonStiffness);
}

virtual double calcMuscleStiffness(const SimTK::State& s) const override
{
const MuscleDynamicsInfo& mdi = getMuscleDynamicsInfo(s);
return calcMuscleStiffness(
mdi.tendonStiffness,
mdi.fiberStiffnessAlongTendon);
}

/// The derivative of pennation angle with respect to fiber length.
/// @note based on
/// MuscleFixedWidthPennationModel::calc_DPennationAngle_DFiberLength().
Expand Down
6 changes: 0 additions & 6 deletions OpenSim/Actuators/Millard2012AccelerationMuscle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1054,11 +1054,6 @@ void Millard2012AccelerationMuscle::
//Compute the stiffness of the tendon
double dFt_dtl = calcTendonStiffness(ami);

//Compute the stiffness of the whole muscle/tendon complex
double Ke = 0;
if (abs(dFceAT_dlceAT*dFt_dtl)>0)
Ke = (dFceAT_dlceAT*dFt_dtl)/(dFceAT_dlceAT+dFt_dtl);

//Populate the output vector

mdi.activation = a;
Expand All @@ -1077,7 +1072,6 @@ void Millard2012AccelerationMuscle::
mdi.fiberStiffness = dFce_dlce;
mdi.fiberStiffnessAlongTendon = dFceAT_dlceAT;
mdi.tendonStiffness = dFt_dtl;
mdi.muscleStiffness = Ke;

//Check that the derivative of system energy less work is zero within
//a reasonable numerical tolerance.
Expand Down
10 changes: 0 additions & 10 deletions OpenSim/Actuators/Millard2012EquilibriumMuscle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1217,15 +1217,6 @@ calcMuscleDynamicsInfo(const SimTK::State& s, MuscleDynamicsInfo& mdi) const

// Compute the stiffness of the muscle.
dFt_dtl = mvi.userDefinedVelocityExtras[MVITendonStiffness];
if(!get_ignore_tendon_compliance()) {
// Compute the stiffness of the whole musculotendon actuator.
if (abs(dFmAT_dlceAT*dFt_dtl) > 0.0
&& abs(dFmAT_dlceAT+dFt_dtl) > SimTK::SignificantReal) {
Ke = (dFmAT_dlceAT*dFt_dtl)/(dFmAT_dlceAT+dFt_dtl);
}
} else {
Ke = dFmAT_dlceAT;
}
}

const double fse = get_ignore_tendon_compliance()
Expand All @@ -1243,7 +1234,6 @@ calcMuscleDynamicsInfo(const SimTK::State& s, MuscleDynamicsInfo& mdi) const
mdi.fiberStiffness = dFm_dlce;
mdi.fiberStiffnessAlongTendon = dFmAT_dlceAT;
mdi.tendonStiffness = dFt_dtl;
mdi.muscleStiffness = Ke;

// Verify that the derivative of system energy minus work is zero within
// a reasonable numerical tolerance.
Expand Down
4 changes: 0 additions & 4 deletions OpenSim/Actuators/Thelen2003Muscle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -623,9 +623,6 @@ void Thelen2003Muscle::calcMuscleDynamicsInfo(const SimTK::State& s,
dFmAT_dlceAT= dFmAT_dlce*cosphi;

dFt_dtl = calcDFseDtl(tl, fiso, tendonSlackLen);

//Compute the stiffness of the whole muscle/tendon complex
Ke = (dFmAT_dlceAT*dFt_dtl)/(dFmAT_dlceAT+dFt_dtl);
}

mdi.activation = a;
Expand All @@ -641,7 +638,6 @@ void Thelen2003Muscle::calcMuscleDynamicsInfo(const SimTK::State& s,
mdi.fiberStiffness = dFm_dlce;
mdi.fiberStiffnessAlongTendon = dFmAT_dlceAT;
mdi.tendonStiffness = dFt_dtl;
mdi.muscleStiffness = Ke;



Expand Down
22 changes: 21 additions & 1 deletion OpenSim/Simulation/Model/Muscle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ double Muscle::getTendonStiffness(const SimTK::State& s) const
of muscle force w.r.t. muscle length */
double Muscle::getMuscleStiffness(const SimTK::State& s) const
{
return getMuscleDynamicsInfo(s).muscleStiffness;
return calcMuscleStiffness(s);
}

/* get the current fiber power (W) */
Expand Down Expand Up @@ -633,6 +633,26 @@ double Muscle::calcMusclePower(const SimTK::State& s) const
return -getLengtheningSpeed(s) * getMuscleDynamicsInfo(s).tendonForce;
}

double Muscle::calcMuscleStiffness(const SimTK::State& s) const
{
const MuscleDynamicsInfo& mdi = getMuscleDynamicsInfo(s);

const double dFmAT_dlceAT = mdi.fiberStiffnessAlongTendon;
const double dFt_dtl = mdi.tendonStiffness;

double Ke = 0.;
if (!get_ignore_tendon_compliance()) {
// Compute the stiffness of the whole musculotendon actuator.
if (abs(dFmAT_dlceAT * dFt_dtl) > 0.0 &&
abs(dFmAT_dlceAT + dFt_dtl) > SimTK::SignificantReal) {
Ke = (dFmAT_dlceAT * dFt_dtl) / (dFmAT_dlceAT + dFt_dtl);
}
} else {
Ke = dFmAT_dlceAT;
}
return Ke;
}

//=============================================================================
// Required by CMC and Static Optimization
//=============================================================================
Expand Down
28 changes: 14 additions & 14 deletions OpenSim/Simulation/Model/Muscle.h
Original file line number Diff line number Diff line change
Expand Up @@ -461,10 +461,21 @@ OpenSim_DECLARE_ABSTRACT_OBJECT(Muscle, PathActuator);
/** Calculate muscle's power (W). */
double calcMusclePower(const SimTK::State& s) const;

protected:
/** Calculate muscle's stiffness.
Muscle stiffness is defined as the partial derivative of muscle force
with respect to changes in muscle length. This quantity can be computed
by noting that the tendon and the fiber are in series, with the fiber
at a pennation angle. Thus
Kmuscle = (Kfiber_along_tendon * Ktendon)
/(Kfiber_along_tendon + Ktendon) */
virtual double calcMuscleStiffness(const SimTK::State& s) const;

//=============================================================================
// DATA
//=============================================================================
protected:

/** The assumed fixed muscle-width from which the fiber pennation angle can
be calculated. */
Expand Down Expand Up @@ -710,13 +721,12 @@ OpenSim_DECLARE_ABSTRACT_OBJECT(Muscle, PathActuator);
fiberStiffness force/length N/m [7]
fiberStiffnessAlongTendon force/length N/m [8]
tendonStiffness force/length N/m [9]
muscleStiffness force/length N/m [10]
fiberActivePower force*velocity W (N*m/s)
fiberPassivePower force*velocity W (N*m/s)
tendonPower force*velocity W (N*m/s)
userDefinedDynamicsData NA NA [11]
userDefinedDynamicsData NA NA [10]
[1] This is a quantity that ranges between 0 and 1 that dictates how
on or activated a muscle is. This term may or may not have its own
Expand Down Expand Up @@ -752,15 +762,7 @@ OpenSim_DECLARE_ABSTRACT_OBJECT(Muscle, PathActuator);
[9] tendonStiffness is defined as the partial derivative of tendon
force with respect to tendon length
[10] muscleStiffness is defined as the partial derivative of muscle force
with respect to changes in muscle length. This quantity can usually
be computed by noting that the tendon and the fiber are in series,
with the fiber at a pennation angle. Thus
Kmuscle = (Kfiber_along_tendon * Ktendon)
/(Kfiber_along_tendon + Ktendon)
[11] This vector is left for the muscle modeler to populate with any
[10] This vector is left for the muscle modeler to populate with any
computationally expensive quantities that might be of interest
after dynamics calculations are completed but maybe of use
in computing muscle derivatives or reporting values of interest.
Expand All @@ -781,7 +783,6 @@ OpenSim_DECLARE_ABSTRACT_OBJECT(Muscle, PathActuator);
double fiberStiffness; // force/length N/m
double fiberStiffnessAlongTendon;//force/length N/m
double tendonStiffness; // force/length N/m
double muscleStiffness; // force/length N/m
//
double fiberActivePower; // force*velocity W
double fiberPassivePower; // force*velocity W
Expand All @@ -801,7 +802,6 @@ OpenSim_DECLARE_ABSTRACT_OBJECT(Muscle, PathActuator);
fiberStiffness(SimTK::NaN),
fiberStiffnessAlongTendon(SimTK::NaN),
tendonStiffness(SimTK::NaN),
muscleStiffness(SimTK::NaN),
fiberActivePower(SimTK::NaN),
fiberPassivePower(SimTK::NaN),
tendonPower(SimTK::NaN),
Expand Down
1 change: 0 additions & 1 deletion OpenSim/Simulation/Test/testMuscleMetabolicsProbes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,6 @@ OpenSim_DECLARE_CONCRETE_OBJECT(UmbergerMuscle, Muscle);
mdi.fiberStiffness = 0;
mdi.fiberStiffnessAlongTendon = 0;
mdi.tendonStiffness = 0;
mdi.muscleStiffness = 0;
mdi.fiberActivePower = 0;
mdi.fiberPassivePower = 0;
mdi.tendonPower = 0;
Expand Down

0 comments on commit 120db03

Please sign in to comment.