This is an example using the MocoTrack tool that also shows how to minimize the total metabolic rate employing the Bhargava2004SmoothedMuscleMetabolics.
 
 
#include <OpenSim/Moco/MocoGoal/MocoOutputGoal.h>
#include <OpenSim/Moco/osimMoco.h>
 
 
void gaitTrackingMetabolics() {
 
    using SimTK::Pi;
 
    MocoTrack track;
    track.setName("gaitTrackingMetabolics");
 
    
    
    Model baseModel("2D_gait.osim");
 
    
    Bhargava2004SmoothedMuscleMetabolics* metabolics =
            new Bhargava2004SmoothedMuscleMetabolics();
    metabolics->setName("metabolics");
    metabolics->set_use_smoothing(true);
    metabolics->addMuscle("hamstrings_r",
            baseModel.getComponent<Muscle>("hamstrings_r"));
    metabolics->addMuscle("hamstrings_l",
            baseModel.getComponent<Muscle>("hamstrings_l"));
    metabolics->addMuscle("bifemsh_r",
            baseModel.getComponent<Muscle>("bifemsh_r"));
    metabolics->addMuscle("bifemsh_l",
            baseModel.getComponent<Muscle>("bifemsh_l"));
    metabolics->addMuscle("glut_max_r",
            baseModel.getComponent<Muscle>("glut_max_r"));
    metabolics->addMuscle("glut_max_l",
            baseModel.getComponent<Muscle>("glut_max_l"));
    metabolics->addMuscle("iliopsoas_r",
            baseModel.getComponent<Muscle>("iliopsoas_r"));
    metabolics->addMuscle("iliopsoas_l",
            baseModel.getComponent<Muscle>("iliopsoas_l"));
    metabolics->addMuscle("rect_fem_r",
            baseModel.getComponent<Muscle>("rect_fem_r"));
    metabolics->addMuscle("rect_fem_l",
            baseModel.getComponent<Muscle>("rect_fem_l"));
    metabolics->addMuscle("vasti_r",
            baseModel.getComponent<Muscle>("vasti_r"));
    metabolics->addMuscle("vasti_l",
            baseModel.getComponent<Muscle>("vasti_l"));
    metabolics->addMuscle("gastroc_r",
            baseModel.getComponent<Muscle>("gastroc_r"));
    metabolics->addMuscle("gastroc_l",
            baseModel.getComponent<Muscle>("gastroc_l"));
    metabolics->addMuscle("soleus_r",
            baseModel.getComponent<Muscle>("soleus_r"));
    metabolics->addMuscle("soleus_l",
            baseModel.getComponent<Muscle>("soleus_l"));
    metabolics->addMuscle("tib_ant_r",
            baseModel.getComponent<Muscle>("tib_ant_r"));
    metabolics->addMuscle("tib_ant_l",
            baseModel.getComponent<Muscle>("tib_ant_l"));
    baseModel.addComponent(metabolics);
    baseModel.finalizeConnections();
 
    ModelProcessor modelprocessor = ModelProcessor(baseModel);
    track.setModel(modelprocessor);
    track.setStatesReference(
            TableProcessor("referenceCoordinates.sto") | TabOpLowPassFilter(6));
    track.set_states_global_tracking_weight(30.0);
    track.set_allow_unused_references(true);
    track.set_track_reference_position_derivatives(true);
    track.set_apply_tracked_states_to_guess(true);
    track.set_initial_time(0.0);
    track.set_final_time(0.47008941);
    MocoStudy study = track.initialize();
    MocoProblem& problem = study.updProblem();
 
    
    
    
    auto* symmetryGoal = problem.addGoal<MocoPeriodicityGoal>("symmetryGoal");
    Model model = modelprocessor.process();
    model.initSystem();
    
    for (const auto& coord : model.getComponentList<Coordinate>()) {
        if (IO::EndsWith(coord.getName(), "_r")) {
            symmetryGoal->addStatePair({coord.getStateVariableNames()[0],
                    std::regex_replace(coord.getStateVariableNames()[0],
                            std::regex("_r"), "_l")});
            symmetryGoal->addStatePair({coord.getStateVariableNames()[1],
                    std::regex_replace(coord.getStateVariableNames()[1],
                            std::regex("_r"), "_l")});
        }
        if (IO::EndsWith(coord.getName(), "_l")) {
            symmetryGoal->addStatePair({coord.getStateVariableNames()[0],
                    std::regex_replace(coord.getStateVariableNames()[0],
                            std::regex("_l"), "_r")});
            symmetryGoal->addStatePair({coord.getStateVariableNames()[1],
                    std::regex_replace(coord.getStateVariableNames()[1],
                            std::regex("_l"), "_r")});
        }
        if (!IO::EndsWith(coord.getName(), "_l") &&
                !IO::EndsWith(coord.getName(), "_r") &&
                !IO::EndsWith(coord.getName(), "_tx")) {
            symmetryGoal->addStatePair({coord.getStateVariableNames()[0],
                    coord.getStateVariableNames()[0]});
            symmetryGoal->addStatePair({coord.getStateVariableNames()[1],
                    coord.getStateVariableNames()[1]});
        }
    }
    symmetryGoal->addStatePair({"/jointset/groundPelvis/pelvis_tx/speed"});
    
    symmetryGoal->addControlPair({"/lumbarAct"});
    
    for (const auto& muscle : model.getComponentList<Muscle>()) {
        if (IO::EndsWith(muscle.getName(), "_r")) {
            symmetryGoal->addStatePair({muscle.getStateVariableNames()[0],
                    std::regex_replace(muscle.getStateVariableNames()[0],
                            std::regex("_r"), "_l")});
        }
        if (IO::EndsWith(muscle.getName(), "_l")) {
            symmetryGoal->addStatePair({muscle.getStateVariableNames()[0],
                    std::regex_replace(muscle.getStateVariableNames()[0],
                            std::regex("_l"), "_r")});
        }
    }
    
    
    MocoControlGoal& effort =
            dynamic_cast<MocoControlGoal&>(problem.updGoal("control_effort"));
    effort.setWeight(0.1);
    
    
    
    auto* metGoal = problem.addGoal<MocoOutputGoal>("met", 0.1);
    metGoal->setOutputPath("/metabolics|total_metabolic_rate");
    metGoal->setDivideByDisplacement(true);
    metGoal->setDivideByMass(true);
 
    
    
    problem.setStateInfo("/jointset/groundPelvis/pelvis_tilt/value",
            {-20 * Pi / 180, -10 * Pi / 180});
    problem.setStateInfo("/jointset/groundPelvis/pelvis_tx/value", {0, 1});
    problem.setStateInfo(
            "/jointset/groundPelvis/pelvis_ty/value", {0.75, 1.25});
    problem.setStateInfo("/jointset/hip_l/hip_flexion_l/value",
            {-10 * Pi / 180, 60 * Pi / 180});
    problem.setStateInfo("/jointset/hip_r/hip_flexion_r/value",
            {-10 * Pi / 180, 60 * Pi / 180});
    problem.setStateInfo(
            "/jointset/knee_l/knee_angle_l/value", {-50 * Pi / 180, 0});
    problem.setStateInfo(
            "/jointset/knee_r/knee_angle_r/value", {-50 * Pi / 180, 0});
    problem.setStateInfo("/jointset/ankle_l/ankle_angle_l/value",
            {-15 * Pi / 180, 25 * Pi / 180});
    problem.setStateInfo("/jointset/ankle_r/ankle_angle_r/value",
            {-15 * Pi / 180, 25 * Pi / 180});
    problem.setStateInfo("/jointset/lumbar/lumbar/value", {0, 20 * Pi / 180});
 
    
    
    MocoCasADiSolver& solver = study.updSolver<MocoCasADiSolver>();
    solver.set_num_mesh_intervals(50);
    solver.set_verbosity(2);
    solver.set_optim_solver("ipopt");
    solver.set_optim_convergence_tolerance(1e-4);
    solver.set_optim_constraint_tolerance(1e-4);
    solver.set_optim_max_iterations(10000);
 
    
    
    MocoSolution solution = study.solve();
    full.write("gaitTrackingMetabolics_solution_fullcycle.sto");
    std::cout << "The metabolic cost of transport is: "
        << solution.getObjectiveTerm("met") << " [J kg-1 m-1]." << std::endl;
    study.visualize(solution);
 
}
 
int main() {
    try {
        gaitTrackingMetabolics();
    } catch (const std::exception& e) { std::cout << e.what() << std::endl; }
    return EXIT_SUCCESS;
}
OSIMMOCO_API MocoTrajectory createPeriodicTrajectory(const MocoTrajectory &halfPeriodTrajectory, std::vector< std::string > addPatterns={".*pelvis_tx/value"}, std::vector< std::string > negatePatterns={ ".*pelvis_list(?!/value).*", ".*pelvis_rotation.*", ".*pelvis_tz(?!/value).*", ".*lumbar_bending(?!/value).*", ".*lumbar_rotation.*"}, std::vector< std::string > negateAndShiftPatterns={ ".*pelvis_list/value", ".*pelvis_tz/value", ".*lumbar_bending/value"}, std::vector< std::pair< std::string, std::string > > symmetryPatterns={{R"(_r(\/|_|$))", "_l$1"}, {R"(_l(\/|_|$))", "_r$1"}})
Convert a trajectory covering half the period of a symmetric motion into a trajectory over the full p...
 
The Moco interface is contained within the OpenSim namespace.
Definition: Moco.dox:5