示例#1
0
def test_initial_guess_update():
    # Load pendulum
    from bioptim.examples.optimal_time_ocp import pendulum_min_time_Mayer as ocp_module

    bioptim_folder = os.path.dirname(ocp_module.__file__)

    ocp = ocp_module.prepare_ocp(
        biorbd_model_path=bioptim_folder + "/models/pendulum.bioMod",
        final_time=2,
        n_shooting=10,
    )

    np.testing.assert_almost_equal(ocp.nlp[0].x_init.init, np.zeros((4, 1)))
    np.testing.assert_almost_equal(ocp.nlp[0].u_init.init, np.zeros((2, 1)))
    idx = ocp.v.parameters_in_list.index("time")
    np.testing.assert_almost_equal(
        ocp.v.parameters_in_list[idx].initial_guess.init[0, 0], 2)
    np.testing.assert_almost_equal(
        ocp.v.init.init, np.concatenate((np.zeros(
            (4 * 11 + 2 * 10, 1)), [[2]])))

    wrong_new_x_init = InitialGuess([1] * 6)
    new_x_init = InitialGuess([1] * 4)
    wrong_new_u_init = InitialGuess([3] * 4)
    new_u_init = InitialGuess([3] * 2)
    new_time_init = InitialGuess([4])

    # No name for the param
    with pytest.raises(
            ValueError,
            match="update_initial_guess must specify a name for the parameters"
    ):
        ocp.update_initial_guess(new_x_init, new_u_init, new_time_init)

    new_time_init.name = "dumb name"
    with pytest.raises(
            ValueError,
            match="update_initial_guess cannot declare new parameters"):
        ocp.update_initial_guess(new_x_init, new_u_init, new_time_init)

    new_time_init.name = "time"
    with pytest.raises(RuntimeError):
        ocp.update_initial_guess(new_x_init, wrong_new_u_init, new_time_init)
    with pytest.raises(RuntimeError):
        ocp.update_initial_guess(wrong_new_x_init, wrong_new_u_init,
                                 new_time_init)

    ocp.update_initial_guess(new_x_init, new_u_init, new_time_init)

    np.testing.assert_almost_equal(ocp.nlp[0].x_init.init, np.ones((4, 1)))
    np.testing.assert_almost_equal(ocp.nlp[0].u_init.init, np.ones((2, 1)) * 3)
    idx = ocp.v.parameters_in_list.index("time")
    np.testing.assert_almost_equal(
        ocp.v.parameters_in_list[idx].initial_guess.init[0, 0], 4)
    np.testing.assert_almost_equal(
        ocp.v.init.init,
        np.array([[1, 1, 1, 1] * 11 + [3, 3] * 10 + [4]]).T)
def test_monophase_time_constraint(ode_solver):
    # Load time_constraint
    from bioptim.examples.optimal_time_ocp import multiphase_time_constraint as ocp_module

    bioptim_folder = os.path.dirname(ocp_module.__file__)

    ocp = ocp_module.prepare_ocp(
        biorbd_model_path=bioptim_folder + "/models/cube.bioMod",
        final_time=(2, 5, 4),
        time_min=[1, 3, 0.1],
        time_max=[2, 4, 0.8],
        n_shooting=(20,),
        ode_solver=ode_solver(),
    )
    sol = ocp.solve()

    # Check objective function value
    f = np.array(sol.cost)
    np.testing.assert_equal(f.shape, (1, 1))
    np.testing.assert_almost_equal(f[0, 0], 10826.61745902614)

    # Check constraints
    g = np.array(sol.constraints)
    if ode_solver == OdeSolver.COLLOCATION:
        np.testing.assert_equal(g.shape, (120 * 5 + 7, 1))
        np.testing.assert_almost_equal(g, np.concatenate((np.zeros((120 * 5, 1)), np.array([[0, 0, 0, 0, 0, 0, 1]]).T)))
    else:
        np.testing.assert_equal(g.shape, (127, 1))
        np.testing.assert_almost_equal(g, np.concatenate((np.zeros((126, 1)), [[1]])))

    # Check some of the results
    q, qdot, tau = sol.states["q"], sol.states["qdot"], sol.controls["tau"]
    tf = sol.parameters["time"][0, 0]

    # initial and final position
    np.testing.assert_almost_equal(q[:, 0], np.array((1, 0, 0)))
    np.testing.assert_almost_equal(q[:, -1], np.array((2, 0, 0)))

    # initial and final velocities
    np.testing.assert_almost_equal(qdot[:, 0], np.array((0, 0, 0)))
    np.testing.assert_almost_equal(qdot[:, -1], np.array((0, 0, 0)))

    # initial and final controls
    np.testing.assert_almost_equal(tau[:, 0], np.array((5.71428583, 9.81, 0)))
    np.testing.assert_almost_equal(tau[:, -2], np.array((-5.71428583, 9.81, 0)))

    # optimized time
    np.testing.assert_almost_equal(tf, 1.0)

    # save and load
    TestUtils.save_and_load(sol, ocp, True)

    # simulate
    TestUtils.simulate(sol)
