Ejemplo n.º 1
0
def prepare_ocp(biorbd_model_path, final_time, number_shooting_points, min_g, max_g, target_g):
    # --- Options --- #
    biorbd_model = biorbd.Model(biorbd_model_path)
    tau_min, tau_max, tau_init = -30, 30, 0
    n_q = biorbd_model.nbQ()
    n_qdot = biorbd_model.nbQdot()
    n_tau = biorbd_model.nbGeneralizedTorque()

    # Add objective functions
    objective_functions = ObjectiveOption(Objective.Lagrange.MINIMIZE_TORQUE, weight=10)

    # Dynamics
    dynamics = DynamicsTypeOption(DynamicsType.TORQUE_DRIVEN)

    # Path constraint
    x_bounds = BoundsOption(QAndQDotBounds(biorbd_model))
    x_bounds[:, [0, -1]] = 0
    x_bounds[1, -1] = 3.14

    # Initial guess
    x_init = InitialGuessOption([0] * (n_q + n_qdot))

    # Define control path constraint
    u_bounds = BoundsOption([[tau_min] * n_tau, [tau_max] * n_tau])
    u_bounds[1, :] = 0

    u_init = InitialGuessOption([tau_init] * n_tau)

    # Define the parameter to optimize
    # Give the parameter some min and max bounds
    parameters = ParameterList()
    bound_gravity = Bounds(min_bound=min_g, max_bound=max_g, interpolation=InterpolationType.CONSTANT)
    # and an initial condition
    initial_gravity = InitialGuess((min_g + max_g) / 2)
    parameter_objective_functions = ObjectiveOption(
        my_target_function, weight=10, quadratic=True, custom_type=Objective.Parameter, target=target_g
    )
    parameters.add(
        "gravity_z",  # The name of the parameter
        my_parameter_function,  # The function that modifies the biorbd model
        initial_gravity,  # The initial guess
        bound_gravity,  # The bounds
        size=1,  # The number of elements this particular parameter vector has
        penalty_list=parameter_objective_functions,  # Objective of constraint for this particular parameter
        extra_value=1,  # You can define as many extra arguments as you want
    )

    return OptimalControlProgram(
        biorbd_model,
        dynamics,
        number_shooting_points,
        final_time,
        x_init,
        u_init,
        x_bounds,
        u_bounds,
        objective_functions,
        parameters=parameters,
    )
Ejemplo n.º 2
0
def test_wrong_parameter():
    param = ParameterList()

    my_parameter_function = 1
    initial_gravity = 1
    bounds = 1

    with pytest.raises(
        ValueError,
        match="Parameters are declared for all phases at once. You must therefore "
        "not use 'phase' but 'list_index' instead",
    ):
        param.add("gravity_z", my_parameter_function, initial_gravity, bounds, size=1, phase=0)
def test_update_bounds_and_init_with_param():
    def my_parameter_function(biorbd_model, value, extra_value):
        biorbd_model.setGravity(biorbd.Vector3d(0, 0, value + extra_value))

    def my_target_function(ocp, value, target_value):
        return value + target_value

    biorbd_model = biorbd.Model(TestUtils.bioptim_folder() + "/examples/track/cube_and_line.bioMod")
    nq = biorbd_model.nbQ()
    ns = 10
    g_min, g_max, g_init = -10, -6, -8

    dynamics = DynamicsList()
    dynamics.add(DynamicsFcn.TORQUE_DRIVEN)

    parameters = ParameterList()
    bounds_gravity = Bounds(g_min, g_max, interpolation=InterpolationType.CONSTANT)
    initial_gravity = InitialGuess(g_init)
    parameter_objective_functions = Objective(
        my_target_function, weight=10, quadratic=True, custom_type=ObjectiveFcn.Parameter, target_value=-8
    )
    parameters.add(
        "gravity_z",
        my_parameter_function,
        initial_gravity,
        bounds_gravity,
        size=1,
        penalty_list=parameter_objective_functions,
        extra_value=1,
    )

    ocp = OptimalControlProgram(biorbd_model, dynamics, ns, 1.0, parameters=parameters)

    x_bounds = Bounds(-np.ones((nq * 2, 1)), np.ones((nq * 2, 1)))
    u_bounds = Bounds(-2.0 * np.ones((nq, 1)), 2.0 * np.ones((nq, 1)))
    ocp.update_bounds(x_bounds, u_bounds)

    expected = np.array([[-1] * (nq * 2) * (ns + 1) + [-2] * nq * ns]).T
    np.testing.assert_almost_equal(ocp.v.bounds.min, np.append(expected, [g_min])[:, np.newaxis])
    expected = np.array([[1] * (nq * 2) * (ns + 1) + [2] * nq * ns]).T
    np.testing.assert_almost_equal(ocp.v.bounds.max, np.append(expected, [g_max])[:, np.newaxis])

    x_init = InitialGuess(0.5 * np.ones((nq * 2, 1)))
    u_init = InitialGuess(-0.5 * np.ones((nq, 1)))
    ocp.update_initial_guess(x_init, u_init)
    expected = np.array([[0.5] * (nq * 2) * (ns + 1) + [-0.5] * nq * ns]).T
    np.testing.assert_almost_equal(ocp.v.init.init, np.append(expected, [g_init])[:, np.newaxis])
