This example conducts a 2-D prediction of walking, employing a MocoPerodicityGoal.
#include <Moco/MocoGoal/MocoOutputGoal.h>
#include <Moco/osimMoco.h>
    using SimTK::Pi;
    track.setName("gaitTracking");
    
    
    track.
setModel(modelprocessor);
    track.set_states_global_tracking_weight(10.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);
    
    
    
    Model model = modelprocessor.
process();
    model.initSystem();
    
    for (const auto& coord : model.getComponentList<Coordinate>()) {
            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")});
        }
            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")});
        }
            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>()) {
            symmetryGoal->addStatePair({muscle.getStateVariableNames()[0],
                    std::regex_replace(muscle.getStateVariableNames()[0],
                            std::regex("_r"), "_l")});
        }
            symmetryGoal->addStatePair({muscle.getStateVariableNames()[0],
                    std::regex_replace(muscle.getStateVariableNames()[0],
                            std::regex("_l"), "_r")});
        }
    }
    
    
    
    
    problem.
setStateInfo(
"/jointset/groundPelvis/pelvis_tilt/value",
            {-20 * Pi / 180, -10 * Pi / 180});
    problem.
setStateInfo(
"/jointset/groundPelvis/pelvis_tx/value", {0, 1});
            "/jointset/groundPelvis/pelvis_ty/value", {0.75, 1.25});
            {-10 * Pi / 180, 60 * Pi / 180});
            {-10 * Pi / 180, 60 * Pi / 180});
            "/jointset/knee_l/knee_angle_l/value", {-50 * Pi / 180, 0});
            "/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});
    
    
    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(1000);
    
    
    full.write("gaitTracking_solution_fullcycle.sto");
    
    return solution;
}
void gaitPrediction(
const MocoSolution& gaitTrackingSolution) {
     using SimTK::Pi;
    study.setName("gaitPrediction");
    
    
    
    
    
    Model model = modelprocessor.
process();
    model.initSystem();
    
    for (const auto& coord : model.getComponentList<Coordinate>()) {
            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")});
        }
            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")});
        }
            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>()) {
            symmetryGoal->addStatePair({muscle.getStateVariableNames()[0],
                    std::regex_replace(muscle.getStateVariableNames()[0],
                            std::regex("_r"), "_l")});
        }
            symmetryGoal->addStatePair({muscle.getStateVariableNames()[0],
                    std::regex_replace(muscle.getStateVariableNames()[0],
                            std::regex("_l"), "_r")});
        }
    }
    
    speedGoal->set_desired_average_speed(1.2);
    
    effortGoal->setDivideByDisplacement(true);
    
    
    problem.
setStateInfo(
"/jointset/groundPelvis/pelvis_tilt/value",
            {-20 * Pi / 180, -10 * Pi / 180});
    problem.
setStateInfo(
"/jointset/groundPelvis/pelvis_tx/value", {0, 1});
            "/jointset/groundPelvis/pelvis_ty/value", {0.75, 1.25});
            {-10 * Pi / 180, 60 * Pi / 180});
            {-10 * Pi / 180, 60 * Pi / 180});
            "/jointset/knee_l/knee_angle_l/value", {-50 * Pi / 180, 0});
            "/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});
    
    
    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(1000);
    
    
    
    full.write("gaitPrediction_solution_fullcycle.sto");
    
    
    std::vector<std::string> contactSpheres_r;
    std::vector<std::string> contactSpheres_l;
    contactSpheres_r.push_back("contactSphereHeel_r");
    contactSpheres_r.push_back("contactSphereFront_r");
    contactSpheres_l.push_back("contactSphereHeel_l");
    contactSpheres_l.push_back("contactSphereFront_l");
            model, full, contactSpheres_r, contactSpheres_l);
            "gaitPrediction_solutionGRF_fullcycle.sto");
}
int main() {
    try {
        gaitPrediction(gaitTrackingSolution);
    } catch (const std::exception& e) { std::cout << e.what() << std::endl; }
    return EXIT_SUCCESS;
}