示例#3
0
def test_simulate_from_initial_single_shoot():
    # Load pendulum
    from bioptim.examples.getting_started import example_save_and_load as ocp_module

    bioptim_folder = os.path.dirname(ocp_module.__file__)

    ocp = ocp_module.prepare_ocp(
        biorbd_model_path=bioptim_folder + "/models/pendulum.bioMod",
        final_time=2,
        n_shooting=10,
        n_threads=4,
    )

    X = InitialGuess([-1, -2, 0.1, 0.2])
    U = InitialGuess(np.array([[-0.1, 0], [1, 2]]).T,
                     interpolation=InterpolationType.LINEAR)

    sol = Solution(ocp, [X, U])
    controls = sol.controls
    sol = sol.integrate(shooting_type=Shooting.SINGLE_CONTINUOUS,
                        keep_intermediate_points=True)

    # Check some of the results
    states = sol.states
    q, qdot, tau = states["q"], states["qdot"], controls["tau"]

    # initial and final position
    np.testing.assert_almost_equal(q[:, 0], np.array((-1.0, -2.0)))
    np.testing.assert_almost_equal(q[:, -1], np.array(
        (-0.33208579, 0.06094747)))

    # initial and final velocities
    np.testing.assert_almost_equal(qdot[:, 0], np.array((0.1, 0.2)))
    np.testing.assert_almost_equal(qdot[:, -1],
                                   np.array((-4.43192682, 6.38146735)))

    # initial and final controls
    np.testing.assert_almost_equal(tau[:, 0], np.array((-0.1, 0.0)))
    np.testing.assert_almost_equal(tau[:, -2], np.array((0.89, 1.8)))
示例#4
0
def test_simulate_from_initial_multiple_shoot():
    from bioptim.examples.getting_started import example_save_and_load as ocp_module

    bioptim_folder = os.path.dirname(ocp_module.__file__)

    ocp = ocp_module.prepare_ocp(
        biorbd_model_path=bioptim_folder + "/models/pendulum.bioMod",
        final_time=2,
        n_shooting=10,
        n_threads=4,
    )

    X = InitialGuess([-1, -2, 1, 0.5])
    U = InitialGuess(np.array([[-0.1, 0], [1, 2]]).T,
                     interpolation=InterpolationType.LINEAR)

    sol = Solution(ocp, [X, U])
    controls = sol.controls
    sol = sol.integrate(shooting_type=Shooting.MULTIPLE,
                        keep_intermediate_points=True)
    states = sol.states

    # Check some of the results
    q, qdot, tau = states["q"], states["qdot"], controls["tau"]

    # initial and final position
    np.testing.assert_almost_equal(q[:, 0], np.array((-1.0, -2.0)))
    np.testing.assert_almost_equal(q[:, -1], np.array(
        (-0.7553692, -1.6579819)))

    # initial and final velocities
    np.testing.assert_almost_equal(qdot[:, 0], np.array((1.0, 0.5)))
    np.testing.assert_almost_equal(qdot[:, -1], np.array(
        (1.05240919, 2.864199)))

    # initial and final controls
    np.testing.assert_almost_equal(tau[:, 0], np.array((-0.1, 0.0)))
    np.testing.assert_almost_equal(tau[:, -2], np.array((0.89, 1.8)))