Ejemplo n.º 4
0
def prepare_ocp(phase_time_constraint, use_parameter):
    # --- Inputs --- #
    final_time = (2, 5, 4)
    time_min = [1, 3, 0.1]
    time_max = [2, 4, 0.8]
    ns = (20, 30, 20)
    biorbd_model_path = TestUtils.bioptim_folder(
    ) + "/examples/optimal_time_ocp/cube.bioMod"
    ode_solver = OdeSolver.RK4()

    # --- Options --- #
    n_phases = len(ns)

    # Model path
    biorbd_model = (biorbd.Model(biorbd_model_path),
                    biorbd.Model(biorbd_model_path),
                    biorbd.Model(biorbd_model_path))

    # Problem parameters
    tau_min, tau_max, tau_init = -100, 100, 0

    # Add objective functions
    objective_functions = ObjectiveList()
    objective_functions.add(ObjectiveFcn.Lagrange.MINIMIZE_TORQUE,
                            weight=100,
                            phase=0)
    objective_functions.add(ObjectiveFcn.Lagrange.MINIMIZE_TORQUE,
                            weight=100,
                            phase=1)
    objective_functions.add(ObjectiveFcn.Lagrange.MINIMIZE_TORQUE,
                            weight=100,
                            phase=2)

    # Dynamics
    dynamics = DynamicsList()
    dynamics.add(DynamicsFcn.TORQUE_DRIVEN, phase=0)
    dynamics.add(DynamicsFcn.TORQUE_DRIVEN, phase=1)
    dynamics.add(DynamicsFcn.TORQUE_DRIVEN, phase=2)

    # Constraints
    constraints = ConstraintList()
    constraints.add(ConstraintFcn.SUPERIMPOSE_MARKERS,
                    node=Node.START,
                    first_marker="m0",
                    second_marker="m1",
                    phase=0)
    constraints.add(ConstraintFcn.SUPERIMPOSE_MARKERS,
                    node=Node.END,
                    first_marker="m0",
                    second_marker="m2",
                    phase=0)
    constraints.add(ConstraintFcn.SUPERIMPOSE_MARKERS,
                    node=Node.END,
                    first_marker="m0",
                    second_marker="m1",
                    phase=1)
    constraints.add(ConstraintFcn.SUPERIMPOSE_MARKERS,
                    node=Node.END,
                    first_marker="m0",
                    second_marker="m2",
                    phase=2)

    constraints.add(
        ConstraintFcn.TIME_CONSTRAINT,
        node=Node.END,
        minimum=time_min[0],
        maximum=time_max[0],
        phase=phase_time_constraint,
    )

    # Path constraint
    x_bounds = BoundsList()
    x_bounds.add(bounds=QAndQDotBounds(biorbd_model[0]))  # Phase 0
    x_bounds.add(bounds=QAndQDotBounds(biorbd_model[0]))  # Phase 1
    x_bounds.add(bounds=QAndQDotBounds(biorbd_model[0]))  # Phase 2

    for bounds in x_bounds:
        for i in [1, 3, 4, 5]:
            bounds[i, [0, -1]] = 0
    x_bounds[0][2, 0] = 0.0
    x_bounds[2][2, [0, -1]] = [0.0, 1.57]

    # Initial guess
    x_init = InitialGuessList()
    x_init.add([0] * (biorbd_model[0].nbQ() + biorbd_model[0].nbQdot()))
    x_init.add([0] * (biorbd_model[0].nbQ() + biorbd_model[0].nbQdot()))
    x_init.add([0] * (biorbd_model[0].nbQ() + biorbd_model[0].nbQdot()))

    # Define control path constraint
    u_bounds = BoundsList()
    u_bounds.add([tau_min] * biorbd_model[0].nbGeneralizedTorque(),
                 [tau_max] * biorbd_model[0].nbGeneralizedTorque())
    u_bounds.add([tau_min] * biorbd_model[0].nbGeneralizedTorque(),
                 [tau_max] * biorbd_model[0].nbGeneralizedTorque())
    u_bounds.add([tau_min] * biorbd_model[0].nbGeneralizedTorque(),
                 [tau_max] * biorbd_model[0].nbGeneralizedTorque())

    u_init = InitialGuessList()
    u_init.add([tau_init] * biorbd_model[0].nbGeneralizedTorque())
    u_init.add([tau_init] * biorbd_model[0].nbGeneralizedTorque())
    u_init.add([tau_init] * biorbd_model[0].nbGeneralizedTorque())

    parameters = ParameterList()
    if use_parameter:

        def my_target_function(ocp, value, target_value):
            return value - target_value

        def my_parameter_function(biorbd_model, value, extra_value):
            new_gravity = MX.zeros(3, 1)
            new_gravity[2] = value + extra_value
            biorbd_model.setGravity(new_gravity)

        min_g = -10
        max_g = -6
        target_g = -8
        bound_gravity = Bounds(min_g,
                               max_g,
                               interpolation=InterpolationType.CONSTANT)
        initial_gravity = InitialGuess((min_g + max_g) / 2)
        parameter_objective_functions = Objective(
            my_target_function,
            weight=10,
            quadratic=True,
            custom_type=ObjectiveFcn.Parameter,
            target_value=target_g)
        parameters.add(
            "gravity_z",
            my_parameter_function,
            initial_gravity,
            bound_gravity,
            size=1,
            penalty_list=parameter_objective_functions,
            extra_value=1,
        )

    # ------------- #

    return OptimalControlProgram(
        biorbd_model[:n_phases],
        dynamics,
        ns,
        final_time[:n_phases],
        x_init,
        u_init,
        x_bounds,
        u_bounds,
        objective_functions,
        constraints,
        ode_solver=ode_solver,
        parameters=parameters,
    )
