@@ -556,43 +556,38 @@ computeFiberEquilibrium(SimTK::State& s, bool solveForVelocity) const
556556 double pathSpeed = solveForVelocity ? getLengtheningSpeed (s) : 0 ;
557557 double activation = getActivation (s);
558558
559- try {
560- std::pair<StatusFromEstimateMuscleFiberState,
561- ValuesFromEstimateMuscleFiberState> result =
562- estimateMuscleFiberState (activation, pathLength, pathSpeed,
563- tol, maxIter, solveForVelocity);
564-
565- switch (result.first ) {
566-
567- case StatusFromEstimateMuscleFiberState::Success_Converged:
568- setActuation (s, result.second [" tendon_force" ]);
569- setFiberLength (s, result.second [" fiber_length" ]);
570- break ;
571-
572- case StatusFromEstimateMuscleFiberState::Warning_FiberAtLowerBound:
573- log_warn (" Millard2012EquilibriumMuscle static solution: '{}' is "
574- " at its minimum fiber length of {}." ,
575- getName (), result.second [" fiber_length" ]);
576- setActuation (s, result.second [" tendon_force" ]);
577- setFiberLength (s, result.second [" fiber_length" ]);
578- break ;
579-
580- case StatusFromEstimateMuscleFiberState::Failure_MaxIterationsReached:
581- // Report internal variables and throw exception.
582- std::ostringstream ss;
583- ss << " \n Solution error " << abs (result.second [" solution_error" ])
584- << " exceeds tolerance of " << tol << " \n "
585- << " Newton iterations reached limit of " << maxIter << " \n "
586- << " Activation is " << activation << " \n "
587- << " Fiber length is " << result.second [" fiber_length" ] << " \n " ;
588- OPENSIM_THROW_FRMOBJ (MuscleCannotEquilibrate, ss.str ());
589- break ;
590- }
559+ const MuscleStateEstimate result =
560+ estimateMuscleFiberState (
561+ activation,
562+ pathLength,
563+ pathSpeed,
564+ tol,
565+ maxIter,
566+ solveForVelocity);
567+
568+ if (result.status ==
569+ MuscleStateEstimate::Status::Failure_MaxIterationsReached) {
570+ std::ostringstream oss;
571+ oss << " Failed to compute muscle equilibrium state:\n "
572+ << " Solution error " << std::abs (result.solutionError )
573+ << " exceeds tolerance of " << tol << " \n "
574+ << " Newton iterations reached limit of " << maxIter << " \n "
575+ << " Activation is " << activation << " \n "
576+ << " Fiber length is " << result.fiberLength << " \n " ;
577+ OPENSIM_THROW_FRMOBJ (MuscleCannotEquilibrate, oss.str ());
578+ }
591579
592- } catch (const std::exception& x) {
593- OPENSIM_THROW_FRMOBJ (MuscleCannotEquilibrate,
594- " Internal exception encountered.\n " + std::string{x.what ()});
580+ if (result.status ==
581+ MuscleStateEstimate::Status::Warning_FiberAtLowerBound) {
582+ log_warn (
583+ " Millard2012EquilibriumMuscle static solution: '{}' is at its"
584+ " minimum fiber length of {}." ,
585+ getName (),
586+ result.fiberLength );
595587 }
588+
589+ setActuation (s, result.tendonForce );
590+ setFiberLength (s, result.fiberLength );
596591}
597592
598593// ==============================================================================
@@ -1355,15 +1350,14 @@ double Millard2012EquilibriumMuscle::clampFiberLength(double lce) const
13551350 return max (lce, getMinimumFiberLength ());
13561351}
13571352
1358- std::pair<Millard2012EquilibriumMuscle::StatusFromEstimateMuscleFiberState,
1359- Millard2012EquilibriumMuscle::ValuesFromEstimateMuscleFiberState>
1360- Millard2012EquilibriumMuscle::estimateMuscleFiberState (
1361- const double aActivation,
1362- const double pathLength,
1363- const double pathLengtheningSpeed,
1364- const double aSolTolerance,
1365- const int aMaxIterations,
1366- bool staticSolution) const
1353+ Millard2012EquilibriumMuscle::MuscleStateEstimate
1354+ Millard2012EquilibriumMuscle::estimateMuscleFiberState (
1355+ const double aActivation,
1356+ const double pathLength,
1357+ const double pathLengtheningSpeed,
1358+ const double aSolTolerance,
1359+ const int aMaxIterations,
1360+ bool staticSolution) const
13671361{
13681362 // If seeking a static solution, set velocities to zero and avoid the
13691363 // velocity-sharing algorithm below, as it can produce nonzero fiber and
@@ -1600,59 +1594,44 @@ Millard2012EquilibriumMuscle::estimateMuscleFiberState(
16001594 iter++;
16011595 }
16021596
1603- // Populate the result map.
1604- ValuesFromEstimateMuscleFiberState resultValues ;
1597+ MuscleStateEstimate result;
1598+ result. solutionError = ferr ;
16051599
1606- if (abs (ferr) < aSolTolerance) { // The solution converged.
1600+ // Check if solution converged.
1601+ if (abs (ferr) < aSolTolerance) {
1602+ result.status = MuscleStateEstimate::Status::Success_Converged;
16071603
1608- if (isFiberStateClamped (lce, dlceN)) {
1609- lce = getMinimumFiberLength ();
1610- }
1611-
1612- resultValues[" solution_error" ] = ferr;
1613- resultValues[" iterations" ] = (double )iter;
1614- resultValues[" fiber_length" ] = lce;
1615- resultValues[" fiber_velocity" ] = dlce;
1616- resultValues[" tendon_force" ] = fse*fiso;
1604+ result.fiberLength = clampFiberLength (lce);
1605+ result.tendonVelocity = dlce;
1606+ result.tendonForce = fse * fiso;
16171607
1618- return std::pair<StatusFromEstimateMuscleFiberState,
1619- ValuesFromEstimateMuscleFiberState>
1620- (StatusFromEstimateMuscleFiberState::Success_Converged, resultValues);
1608+ return result;
16211609 }
16221610
1623- // Fiber length is at or exceeds its lower bound.
1611+ // Check if fiberlength is at or exceeds lower bound.
16241612 if (lce <= getMinimumFiberLength ()) {
1613+ result.status = MuscleStateEstimate::Status::
1614+ Warning_FiberAtLowerBound;
16251615
1626- lce = getMinimumFiberLength ();
1616+ lce = getMinimumFiberLength ();
16271617 phi = getPennationModel ().calcPennationAngle (lce);
16281618 cosphi = cos (phi);
16291619 tl = getPennationModel ().calcTendonLength (cosphi,lce,ml);
16301620 lceN = lce/ofl;
16311621 tlN = tl/tsl;
16321622 fse = fseCurve.calcValue (tlN);
16331623
1634- resultValues[" solution_error" ] = ferr;
1635- resultValues[" iterations" ] = (double )iter;
1636- resultValues[" fiber_length" ] = lce;
1637- resultValues[" fiber_velocity" ] = 0 ;
1638- resultValues[" tendon_force" ] = fse*fiso;
1624+ result.fiberLength = lce;
1625+ result.tendonVelocity = 0 ;
1626+ result.tendonForce = fse * fiso;
16391627
1640- return std::pair<StatusFromEstimateMuscleFiberState,
1641- ValuesFromEstimateMuscleFiberState>
1642- (StatusFromEstimateMuscleFiberState::Warning_FiberAtLowerBound,
1643- resultValues);
1628+ return result;
16441629 }
16451630
1646- resultValues[" solution_error" ] = ferr;
1647- resultValues[" iterations" ] = (double )iter;
1648- resultValues[" fiber_length" ] = SimTK::NaN;
1649- resultValues[" fiber_velocity" ] = SimTK::NaN;
1650- resultValues[" tendon_force" ] = SimTK::NaN;
1651-
1652- return std::pair<StatusFromEstimateMuscleFiberState,
1653- ValuesFromEstimateMuscleFiberState>
1654- (StatusFromEstimateMuscleFiberState::Failure_MaxIterationsReached,
1655- resultValues);
1631+ // Solution failed to converge.
1632+ result.status = MuscleStateEstimate::Status::
1633+ Failure_MaxIterationsReached;
1634+ return result;
16561635}
16571636
16581637// ==============================================================================
0 commit comments