def test_multiphase_time_constraint(ode_solver):
    # Load time_constraint
    from bioptim.examples.optimal_time_ocp import multiphase_time_constraint as ocp_module

    bioptim_folder = os.path.dirname(ocp_module.__file__)

    ocp = ocp_module.prepare_ocp(
        biorbd_model_path=bioptim_folder + "/models/cube.bioMod",
        final_time=(2, 5, 4),
        time_min=[1, 3, 0.1],
        time_max=[2, 4, 0.8],
        n_shooting=(20, 30, 20),
        ode_solver=ode_solver(),
    )
    sol = ocp.solve()

    # Check objective function value
    f = np.array(sol.cost)
    np.testing.assert_equal(f.shape, (1, 1))
    np.testing.assert_almost_equal(f[0, 0], 55582.04125083612)

    # Check constraints
    g = np.array(sol.constraints)
    if ode_solver == OdeSolver.COLLOCATION:
        np.testing.assert_equal(g.shape, (421 * 5 + 22, 1))
        np.testing.assert_almost_equal(
            g, np.concatenate((np.zeros((612, 1)), [[1]], np.zeros((909, 1)), [[3]], np.zeros((603, 1)), [[0.8]]))
        )
    else:
        np.testing.assert_equal(g.shape, (447, 1))
        np.testing.assert_almost_equal(
            g, np.concatenate((np.zeros((132, 1)), [[1]], np.zeros((189, 1)), [[3]], np.zeros((123, 1)), [[0.8]]))
        )

    # Check some of the results
    sol_merged = sol.merge_phases()
    states, controls = sol_merged.states, sol_merged.controls
    q, qdot, tau = states["q"], states["qdot"], controls["tau"]
    tf_all = sol.parameters["time"]
    tf = sol_merged.phase_time[1]

    # initial and final position
    np.testing.assert_almost_equal(q[:, 0], np.array((1, 0, 0)))
    np.testing.assert_almost_equal(q[:, -1], np.array((2, 0, 1.57)))

    # initial and final velocities
    np.testing.assert_almost_equal(qdot[:, 0], np.array((0, 0, 0)))
    np.testing.assert_almost_equal(qdot[:, -1], np.array((0, 0, 0)))

    # initial and final controls
    np.testing.assert_almost_equal(tau[:, 0], np.array((5.71428583, 9.81, 0)))
    np.testing.assert_almost_equal(tau[:, -2], np.array((-8.92857121, 9.81, -14.01785679)))

    # optimized time
    np.testing.assert_almost_equal(tf_all.T, [[1.0, 3, 0.8]])
    np.testing.assert_almost_equal(tf, np.sum(tf_all))

    # save and load
    TestUtils.save_and_load(sol, ocp, True)

    # simulate
    TestUtils.simulate(sol)