Ejemplo n.º 5
0
def prepare_ocp_parameters(
        biorbd_model_path,
        final_time,
        n_shooting,
        optim_gravity,
        optim_mass,
        min_g,
        max_g,
        target_g,
        min_m,
        max_m,
        target_m,
        ode_solver=OdeSolver.RK4(),
        use_sx=False,
) -> OptimalControlProgram:
    """
    Prepare the program

    Parameters
    ----------
    biorbd_model_path: str
        The path of the biorbd model
    final_time: float
        The time at the final node
    n_shooting: int
        The number of shooting points
    optim_gravity: bool
        If the gravity should be optimized
    optim_mass: bool
        If the mass should be optimized
    min_g: np.ndarray
        The minimal value for the gravity
    max_g: np.ndarray
        The maximal value for the gravity
    target_g: np.ndarray
        The target value for the gravity
    min_m: float
        The minimal value for the mass
    max_m: float
        The maximal value for the mass
    target_m: float
        The target value for the mass
    ode_solver: OdeSolver
        The type of ode solver used
    use_sx: bool
        If the program should be constructed using SX instead of MX (longer to create the CasADi graph, faster to solve)

    Returns
    -------
    The ocp ready to be solved
    """

    # --- Options --- #
    biorbd_model = biorbd.Model(biorbd_model_path)
    n_tau = biorbd_model.nbGeneralizedTorque()

    # Add objective functions
    objective_functions = ObjectiveList()
    objective_functions.add(ObjectiveFcn.Lagrange.MINIMIZE_TORQUE, weight=10)
    objective_functions.add(ObjectiveFcn.Mayer.MINIMIZE_TIME, weight=10)

    # Dynamics
    dynamics = Dynamics(DynamicsFcn.TORQUE_DRIVEN)

    # Path constraint
    x_bounds = QAndQDotBounds(biorbd_model)
    x_bounds[:, [0, -1]] = 0
    x_bounds[1, -1] = 3.14

    # Initial guess
    n_q = biorbd_model.nbQ()
    n_qdot = biorbd_model.nbQdot()
    x_init = InitialGuess([0] * (n_q + n_qdot))

    # Define control path constraint
    tau_min, tau_max, tau_init = -300, 300, 0
    u_bounds = Bounds([tau_min] * n_tau, [tau_max] * n_tau)
    u_bounds[1, :] = 0

    u_init = InitialGuess([tau_init] * n_tau)

    # Define the parameter to optimize
    parameters = ParameterList()

    if optim_gravity:
        # Give the parameter some min and max bounds
        bound_gravity = Bounds(min_g,
                               max_g,
                               interpolation=InterpolationType.CONSTANT)
        # and an initial condition
        initial_gravity = InitialGuess((min_g + max_g) / 2)
        # and an objective function
        parameter_objective_functions = Objective(
            my_target_function,
            weight=1000,
            quadratic=False,
            custom_type=ObjectiveFcn.Parameter,
            target=target_g)
        parameters.add(
            "gravity_xyz",  # The name of the parameter
            my_parameter_function,  # The function that modifies the biorbd model
            initial_gravity,  # The initial guess
            bound_gravity,  # The bounds
            size=
            3,  # The number of elements this particular parameter vector has
            penalty_list=
            parameter_objective_functions,  # ObjectiveFcn of constraint for this particular parameter
            scaling=np.array([1, 1, 10.0]),
            extra_value=1,  # You can define as many extra arguments as you want
        )

    if optim_mass:
        bound_mass = Bounds(min_m,
                            max_m,
                            interpolation=InterpolationType.CONSTANT)
        initial_mass = InitialGuess((min_m + max_m) / 2)
        mass_objective_functions = Objective(
            my_target_function,
            weight=100,
            quadratic=False,
            custom_type=ObjectiveFcn.Parameter,
            target=target_m)
        parameters.add(
            "mass",  # The name of the parameter
            set_mass,  # The function that modifies the biorbd model
            initial_mass,  # The initial guess
            bound_mass,  # The bounds
            size=
            1,  # The number of elements this particular parameter vector has
            penalty_list=
            mass_objective_functions,  # ObjectiveFcn of constraint for this particular parameter
            scaling=np.array([10.0]),
        )

    return OptimalControlProgram(
        biorbd_model,
        dynamics,
        n_shooting,
        final_time,
        x_init,
        u_init,
        x_bounds,
        u_bounds,
        objective_functions,
        parameters=parameters,
        ode_solver=ode_solver,
        use_sx=use_sx,
    )
