diff --git a/Bindings/Java/Matlab/examples/Moco/example2DWalking/example2DWalking.m b/Bindings/Java/Matlab/examples/Moco/example2DWalking/example2DWalking.m index 3fe633d62d..7c0bdeb532 100644 --- a/Bindings/Java/Matlab/examples/Moco/example2DWalking/example2DWalking.m +++ b/Bindings/Java/Matlab/examples/Moco/example2DWalking/example2DWalking.m @@ -52,6 +52,9 @@ % Load the Moco libraries import org.opensim.modeling.*; +% Flag to enable or disable the custom ipopt options files. +USE_CUSTOM_OPTIONS = true; + % --------------------------------------------------------------------------- % Set up a coordinate tracking problem where the goal is to minimize the % difference between provided and simulated coordinate values and speeds (and @@ -183,6 +186,16 @@ 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 = MocoDirectCollocationSolver.safeDownCast(study.updSolver()); +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); +if (USE_CUSTOM_OPTIONS) + % This is a file which contains more custom solver options for ipopt. + solver.set_optim_ipopt_opt_filename("track_opt.opt"); +end % Solve the problem % ================= @@ -326,6 +339,10 @@ solver.set_optim_max_iterations(1000); solver.setGuess(gaitTrackingSolution); % Use tracking solution as initial guess +if (USE_CUSTOM_OPTIONS) + % This is a file which contains more custom solver options for ipopt. + solver.set_optim_ipopt_opt_filename("predi_opt.opt"); +end % Solve problem % ============= diff --git a/OpenSim/Examples/Moco/example2DWalking/CMakeLists.txt b/OpenSim/Examples/Moco/example2DWalking/CMakeLists.txt index b94fa6497c..28de8d11b0 100644 --- a/OpenSim/Examples/Moco/example2DWalking/CMakeLists.txt +++ b/OpenSim/Examples/Moco/example2DWalking/CMakeLists.txt @@ -2,7 +2,9 @@ set(EXAMPLE_2D_WALKING_FILES 2D_gait.osim referenceCoordinates.sto referenceGRF.sto - referenceGRF.xml) + referenceGRF.xml + predi_opt.opt + track_opt.opt) OpenSimAddExampleCXX(NAME example2DWalking SUBDIR Moco EXECUTABLES example2DWalking example2DWalkingMetabolics diff --git a/OpenSim/Examples/Moco/example2DWalking/example2DWalking.cpp b/OpenSim/Examples/Moco/example2DWalking/example2DWalking.cpp index e99cd5740a..7b923702a0 100644 --- a/OpenSim/Examples/Moco/example2DWalking/example2DWalking.cpp +++ b/OpenSim/Examples/Moco/example2DWalking/example2DWalking.cpp @@ -47,6 +47,8 @@ using namespace OpenSim; +bool USE_CUSTOM_OPTIONS = false; + /// Set a coordinate tracking problem where the goal is to minimize the /// difference between provided and simulated coordinate values and speeds /// (and ground reaction forces) as well as to minimize an effort cost (squared @@ -185,6 +187,11 @@ MocoSolution gaitTracking(double controlEffortWeight = 10, solver.set_optim_constraint_tolerance(1e-4); solver.set_optim_max_iterations(1000); + if (USE_CUSTOM_OPTIONS) { + // This is a file which contains more custom solver options for ipopt. + solver.set_optim_ipopt_opt_filename("track_opt.opt"); + } + // Solve problem. // ============== MocoSolution solution = study.solve(); @@ -318,6 +325,11 @@ void gaitPrediction(const MocoSolution& gaitTrackingSolution) { // Use the solution from the tracking simulation as initial guess. solver.setGuess(gaitTrackingSolution); + if (USE_CUSTOM_OPTIONS) { + // This is a file which contains more custom solver options for ipopt. + solver.set_optim_ipopt_opt_filename("predi_opt.opt"); + } + // Solve problem. // ============== MocoSolution solution = study.solve(); diff --git a/OpenSim/Examples/Moco/example2DWalking/predi_opt.opt b/OpenSim/Examples/Moco/example2DWalking/predi_opt.opt new file mode 100644 index 0000000000..758247aae0 --- /dev/null +++ b/OpenSim/Examples/Moco/example2DWalking/predi_opt.opt @@ -0,0 +1,2 @@ +# Warm start since the problem is probably somewhat converged from the first problem. +warm_start_init_point yes \ No newline at end of file diff --git a/OpenSim/Examples/Moco/example2DWalking/track_opt.opt b/OpenSim/Examples/Moco/example2DWalking/track_opt.opt new file mode 100644 index 0000000000..01c3b3d41c --- /dev/null +++ b/OpenSim/Examples/Moco/example2DWalking/track_opt.opt @@ -0,0 +1,3 @@ +# Example of an option that can be specified when we use an external options file. + +least_square_init_duals yes \ No newline at end of file diff --git a/OpenSim/Moco/MocoCasADiSolver/MocoCasADiSolver.cpp b/OpenSim/Moco/MocoCasADiSolver/MocoCasADiSolver.cpp index df908eadb0..2afee8e0e9 100644 --- a/OpenSim/Moco/MocoCasADiSolver/MocoCasADiSolver.cpp +++ b/OpenSim/Moco/MocoCasADiSolver/MocoCasADiSolver.cpp @@ -239,6 +239,8 @@ std::unique_ptr MocoCasADiSolver::createCasOCSolver( checkPropertyValueIsInSet(getProperty_verbosity(), {0, 1, 2}); if (get_optim_solver() == "ipopt") { solverOptions["print_user_options"] = "yes"; + // Set the optional options file name. + solverOptions["option_file_name"] = get_optim_ipopt_opt_filename(); if (get_verbosity() < 2) { solverOptions["print_level"] = 0; } else if (get_optim_ipopt_print_level() != -1) { diff --git a/OpenSim/Moco/MocoDirectCollocationSolver.cpp b/OpenSim/Moco/MocoDirectCollocationSolver.cpp index d80c1b9805..6691ba4776 100644 --- a/OpenSim/Moco/MocoDirectCollocationSolver.cpp +++ b/OpenSim/Moco/MocoDirectCollocationSolver.cpp @@ -40,6 +40,7 @@ void MocoDirectCollocationSolver::constructProperties() { constructProperty_implicit_auxiliary_derivative_bounds({-1000, 1000}); constructProperty_minimize_lagrange_multipliers(false); constructProperty_lagrange_multiplier_weight(1.0); + constructProperty_optim_ipopt_opt_filename("ipopt.opt"); } void MocoDirectCollocationSolver::setMesh(const std::vector& mesh) { diff --git a/OpenSim/Moco/MocoDirectCollocationSolver.h b/OpenSim/Moco/MocoDirectCollocationSolver.h index 66393aa192..c94c173bd3 100644 --- a/OpenSim/Moco/MocoDirectCollocationSolver.h +++ b/OpenSim/Moco/MocoDirectCollocationSolver.h @@ -124,6 +124,10 @@ class OSIMMOCO_API MocoDirectCollocationSolver : public MocoSolver { "Newton."); OpenSim_DECLARE_PROPERTY(optim_ipopt_print_level, int, "IPOPT's verbosity (see IPOPT documentation)."); + OpenSim_DECLARE_PROPERTY(optim_ipopt_opt_filename, std::string, + "When using IPOPT, 'ipopt.opt' (default)." + "IPOPT looks for this file before it starts and uses it " + "to set optimizer options. See: https://coin-or.github.io/Ipopt/OPTIONS.html."); OpenSim_DECLARE_OPTIONAL_PROPERTY(enforce_constraint_derivatives, bool, "'true' (default) or 'false', whether or not derivatives of " "kinematic constraints are enforced as path constraints in the " diff --git a/OpenSim/Moco/MocoTropterSolver.cpp b/OpenSim/Moco/MocoTropterSolver.cpp index b6558d2d73..4dd4e594fe 100644 --- a/OpenSim/Moco/MocoTropterSolver.cpp +++ b/OpenSim/Moco/MocoTropterSolver.cpp @@ -188,6 +188,9 @@ MocoTropterSolver::createTropterSolver( // Check that IPOPT print level is valid. checkPropertyValueIsInRangeOrSet( getProperty_optim_ipopt_print_level(), 0, 12, {-1}); + // Set the optional options file name. + optsolver.set_advanced_option_string( + "option_file_name", get_optim_ipopt_opt_filename()); if (get_verbosity() < 2) { optsolver.set_advanced_option_int("print_level", 0); } else {