def test_time_constraint(ode_solver):
    # Load time_constraint
    from bioptim.examples.optimal_time_ocp import time_constraint as ocp_module

    bioptim_folder = os.path.dirname(ocp_module.__file__)

    if ode_solver == OdeSolver.IRK:
        ft = 2
        ns = 35
    elif ode_solver == OdeSolver.COLLOCATION:
        ft = 2
        ns = 15
    elif ode_solver == OdeSolver.RK4:
        ft = 2
        ns = 42
    else:
        raise ValueError("Test not implemented")

    ocp = ocp_module.prepare_ocp(
        biorbd_model_path=bioptim_folder + "/models/pendulum.bioMod",
        final_time=ft,
        n_shooting=ns,
        time_min=0.2,
        time_max=1,
        ode_solver=ode_solver(),
    )
    sol = ocp.solve()

    # Check constraints
    g = np.array(sol.constraints)
    if ode_solver == OdeSolver.COLLOCATION:
        np.testing.assert_equal(g.shape, (ns * 20 + 1, 1))
        np.testing.assert_almost_equal(g, np.concatenate((np.zeros((ns * 20, 1)), [[1]])))
    else:
        np.testing.assert_equal(g.shape, (ns * 4 + 1, 1))
        np.testing.assert_almost_equal(g, np.concatenate((np.zeros((ns * 4, 1)), [[1]])))

    # Check some of the results
    q, qdot, tau = sol.states["q"], sol.states["qdot"], sol.controls["tau"]
    tf = sol.parameters["time"][0, 0]

    # initial and final position
    np.testing.assert_almost_equal(q[:, 0], np.array((0, 0)))
    np.testing.assert_almost_equal(q[:, -1], np.array((0, 3.14)))

    # initial and final velocities
    np.testing.assert_almost_equal(qdot[:, 0], np.array((0, 0)))
    np.testing.assert_almost_equal(qdot[:, -1], np.array((0, 0)))

    # optimized time
    np.testing.assert_almost_equal(tf, 1.0)

    if ode_solver == OdeSolver.IRK:
        # Check objective function value
        f = np.array(sol.cost)
        np.testing.assert_equal(f.shape, (1, 1))
        np.testing.assert_almost_equal(f[0, 0], 57.84641870505798)

        # initial and final controls
        np.testing.assert_almost_equal(tau[:, 0], np.array((5.33802896, 0)))
        np.testing.assert_almost_equal(tau[:, -2], np.array((-23.69200381, 0)))

    elif ode_solver == OdeSolver.COLLOCATION:
        # Check objective function value
        f = np.array(sol.cost)
        np.testing.assert_equal(f.shape, (1, 1))
        np.testing.assert_almost_equal(f[0, 0], 90.22986699069487)

        # initial and final controls
        np.testing.assert_almost_equal(tau[:, 0], np.array((8.48542163, 0)))
        np.testing.assert_almost_equal(tau[:, -2], np.array((-18.13750096, 0)))

    elif ode_solver == OdeSolver.RK4:
        # Check objective function value
        f = np.array(sol.cost)
        np.testing.assert_equal(f.shape, (1, 1))
        np.testing.assert_almost_equal(f[0, 0], 39.593354247030085)

        # initial and final controls
        np.testing.assert_almost_equal(tau[:, 0], np.array((6.28713595, 0)))
        np.testing.assert_almost_equal(tau[:, -2], np.array((-12.72892599, 0)))
    else:
        raise ValueError("Test not ready")

    # save and load
    TestUtils.save_and_load(sol, ocp, True)

    # simulate
    TestUtils.simulate(sol, decimal_value=6)
def test_pendulum_min_time_mayer(ode_solver):
    # Load pendulum_min_time_Mayer
    from bioptim.examples.optimal_time_ocp import pendulum_min_time_Mayer as ocp_module

    bioptim_folder = os.path.dirname(ocp_module.__file__)

    if ode_solver == OdeSolver.IRK:
        ft = 2
        ns = 35
    elif ode_solver == OdeSolver.COLLOCATION:
        ft = 2
        ns = 10
    elif ode_solver == OdeSolver.RK4:
        ft = 2
        ns = 30
    else:
        raise ValueError("Test not implemented")

    ocp = ocp_module.prepare_ocp(
        biorbd_model_path=bioptim_folder + "/models/pendulum.bioMod",
        final_time=ft,
        n_shooting=ns,
        ode_solver=ode_solver(),
    )
    sol = ocp.solve()

    # Check objective function value
    f = np.array(sol.cost)
    np.testing.assert_equal(f.shape, (1, 1))

    # Check constraints
    g = np.array(sol.constraints)
    if ode_solver == OdeSolver.COLLOCATION:
        np.testing.assert_equal(g.shape, (ns * 20, 1))
        np.testing.assert_almost_equal(g, np.zeros((ns * 20, 1)), decimal=6)
    else:
        np.testing.assert_equal(g.shape, (ns * 4, 1))
        np.testing.assert_almost_equal(g, np.zeros((ns * 4, 1)), decimal=6)

    # Check some of the results
    q, qdot, tau = sol.states["q"], sol.states["qdot"], sol.controls["tau"]
    tf = sol.parameters["time"][0, 0]

    # initial and final position
    np.testing.assert_almost_equal(q[:, 0], np.array((0, 0)))
    np.testing.assert_almost_equal(q[:, -1], np.array((0, 3.14)))

    # initial and final velocities
    np.testing.assert_almost_equal(qdot[:, 0], np.array((0, 0)))
    np.testing.assert_almost_equal(qdot[:, -1], np.array((0, 0)))

    if ode_solver == OdeSolver.IRK:
        np.testing.assert_almost_equal(f[0, 0], 0.2855606738489079)

        # initial and final controls
        np.testing.assert_almost_equal(tau[:, 0], np.array((87.13363409, 0)), decimal=6)
        np.testing.assert_almost_equal(tau[:, -2], np.array((-99.99938226, 0)), decimal=6)

        # optimized time
        np.testing.assert_almost_equal(tf, 0.2855606738489079)

    elif ode_solver == OdeSolver.COLLOCATION:
        pass

    elif ode_solver == OdeSolver.RK4:
        np.testing.assert_almost_equal(f[0, 0], 0.2862324498580764)

        # initial and final controls
        np.testing.assert_almost_equal(tau[:, 0], np.array((70.46234418, 0)))
        np.testing.assert_almost_equal(tau[:, -2], np.array((-99.99964325, 0)))

        # optimized time
        np.testing.assert_almost_equal(tf, 0.2862324498580764)
    else:
        raise ValueError("Test not implemented")

    # save and load
    TestUtils.save_and_load(sol, ocp, True)

    # simulate
    TestUtils.simulate(sol, decimal_value=5)