def test_add_wrong_param():
    g_min, g_max, g_init = -10, -6, -8

    def my_parameter_function(biorbd_model, value, extra_value):
        biorbd_model.setGravity(biorbd.Vector3d(0, 0, value + extra_value))

    def my_target_function(ocp, value, target_value):
        return value + target_value

    parameters = ParameterList()
    initial_gravity = InitialGuess(g_init)
    bounds_gravity = Bounds(g_min,
                            g_max,
                            interpolation=InterpolationType.CONSTANT)
    parameter_objective_functions = Objective(
        my_target_function,
        weight=10,
        quadratic=True,
        custom_type=ObjectiveFcn.Parameter,
        target_value=-8)

    with pytest.raises(
            RuntimeError,
            match=
            "function, initial_guess, bounds and size are mandatory elements to declare a parameter"
    ):
        parameters.add(
            "gravity_z",
            [],
            initial_gravity,
            bounds_gravity,
            size=1,
            penalty_list=parameter_objective_functions,
            extra_value=1,
        )

    with pytest.raises(
            RuntimeError,
            match=
            "function, initial_guess, bounds and size are mandatory elements to declare a parameter"
    ):
        parameters.add(
            "gravity_z",
            my_parameter_function,
            None,
            bounds_gravity,
            size=1,
            penalty_list=parameter_objective_functions,
            extra_value=1,
        )

    with pytest.raises(
            RuntimeError,
            match=
            "function, initial_guess, bounds and size are mandatory elements to declare a parameter"
    ):
        parameters.add(
            "gravity_z",
            my_parameter_function,
            initial_gravity,
            None,
            size=1,
            penalty_list=parameter_objective_functions,
            extra_value=1,
        )

    with pytest.raises(
            RuntimeError,
            match=
            "function, initial_guess, bounds and size are mandatory elements to declare a parameter"
    ):
        parameters.add(
            "gravity_z",
            my_parameter_function,
            initial_gravity,
            bounds_gravity,
            penalty_list=parameter_objective_functions,
            extra_value=1,
        )
