This is an example using the MocoInverse tool with a complex model to prescribe walking. This example also shows how to track electromyography data.
#include <OpenSim/Actuators/ModelOperators.h>
#include <OpenSim/Common/Adapters.h>
#include <OpenSim/Moco/osimMoco.h>
void solveMocoInverse() {
MocoInverse inverse;
inverse.setName("example3DWalking_MocoInverse");
ModelProcessor modelProcessor("subject_walk_armless.osim");
modelProcessor.append(ModOpAddExternalLoads("grf_walk.xml"));
modelProcessor.append(ModOpIgnoreTendonCompliance());
modelProcessor.append(ModOpReplaceMusclesWithDeGrooteFregly2016());
modelProcessor.append(ModOpIgnorePassiveFiberForcesDGF());
modelProcessor.append(ModOpScaleActiveFiberForceCurveWidthDGF(1.5));
modelProcessor.append(ModOpAddReserves(1.0));
inverse.setModel(modelProcessor);
inverse.setKinematics(TableProcessor("coordinates.sto"));
inverse.set_initial_time(0.81);
inverse.set_final_time(1.79);
inverse.set_mesh_interval(0.02);
inverse.set_kinematics_allow_extra_columns(true);
MocoInverseSolution solution = inverse.solve();
solution.getMocoSolution().write(
"example3DWalking_MocoInverse_solution.sto");
}
void solveMocoInverseWithEMG() {
MocoInverse inverse;
inverse.setName("example3DWalking_MocoInverseWithEMG");
ModelProcessor modelProcessor("subject_walk_armless.osim");
modelProcessor.append(ModOpAddExternalLoads("grf_walk.xml"));
modelProcessor.append(ModOpIgnoreTendonCompliance());
modelProcessor.append(ModOpReplaceMusclesWithDeGrooteFregly2016());
modelProcessor.append(ModOpIgnorePassiveFiberForcesDGF());
modelProcessor.append(ModOpScaleActiveFiberForceCurveWidthDGF(1.5));
modelProcessor.append(ModOpAddReserves(1.0));
inverse.setModel(modelProcessor);
inverse.setKinematics(TableProcessor("coordinates.sto"));
inverse.set_initial_time(0.81);
inverse.set_final_time(1.79);
inverse.set_mesh_interval(0.02);
inverse.set_kinematics_allow_extra_columns(true);
MocoStudy study = inverse.initialize();
MocoProblem& problem = study.updProblem();
auto* tracking = problem.addGoal<MocoControlTrackingGoal>("emg_tracking");
tracking->setWeight(50.0);
controlsRef.updDependentColumn("soleus") *= 0.77;
controlsRef.updDependentColumn("gastrocnemius") *= 0.87;
controlsRef.updDependentColumn("tibialis_anterior") *= 0.37;
tracking->setReference(controlsRef);
tracking->setReferenceLabel("/forceset/soleus_r", "soleus");
tracking->setReferenceLabel("/forceset/gasmed_r", "gastrocnemius");
tracking->setReferenceLabel("/forceset/gaslat_r", "gastrocnemius");
tracking->setReferenceLabel("/forceset/tibant_r", "tibialis_anterior");
MocoSolution solution = study.solve();
solution.write("example3DWalking_MocoInverseWithEMG_solution.sto");
controlsRef.removeColumn("medial_hamstrings");
controlsRef.removeColumn("biceps_femoris");
controlsRef.removeColumn("vastus_lateralis");
controlsRef.removeColumn("vastus_medius");
controlsRef.removeColumn("rectus_femoris");
controlsRef.removeColumn("gluteus_maximus");
controlsRef.removeColumn("gluteus_medius");
controlsRef.setColumnLabels({"/forceset/soleus_r", "/forceset/gasmed_r",
"/forceset/tibant_r"});
controlsRef.appendColumn("/forceset/gaslat_r",
controlsRef.getDependentColumn("/forceset/gasmed_r"));
}
int main() {
solveMocoInverse();
solveMocoInverseWithEMG();
return EXIT_SUCCESS;
}
static void write(const TimeSeriesTable_< T > &table, const std::string &fileName)
Write a STO file.
Definition: STOFileAdapter.h:139
The Moco interface is contained within the OpenSim namespace.
Definition: ActivationCoordinateActuator.h:30
TimeSeriesTable_< SimTK::Real > TimeSeriesTable
See TimeSeriesTable_ for details on the interface.
Definition: TimeSeriesTable.h:519