def test_pendulum_min_time_mayer_constrained(ode_solver):
    # Load pendulum_min_time_Mayer
    from bioptim.examples.optimal_time_ocp import pendulum_min_time_Mayer as ocp_module

    bioptim_folder = os.path.dirname(ocp_module.__file__)

    if ode_solver == OdeSolver.IRK:
        ft = 2
        ns = 35
        min_ft = 0.5
    elif ode_solver == OdeSolver.COLLOCATION:
        ft = 2
        ns = 10
        min_ft = 0.5
    elif ode_solver == OdeSolver.RK4:
        ft = 2
        ns = 30
        min_ft = 0.5
    else:
        raise ValueError("Test not implemented")

    ocp = ocp_module.prepare_ocp(
        biorbd_model_path=bioptim_folder + "/models/pendulum.bioMod",
        final_time=ft,
        n_shooting=ns,
        ode_solver=ode_solver(),
        min_time=min_ft,
    )
    sol = ocp.solve()

    # Check constraints
    g = np.array(sol.constraints)
    if ode_solver == OdeSolver.COLLOCATION:
        np.testing.assert_equal(g.shape, (ns * 20, 1))
        np.testing.assert_almost_equal(g, np.zeros((ns * 20, 1)), decimal=6)
    else:
        np.testing.assert_equal(g.shape, (ns * 4, 1))
        np.testing.assert_almost_equal(g, np.zeros((ns * 4, 1)), decimal=6)

    # Check some of the results
    q, qdot, tau = sol.states["q"], sol.states["qdot"], sol.controls["tau"]
    tf = sol.parameters["time"][0, 0]

    # initial and final position
    np.testing.assert_almost_equal(q[:, 0], np.array((0, 0)))
    np.testing.assert_almost_equal(q[:, -1], np.array((0, 3.14)))

    # initial and final velocities
    np.testing.assert_almost_equal(qdot[:, 0], np.array((0, 0)))
    np.testing.assert_almost_equal(qdot[:, -1], np.array((0, 0)))

    # Check objective function value
    f = np.array(sol.cost)
    np.testing.assert_equal(f.shape, (1, 1))
    if ode_solver == OdeSolver.COLLOCATION:
        np.testing.assert_almost_equal(f[0, 0], 1.1878186850775596)
    else:
        np.testing.assert_almost_equal(f[0, 0], min_ft)

    # optimized time
    if ode_solver == OdeSolver.COLLOCATION:
        np.testing.assert_almost_equal(tf, 1.1878186850775596)
    else:
        np.testing.assert_almost_equal(tf, min_ft)

    # save and load
    TestUtils.save_and_load(sol, ocp, True)

    # simulate
    TestUtils.simulate(sol, decimal_value=6)