Ejemplo n.º 7
0
def test_param_scaling():
    param = ParameterList()

    my_parameter_function = 1
    initial_gravity = 1
    bounds = 1

    with pytest.raises(
        ValueError,
        match="Parameter scaling must be a numpy array",
    ):
        param.add("gravity_z", my_parameter_function, initial_gravity, bounds, size=1, scaling="a")

    with pytest.raises(
        ValueError,
        match="Parameter scaling must be a numpy array",
    ):
        param.add("gravity_z", my_parameter_function, initial_gravity, bounds, size=1, scaling=1.0)

    with pytest.raises(
        ValueError,
        match="Parameter scaling must be a numpy array",
    ):
        param.add("gravity_z", my_parameter_function, initial_gravity, bounds, size=1, scaling=[])

    with pytest.raises(
        ValueError,
        match="Parameter scaling must contain only positive values",
    ):
        param.add("gravity_z", my_parameter_function, initial_gravity, bounds, size=1, scaling=np.array([-1]))

    with pytest.raises(
        ValueError,
        match="Parameter scaling must be a 1- or 2- dimensional numpy array",
    ):
        param.add("gravity_z", my_parameter_function, initial_gravity, bounds, size=1, scaling=np.array([[[1]]]))

    with pytest.raises(
        ValueError, match=f"The shape \(2\) of the scaling of parameter gravity_z does not match the params shape."
    ):
        param.add("gravity_z", my_parameter_function, initial_gravity, bounds, size=3, scaling=np.array([1, 2]))

    with pytest.raises(
        ValueError, match=f"Invalid ncols for Parameter Scaling \(ncols = 2\), the expected number of column is 1"
    ):
        param.add("gravity_z", my_parameter_function, initial_gravity, bounds, size=3, scaling=np.ones((1, 2)))
Ejemplo n.º 8
0
def prepare_ocp(biorbd_model,
                final_time,
                number_shooting_points,
                marker_ref,
                excitations_ref,
                q_ref,
                state_init,
                f_init,
                use_residual_torque,
                activation_driven,
                kin_data_to_track,
                nb_threads,
                use_SX=True,
                param=False):

    # --- Options --- #
    nb_mus = biorbd_model.nbMuscleTotal()
    activation_min, activation_max, activation_init = 0, 1, 0.3
    excitation_min, excitation_max, excitation_init = 0, 1, 0.1
    torque_min, torque_max, torque_init = -100, 100, 0
    # nb_tau = biorbd_model.segment(0).nbQ()
    # tau_mapping = BidirectionalMapping(Mapping(range(6)), Mapping(range(nb_tau)))

    # Add objective functions
    objective_functions = ObjectiveList()
    objective_functions.add(Objective.Lagrange.TRACK_MUSCLES_CONTROL,
                            weight=10,
                            target=excitations_ref)
    # objective_functions.add(Objective.Lagrange.MINIMIZE_STATE, weight=1000,
    #                         idx_states=(0, 1, 2, 3, 4, 5, 11, 12, 13, 14, 15, 16))
    objective_functions.add(Objective.Lagrange.MINIMIZE_STATE,
                            weight=1,
                            idx_states=(6, 7, 8, 9, 10))

    if use_residual_torque:
        objective_functions.add(Objective.Lagrange.MINIMIZE_TORQUE,
                                weight=1)  # controls_idx=[6, 7, 8, 9, 10],

    if kin_data_to_track == "markers":
        objective_functions.add(Objective.Lagrange.TRACK_MARKERS,
                                weight=1000,
                                target=marker_ref)

    elif kin_data_to_track == "q":
        objective_functions.add(Objective.Lagrange.TRACK_STATE,
                                weight=100,
                                target=q_ref,
                                states_idx=range(biorbd_model.nbQ()))
    else:
        raise RuntimeError("Wrong choice of kin_data_to_track")

    # Dynamics
    dynamics = DynamicsTypeList()
    if use_residual_torque:
        dynamics.add(DynamicsType.MUSCLE_ACTIVATIONS_AND_TORQUE_DRIVEN)

    elif activation_driven:
        dynamics.add(DynamicsType.MUSCLE_ACTIVATIONS_DRIVEN)
    else:
        dynamics.add(DynamicsType.MUSCLE_EXCITATIONS_DRIVEN)

    # Constraints
    constraints = ()
    # constraints = ConstraintList()
    # constraints.add(Constraint.TRACK_TORQUE, instant=Instant.ALL, controls_idx=(6, 7, 8, 9, 10),
    #                 target=np.zeros((biorbd_model.nbQ()*2, number_shooting_points)))

    # Path constraint
    x_bounds = BoundsList()
    x_bounds.add(QAndQDotBounds(biorbd_model))
    # if use_SX:
    #     x_bounds[0].min[biorbd_model.nbQ():, 0] = -10
    #     x_bounds[0].max[biorbd_model.nbQ():, 0] = 10

    # Add muscle to the bounds
    if activation_driven is not True:
        x_bounds[0].concatenate(
            Bounds([activation_min] * biorbd_model.nbMuscles(),
                   [activation_max] * biorbd_model.nbMuscles()))

    # Initial guess
    x_init = InitialGuessList()
    if activation_driven:
        # state_base = np.ndarray((12, n_shooting_points+1))
        # for i in range(n_shooting_points+1):
        #     state_base[:, i] = np.concatenate((state_init[:6, 0], np.zeros((6))))
        x_init.add(state_init[:-nb_mus, :],
                   interpolation=InterpolationType.EACH_FRAME)
        # x_init.add(state_init[:-nb_mus, :], interpolation=InterpolationType.EACH_FRAME)
    else:
        x_init.add([0] * (biorbd_model.nbQ() + biorbd_model.nbQdot()) +
                   [0] * biorbd_model.nbMuscles())
        # x_init.add(state_init[biorbd_model.nbQ():, :], interpolation=InterpolationType.EACH_FRAME)

    # Add muscle to the bounds
    u_bounds = BoundsList()
    u_init = InitialGuessList()
    nb_tau = biorbd_model.nbGeneralizedTorque()
    init_residual_torque = np.concatenate((np.ones(
        (nb_tau, n_shooting_points)) * 0.5, excitations_ref))
    if use_residual_torque:
        u_bounds.add([
            [torque_min] * nb_tau +
            [excitation_min] * biorbd_model.nbMuscleTotal(),
            [torque_max] * nb_tau +
            [excitation_max] * biorbd_model.nbMuscleTotal(),
        ])
        # u_init.add([torque_init] * tau_mapping.reduce.len + [excitation_init] * biorbd_model.nbMuscleTotal())
        u_init.add(init_residual_torque,
                   interpolation=InterpolationType.EACH_FRAME)

    else:
        u_bounds.add([[excitation_min] * biorbd_model.nbMuscleTotal(),
                      [excitation_max] * biorbd_model.nbMuscleTotal()])
        if activation_driven:
            # u_init.add([activation_init] * biorbd_model.nbMuscleTotal())
            u_init.add(excitations_ref,
                       interpolation=InterpolationType.EACH_FRAME)
        else:
            # u_init.add([excitation_init] * biorbd_model.nbMuscleTotal())
            u_init.add(excitations_ref,
                       interpolation=InterpolationType.EACH_FRAME)

    # Get initial isometric forces
    fiso = []
    for k in range(nb_mus):
        fiso.append(
            biorbd_model.muscle(k).characteristics().forceIsoMax().to_mx())

    # Define the parameter to optimize
    bound_p_iso = Bounds(
        # min_bound=np.repeat(0.01, nb_mus+1), max_bound=np.repeat(7, nb_mus+1), interpolation=InterpolationType.CONSTANT)
        min_bound=[0.5] * nb_mus,
        max_bound=[3] * nb_mus,
        interpolation=InterpolationType.CONSTANT)
    bound_shape_factor = Bounds(min_bound=np.repeat(-3, nb_mus),
                                max_bound=np.repeat(0, nb_mus),
                                interpolation=InterpolationType.CONSTANT)

    p_iso_init = InitialGuess(f_init)
    initial_guess_A = InitialGuess([-3] * nb_mus)

    parameters = ParameterList()
    parameters.add(
        "p_iso",  # The name of the parameter
        modify_isometric_force,  # The function that modifies the biorbd model
        p_iso_init,
        bound_p_iso,  # The bounds
        size=
        nb_mus,  # The number of elements this particular parameter vector has
        fiso_init=fiso,
    )
    # parameters.add(
    #         "shape_factor",  # The name of the parameter
    #         modify_shape_factor,
    #         initial_guess_A,
    #         bound_shape_factor,  # The bounds
    #         size=nb_mus,  # The number of elements this particular parameter vector has
    # )

    # ------------- #
    return OptimalControlProgram(
        biorbd_model,
        dynamics,
        number_shooting_points,
        final_time,
        x_init,
        u_init,
        x_bounds,
        u_bounds,
        objective_functions,
        nb_threads=nb_threads,
        use_SX=use_SX,
        parameters=parameters,
        # tau_mapping=tau_mapping,
    )
Ejemplo n.º 9
0
def test_update_bounds_and_init_with_param():
    def my_parameter_function(biorbd_model, value, extra_value):
        biorbd_model.setGravity(biorbd.Vector3d(0, 0, value + extra_value))

    def my_target_function(ocp, value, target_value):
        return value + target_value

    PROJECT_FOLDER = Path(__file__).parent / ".."
    biorbd_model = biorbd.Model(
        str(PROJECT_FOLDER) + "/examples/align/cube_and_line.bioMod")
    nq = biorbd_model.nbQ()
    ns = 10
    g_min, g_max, g_init = -10, -6, -8

    dynamics = DynamicsTypeList()
    dynamics.add(DynamicsType.TORQUE_DRIVEN)

    parameters = ParameterList()
    bounds_gravity = Bounds(min_bound=g_min,
                            max_bound=g_max,
                            interpolation=InterpolationType.CONSTANT)
    initial_gravity = InitialGuess(g_init)
    parameter_objective_functions = ObjectiveOption(
        my_target_function,
        weight=10,
        quadratic=True,
        custom_type=Objective.Parameter,
        target_value=-8)
    parameters.add(
        "gravity_z",
        my_parameter_function,
        initial_gravity,
        bounds_gravity,
        size=1,
        penalty_list=parameter_objective_functions,
        extra_value=1,
    )

    ocp = OptimalControlProgram(biorbd_model,
                                dynamics,
                                ns,
                                1.0,
                                parameters=parameters)

    x_bounds = BoundsOption([-np.ones((nq * 2, 1)), np.ones((nq * 2, 1))])
    u_bounds = BoundsOption([-2.0 * np.ones((nq, 1)), 2.0 * np.ones((nq, 1))])
    ocp.update_bounds(x_bounds, u_bounds)

    expected = np.append(
        np.tile(np.append(-np.ones((nq * 2, 1)), -2.0 * np.ones((nq, 1))), ns),
        -np.ones((nq * 2, 1)))
    np.testing.assert_almost_equal(
        ocp.V_bounds.min,
        np.append([g_min], expected).reshape(129, 1))
    expected = np.append(
        np.tile(np.append(np.ones((nq * 2, 1)), 2.0 * np.ones((nq, 1))), ns),
        np.ones((nq * 2, 1)))
    np.testing.assert_almost_equal(
        ocp.V_bounds.max,
        np.append([[g_max]], expected).reshape(129, 1))

    x_init = InitialGuessOption(0.5 * np.ones((nq * 2, 1)))
    u_init = InitialGuessOption(-0.5 * np.ones((nq, 1)))
    ocp.update_initial_guess(x_init, u_init)
    expected = np.append(
        np.tile(np.append(0.5 * np.ones((nq * 2, 1)), -0.5 * np.ones((nq, 1))),
                ns), 0.5 * np.ones((nq * 2, 1)))
    np.testing.assert_almost_equal(
        ocp.V_init.init,
        np.append([g_init], expected).reshape(129, 1))