示例#1
0
def prepare_ocp(
    biorbd_model_path: str,
    final_time: float,
    n_shooting: int,
    ode_solver: OdeSolver = OdeSolver.RK4(),
    use_sx: bool = True,
    n_threads: int = 1,
) -> OptimalControlProgram:
    """
    The initialization of an ocp

    Parameters
    ----------
    biorbd_model_path: str
        The path to the biorbd model
    final_time: float
        The time in second required to perform the task
    n_shooting: int
        The number of shooting points to define int the direct multiple shooting program
    ode_solver: OdeSolver = OdeSolver.RK4()
        Which type of OdeSolver to use
    use_sx: bool
        If the SX variable should be used instead of MX (can be extensive on RAM)
    n_threads: int
        The number of threads to use in the paralleling (1 = no parallel computing)

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

    biorbd_model = biorbd.Model(biorbd_model_path)

    # Add objective functions
    objective_functions = Objective(ObjectiveFcn.Lagrange.MINIMIZE_CONTROL, key="tau")

    # 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
    n_tau = biorbd_model.nbGeneralizedTorque()
    tau_min, tau_max, tau_init = -100, 100, 0
    u_bounds = Bounds([tau_min] * n_tau, [tau_max] * n_tau)
    u_bounds[n_tau - 1, :] = 0

    u_init = InitialGuess([tau_init] * n_tau)

    return OptimalControlProgram(
        biorbd_model,
        dynamics,
        n_shooting,
        final_time,
        x_init=x_init,
        u_init=u_init,
        x_bounds=x_bounds,
        u_bounds=u_bounds,
        objective_functions=objective_functions,
        ode_solver=ode_solver,
        use_sx=use_sx,
        n_threads=n_threads,
    )
def prepare_ocp(
        biorbd_model_path: str,
        final_time: float,
        n_shooting: int,
        n_threads: int,
        use_sx: bool = False,
        ode_solver: OdeSolver = OdeSolver.RK4(),
) -> 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
    n_threads: int
        The number of threads to use while using multithreading
    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
    """

    biorbd_model = biorbd.Model(biorbd_model_path)

    # Add objective functions
    objective_functions = Objective(
        ObjectiveFcn.Lagrange.MINIMIZE_TORQUE_DERIVATIVE)

    # 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
    n_tau = biorbd_model.nbGeneralizedTorque()
    tau_min, tau_max, tau_init = -100, 100, 0
    u_bounds = Bounds([tau_min] * n_tau, [tau_max] * n_tau)
    u_bounds[n_tau - 1, :] = 0

    u_init = InitialGuess([tau_init] * n_tau)

    return OptimalControlProgram(
        biorbd_model,
        dynamics,
        n_shooting,
        final_time,
        x_init,
        u_init,
        x_bounds,
        u_bounds,
        objective_functions=objective_functions,
        n_threads=n_threads,
        use_sx=use_sx,
        ode_solver=ode_solver,
    )
示例#3
0
def prepare_ocp(
    biorbd_model_path: str,
    final_time: float,
    n_shooting: int,
    fatigue_type: str,
    split_controls: bool,
    use_sx: bool = True,
) -> OptimalControlProgram:
    """
    The initialization of an ocp

    Parameters
    ----------
    biorbd_model_path: str
        The path to the biorbd model
    final_time: float
        The time in second required to perform the task
    n_shooting: int
        The number of shooting points to define int the direct multiple shooting program
    fatigue_type: str
        The type of dynamics to apply ("xia" or "michaud")
    split_controls: bool
        If the tau should be split into minus and plus or a if_else should be used
    use_sx: bool
        If the program should be built from SX (True) or MX (False)

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

    biorbd_model = biorbd.Model(biorbd_model_path)
    n_tau = biorbd_model.nbGeneralizedTorque()
    tau_min, tau_max, tau_init = -100, 100, 0

    # Add objective functions
    objective_functions = Objective(ObjectiveFcn.Lagrange.MINIMIZE_CONTROL, key="tau", expand=True)

    # Fatigue parameters
    fatigue_dynamics = FatigueList()
    for i in range(n_tau):
        if fatigue_type == "xia":
            fatigue_dynamics.add(
                XiaTauFatigue(
                    XiaFatigue(LD=100, LR=100, F=5, R=10, scaling=tau_min),
                    XiaFatigue(LD=100, LR=100, F=5, R=10, scaling=tau_max),
                    state_only=False,
                    split_controls=split_controls,
                ),
            )
        elif fatigue_type == "xia_stabilized":
            fatigue_dynamics.add(
                XiaTauFatigue(
                    XiaFatigueStabilized(LD=100, LR=100, F=5, R=10, stabilization_factor=10, scaling=tau_min),
                    XiaFatigueStabilized(LD=100, LR=100, F=5, R=10, stabilization_factor=10, scaling=tau_max),
                    state_only=False,
                    split_controls=split_controls,
                ),
            )
        elif fatigue_type == "michaud":
            fatigue_dynamics.add(
                MichaudTauFatigue(
                    MichaudFatigue(
                        LD=100,
                        LR=100,
                        F=0.005,
                        R=0.005,
                        effort_threshold=0.2,
                        effort_factor=0.001,
                        stabilization_factor=10,
                        scaling=tau_min,
                    ),
                    MichaudFatigue(
                        LD=100,
                        LR=100,
                        F=0.005,
                        R=0.005,
                        effort_threshold=0.2,
                        effort_factor=0.001,
                        stabilization_factor=10,
                        scaling=tau_max,
                    ),
                    state_only=False,
                    split_controls=split_controls,
                ),
            )
        elif fatigue_type == "effort":
            fatigue_dynamics.add(
                TauEffortPerception(
                    EffortPerception(effort_threshold=0.2, effort_factor=0.001, scaling=tau_min),
                    EffortPerception(effort_threshold=0.2, effort_factor=0.001, scaling=tau_max),
                    split_controls=split_controls,
                )
            )
        else:
            raise ValueError("fatigue_type not implemented")

    # Dynamics
    dynamics = Dynamics(DynamicsFcn.TORQUE_DRIVEN, fatigue=fatigue_dynamics, expand=True)

    # Path constraint
    x_bounds = QAndQDotBounds(biorbd_model)
    x_bounds[:, [0, -1]] = 0
    x_bounds[1, -1] = 3.14
    x_bounds.concatenate(FatigueBounds(fatigue_dynamics, fix_first_frame=True))
    if fatigue_type != "effort":
        x_bounds[[5, 11], 0] = 0  # The rotation dof is passive (fatigue_ma = 0)
        if fatigue_type == "xia":
            x_bounds[[7, 13], 0] = 1  # The rotation dof is passive (fatigue_mr = 1)

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

    # Define control path constraint
    u_bounds = FatigueBounds(fatigue_dynamics, variable_type=VariableType.CONTROLS)
    if split_controls:
        u_bounds[[1, 3], :] = 0  # The rotation dof is passive
    else:
        u_bounds[1, :] = 0  # The rotation dof is passive
    u_init = FatigueInitialGuess(fatigue_dynamics, variable_type=VariableType.CONTROLS)

    return OptimalControlProgram(
        biorbd_model,
        dynamics,
        n_shooting,
        final_time,
        x_init=x_init,
        u_init=u_init,
        x_bounds=x_bounds,
        u_bounds=u_bounds,
        objective_functions=objective_functions,
        use_sx=use_sx,
    )
示例#4
0
def prepare_ocp(
        biorbd_model_path: str,
        final_time: float,
        n_shooting: int,
        time_min: float,
        time_max: float,
        ode_solver: OdeSolver = OdeSolver.RK4(),
) -> OptimalControlProgram:
    """
    Prepare the optimal control program

    Parameters
    ----------
    biorbd_model_path: str
        The path to the bioMod
    final_time: float
        The initial guess for the final time
    n_shooting: int
        The number of shooting points
    time_min: float
        The minimal time the phase can have
    time_max: float
        The maximal time the phase can have
    ode_solver: OdeSolver
        The ode solver to use

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

    biorbd_model = biorbd.Model(biorbd_model_path)

    # Add objective functions
    objective_functions = Objective(ObjectiveFcn.Lagrange.MINIMIZE_CONTROL,
                                    key="tau")

    # Dynamics
    expand = False if isinstance(ode_solver, OdeSolver.IRK) else True
    dynamics = Dynamics(DynamicsFcn.TORQUE_DRIVEN, expand=expand)

    # Constraints
    constraints = Constraint(ConstraintFcn.TIME_CONSTRAINT,
                             node=Node.END,
                             min_bound=time_min,
                             max_bound=time_max)

    # Path constraint
    n_q = biorbd_model.nbQ()
    n_qdot = biorbd_model.nbQdot()
    x_bounds = QAndQDotBounds(biorbd_model)
    x_bounds[:, [0, -1]] = 0
    x_bounds[n_q - 1, -1] = 3.14

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

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

    u_init = InitialGuess([tau_init] * n_tau)

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

    return OptimalControlProgram(
        biorbd_model,
        dynamics,
        n_shooting,
        final_time,
        x_init,
        u_init,
        x_bounds,
        u_bounds,
        objective_functions,
        constraints,
        ode_solver=ode_solver,
    )
示例#5
0
def test_update_bounds_and_init_with_param():
    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)

    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])
示例#6
0
def prepare_test_ocp(with_muscles=False,
                     with_contact=False,
                     with_actuator=False,
                     implicit=False,
                     use_sx=True):
    bioptim_folder = TestUtils.bioptim_folder()
    if with_muscles and with_contact or with_muscles and with_actuator or with_contact and with_actuator:
        raise RuntimeError(
            "With muscles and with contact and with_actuator together is not defined"
        )
    if with_muscles and implicit or implicit and with_actuator:
        raise RuntimeError(
            "With muscles and implicit and with_actuator together is not defined"
        )
    elif with_muscles:
        biorbd_model = biorbd.Model(
            bioptim_folder + "/examples/muscle_driven_ocp/models/arm26.bioMod")
        dynamics = DynamicsList()
        dynamics.add(DynamicsFcn.MUSCLE_DRIVEN, with_torque=True)
        nx = biorbd_model.nbQ() + biorbd_model.nbQdot()
        nu = biorbd_model.nbGeneralizedTorque() + biorbd_model.nbMuscles()
    elif with_contact:
        biorbd_model = biorbd.Model(
            bioptim_folder +
            "/examples/muscle_driven_with_contact/models/2segments_4dof_2contacts_1muscle.bioMod"
        )
        dynamics = DynamicsList()
        dynamics.add(DynamicsFcn.TORQUE_DRIVEN,
                     with_contact=True,
                     expand=False,
                     implicit_dynamics=implicit)
        nx = biorbd_model.nbQ() + biorbd_model.nbQdot()
        nu = biorbd_model.nbGeneralizedTorque()
    elif with_actuator:
        biorbd_model = biorbd.Model(
            bioptim_folder + "/examples/torque_driven_ocp/models/cube.bioMod")
        dynamics = DynamicsList()
        dynamics.add(DynamicsFcn.TORQUE_DRIVEN)
        nx = biorbd_model.nbQ() + biorbd_model.nbQdot()
        nu = biorbd_model.nbGeneralizedTorque()
    else:
        biorbd_model = biorbd.Model(
            bioptim_folder + "/examples/track/models/cube_and_line.bioMod")
        dynamics = DynamicsList()
        dynamics.add(DynamicsFcn.TORQUE_DRIVEN)
        nx = biorbd_model.nbQ() + biorbd_model.nbQdot()
        nu = biorbd_model.nbGeneralizedTorque()
    x_init = InitialGuess(np.zeros((nx, 1)))

    mod = 2 if implicit else 1

    u_init = InitialGuess(np.zeros((nu * mod, 1)))
    x_bounds = Bounds(np.zeros((nx, 1)), np.zeros((nx, 1)))
    u_bounds = Bounds(np.zeros((nu * mod, 1)), np.zeros((nu * mod, 1)))
    ocp = OptimalControlProgram(biorbd_model,
                                dynamics,
                                10,
                                1.0,
                                x_init,
                                u_init,
                                x_bounds,
                                u_bounds,
                                use_sx=use_sx)
    ocp.nlp[0].J = [[]]
    ocp.nlp[0].g = [[]]
    return ocp
示例#7
0
def prepare_ocp(
    biorbd_model_path: str,
    problem_type_custom: bool = True,
    ode_solver: OdeSolver = OdeSolver.RK4(),
    use_sx: bool = False,
) -> OptimalControlProgram:
    """
    Prepare the program

    Parameters
    ----------
    biorbd_model_path: str
        The path of the biorbd model
    problem_type_custom: bool
        If the preparation should be done using the user-defined dynamic function or the normal TORQUE_DRIVEN.
        They should return the same results
    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 --- #
    # Model path
    biorbd_model = biorbd.Model(biorbd_model_path)

    # Problem parameters
    n_shooting = 30
    final_time = 2

    # Add objective functions
    objective_functions = Objective(ObjectiveFcn.Lagrange.MINIMIZE_CONTROL, key="tau", weight=100, multi_thread=False)

    # Dynamics
    dynamics = DynamicsList()
    expand = False if isinstance(ode_solver, OdeSolver.IRK) else True
    if problem_type_custom:
        dynamics.add(custom_configure, dynamic_function=custom_dynamic, my_additional_factor=1, expand=expand)
    else:
        dynamics.add(DynamicsFcn.TORQUE_DRIVEN, dynamic_function=custom_dynamic, expand=expand)

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

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

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

    # Define control path constraint
    tau_min, tau_max, tau_init = -100, 100, 0
    u_bounds = Bounds([tau_min] * biorbd_model.nbGeneralizedTorque(), [tau_max] * biorbd_model.nbGeneralizedTorque())

    u_init = InitialGuess([tau_init] * biorbd_model.nbGeneralizedTorque())

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

    return OptimalControlProgram(
        biorbd_model,
        dynamics,
        n_shooting,
        final_time,
        x_init,
        u_init,
        x_bounds,
        u_bounds,
        objective_functions,
        constraints,
        ode_solver=ode_solver,
        use_sx=use_sx,
    )
示例#8
0
def prepare_ocp(biorbd_model_path, ode_solver=OdeSolver.RK4()) -> OptimalControlProgram:
    """
    Prepare the program

    Parameters
    ----------
    biorbd_model_path: str
        The path of the biorbd model
    ode_solver: OdeSolver
        The type of ode solver used

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

    # --- Options --- #
    # Model path
    biorbd_model = biorbd.Model(biorbd_model_path)

    # Problem parameters
    n_shooting = 30
    final_time = 2
    tau_min, tau_max, tau_init = -100, 100, 0

    # Add objective functions
    objective_functions = ObjectiveList()
    objective_functions.add(ObjectiveFcn.Lagrange.MINIMIZE_TORQUE)
    objective_functions.add(
        custom_func_track_markers,
        custom_type=ObjectiveFcn.Mayer,
        node=Node.START,
        quadratic=True,
        first_marker="m0",
        second_marker="m1",
        weight=1000,
    )
    objective_functions.add(
        custom_func_track_markers,
        custom_type=ObjectiveFcn.Mayer,
        node=Node.END,
        quadratic=True,
        first_marker="m0",
        second_marker="m2",
        weight=1000,
    )

    # Dynamics
    dynamics = Dynamics(DynamicsFcn.TORQUE_DRIVEN)

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

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

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

    u_init = InitialGuess([tau_init] * biorbd_model.nbGeneralizedTorque())

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

    return OptimalControlProgram(
        biorbd_model,
        dynamics,
        n_shooting,
        final_time,
        x_init,
        u_init,
        x_bounds,
        u_bounds,
        objective_functions,
        ode_solver=ode_solver,
    )
示例#9
0
def prepare_ocp(biorbd_model_path, ode_solver=OdeSolver.RK):
    # --- Options --- #
    # Model path
    biorbd_model = biorbd.Model(biorbd_model_path)

    # Problem parameters
    number_shooting_points = 30
    final_time = 2
    tau_min, tau_max, tau_init = -100, 100, 0

    # Add objective functions
    objective_functions = ObjectiveList()
    objective_functions.add(ObjectiveFcn.Lagrange.MINIMIZE_TORQUE)
    objective_functions.add(
        custom_func_align_markers,
        custom_type=ObjectiveFcn.Mayer,
        node=Node.START,
        quadratic=True,
        first_marker_idx=0,
        second_marker_idx=1,
        weight=1000,
    )
    objective_functions.add(
        custom_func_align_markers,
        custom_type=ObjectiveFcn.Mayer,
        node=Node.END,
        quadratic=True,
        first_marker_idx=0,
        second_marker_idx=2,
        weight=1000,
    )

    # Dynamics
    dynamics = Dynamics(DynamicsFcn.TORQUE_DRIVEN)

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

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

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

    u_init = InitialGuess([tau_init] * biorbd_model.nbGeneralizedTorque())

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

    return OptimalControlProgram(
        biorbd_model,
        dynamics,
        number_shooting_points,
        final_time,
        x_init,
        u_init,
        x_bounds,
        u_bounds,
        objective_functions,
        ode_solver=ode_solver,
    )
示例#10
0
def prepare_ocp(
    biorbd_model,
    final_time,
    x0,
    nbGT,
    number_shooting_points,
    use_SX=False,
    nb_threads=8,
    use_torque=False,
    use_activation=False,
):
    # --- Options --- #
    # Model path
    biorbd_model = biorbd_model
    nbGT = nbGT
    nbMT = biorbd_model.nbMuscleTotal()
    tau_min, tau_max, tau_init = -100, 100, 0
    muscle_min, muscle_max, muscle_init = 0, 1, 0.5
    activation_min, activation_max, activation_init = 0, 1, 0.2

    # Add objective functions
    objective_functions = ObjectiveList()

    # Dynamics
    dynamics = DynamicsList()
    if use_activation and use_torque:
        dynamics.add(DynamicsFcn.MUSCLE_ACTIVATIONS_AND_TORQUE_DRIVEN)
    elif use_activation is not True and use_torque:
        dynamics.add(DynamicsFcn.MUSCLE_EXCITATIONS_AND_TORQUE_DRIVEN)
    elif use_activation and use_torque is not True:
        dynamics.add(DynamicsFcn.MUSCLE_ACTIVATIONS_DRIVEN)
    elif use_activation is not True and use_torque is not True:
        dynamics.add(DynamicsFcn.MUSCLE_EXCITATIONS_DRIVEN)

    # State path constraint
    x_bounds = BoundsList()
    x_bounds.add(bounds=QAndQDotBounds(biorbd_model))
    if use_activation is not True:
        x_bounds[0].concatenate(
            Bounds([activation_min] * biorbd_model.nbMuscles(),
                   [activation_max] * biorbd_model.nbMuscles()))

    # Control path constraint
    u_bounds = BoundsList()
    u_bounds.add(
        [tau_min] * nbGT + [muscle_min] * biorbd_model.nbMuscleTotal(),
        [tau_max] * nbGT + [muscle_max] * biorbd_model.nbMuscleTotal(),
    )

    # Initial guesses
    x_init = InitialGuess(np.tile(x0, (number_shooting_points + 1, 1)).T,
                          interpolation=InterpolationType.EACH_FRAME)

    u0 = np.array([tau_init] * nbGT + [muscle_init] * nbMT)
    u_init = InitialGuess(np.tile(u0, (number_shooting_points, 1)).T,
                          interpolation=InterpolationType.EACH_FRAME)
    # ------------- #

    return OptimalControlProgram(
        biorbd_model,
        dynamics,
        number_shooting_points,
        final_time,
        x_init,
        u_init,
        x_bounds,
        u_bounds,
        objective_functions,
        use_sx=use_SX,
        n_threads=nb_threads,
    )
示例#11
0
def prepare_ocp(
    biorbd_model_path: str,
    final_time: float,
    n_shooting: int,
    fatigue_type: str,
    ode_solver: OdeSolver = OdeSolver.COLLOCATION(),
    torque_level: int = 0,
) -> OptimalControlProgram:
    """
    Prepare the ocp
    Parameters
    ----------
    biorbd_model_path: str
        The path to the bioMod
    final_time: float
        The time at the final node
    n_shooting: int
        The number of shooting points
    fatigue_type: str
        The type of dynamics to apply ("xia" or "michaud")
    ode_solver: OdeSolver
        The ode solver to use
    torque_level: int
        0 no residual torque, 1 with residual torque, 2 with fatigable residual torque
    Returns
    -------
    The OptimalControlProgram ready to be solved
    """

    biorbd_model = biorbd.Model(biorbd_model_path)

    n_tau = biorbd_model.nbGeneralizedTorque()
    n_muscles = biorbd_model.nbMuscleTotal()
    tau_min, tau_max = -10, 10

    # Define fatigue parameters for each muscle and residual torque
    fatigue_dynamics = FatigueList()
    for i in range(n_muscles):
        if fatigue_type == "xia":
            fatigue_dynamics.add(XiaFatigue(LD=10, LR=10, F=0.01, R=0.002), state_only=False)
        elif fatigue_type == "xia_stabilized":
            fatigue_dynamics.add(
                XiaFatigueStabilized(LD=10, LR=10, F=0.01, R=0.002, stabilization_factor=10), state_only=False
            )
        elif fatigue_type == "michaud":
            fatigue_dynamics.add(
                MichaudFatigue(
                    LD=100, LR=100, F=0.005, R=0.005, effort_threshold=0.2, effort_factor=0.001, stabilization_factor=10
                ),
                state_only=True,
            )
        elif fatigue_type == "effort":
            fatigue_dynamics.add(EffortPerception(effort_threshold=0.2, effort_factor=0.001))
        else:
            raise ValueError("fatigue_type not implemented")
    if torque_level >= 2:
        for i in range(n_tau):
            if fatigue_type == "xia":
                fatigue_dynamics.add(
                    XiaTauFatigue(
                        XiaFatigue(LD=10, LR=10, F=5, R=10, scaling=tau_min),
                        XiaFatigue(LD=10, LR=10, F=5, R=10, scaling=tau_max),
                    ),
                    state_only=False,
                )
            elif fatigue_type == "xia_stabilized":
                fatigue_dynamics.add(
                    XiaTauFatigue(
                        XiaFatigueStabilized(LD=10, LR=10, F=5, R=10, stabilization_factor=10, scaling=tau_min),
                        XiaFatigueStabilized(LD=10, LR=10, F=5, R=10, stabilization_factor=10, scaling=tau_max),
                    ),
                    state_only=False,
                )
            elif fatigue_type == "michaud":
                fatigue_dynamics.add(
                    MichaudTauFatigue(
                        MichaudFatigue(
                            LD=10, LR=10, F=5, R=10, effort_threshold=0.15, effort_factor=0.07, scaling=tau_min
                        ),
                        MichaudFatigue(
                            LD=10, LR=10, F=5, R=10, effort_threshold=0.15, effort_factor=0.07, scaling=tau_max
                        ),
                    ),
                    state_only=False,
                )
            elif fatigue_type == "effort":
                fatigue_dynamics.add(
                    TauEffortPerception(
                        EffortPerception(effort_threshold=0.15, effort_factor=0.001, scaling=tau_min),
                        EffortPerception(effort_threshold=0.15, effort_factor=0.001, scaling=tau_max),
                    ),
                    state_only=False,
                )
            else:
                raise ValueError("fatigue_type not implemented")

    # Dynamics
    dynamics = Dynamics(DynamicsFcn.MUSCLE_DRIVEN, expand=False, fatigue=fatigue_dynamics, with_torque=torque_level > 0)

    # Add objective functions
    objective_functions = ObjectiveList()
    if torque_level > 0:
        objective_functions.add(ObjectiveFcn.Lagrange.MINIMIZE_CONTROL, key="tau")
    objective_functions.add(ObjectiveFcn.Lagrange.MINIMIZE_CONTROL, key="muscles", weight=100)
    objective_functions.add(
        ObjectiveFcn.Mayer.SUPERIMPOSE_MARKERS, first_marker="target", second_marker="COM_hand", weight=0.01
    )
    objective_functions.add(ObjectiveFcn.Lagrange.MINIMIZE_FATIGUE, key="muscles", weight=1000)

    # Constraint
    constraint = Constraint(
        ConstraintFcn.SUPERIMPOSE_MARKERS,
        first_marker="target",
        second_marker="COM_hand",
        node=Node.END,
        axes=[Axis.X, Axis.Y],
    )

    x_bounds = QAndQDotBounds(biorbd_model)
    x_bounds[:, 0] = (0.07, 1.4, 0, 0)
    x_bounds.concatenate(FatigueBounds(fatigue_dynamics, fix_first_frame=True))

    x_init = InitialGuess([1.57] * biorbd_model.nbQ() + [0] * biorbd_model.nbQdot())
    x_init.concatenate(FatigueInitialGuess(fatigue_dynamics))

    # Define control path constraint
    u_bounds = Bounds([tau_min] * n_tau, [tau_max] * n_tau) if torque_level == 1 else Bounds()
    u_bounds.concatenate(FatigueBounds(fatigue_dynamics, variable_type=VariableType.CONTROLS))
    u_init = InitialGuess([0] * n_tau) if torque_level == 1 else InitialGuess()
    u_init.concatenate(FatigueInitialGuess(fatigue_dynamics, variable_type=VariableType.CONTROLS))

    return OptimalControlProgram(
        biorbd_model,
        dynamics,
        n_shooting,
        final_time,
        x_init,
        u_init,
        x_bounds,
        u_bounds,
        objective_functions,
        constraint,
        ode_solver=ode_solver,
        use_sx=False,
        n_threads=8,
    )
示例#12
0
def prepare_ocp(
    biorbd_model_path: str, ode_solver: OdeSolver = OdeSolver.IRK()
) -> OptimalControlProgram:
    """
    Prepare the program

    Parameters
    ----------
    biorbd_model_path: str
        The path of the biorbd model
    ode_solver: OdeSolver
        The type of ode solver used

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

    # --- Options --- #
    # Model path
    biorbd_model = biorbd.Model(biorbd_model_path)

    # Problem parameters
    n_shooting = 30
    final_time = 2
    tau_min, tau_max, tau_init = -100, 100, 0

    # Add objective functions
    objective_functions = Objective(ObjectiveFcn.Lagrange.MINIMIZE_CONTROL,
                                    key="tau",
                                    weight=100)

    # Dynamics
    expand = False if isinstance(ode_solver, OdeSolver.IRK) else True
    dynamics = Dynamics(DynamicsFcn.TORQUE_DRIVEN, expand=expand)

    # Constraints
    constraints = ConstraintList()
    constraints.add(custom_func_track_markers,
                    node=Node.START,
                    first_marker="m0",
                    second_marker="m1",
                    method=0)
    constraints.add(custom_func_track_markers,
                    node=Node.END,
                    first_marker="m0",
                    second_marker="m2",
                    method=1)

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

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

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

    u_init = InitialGuess([tau_init] * biorbd_model.nbGeneralizedTorque())

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

    return OptimalControlProgram(
        biorbd_model,
        dynamics,
        n_shooting,
        final_time,
        x_init,
        u_init,
        x_bounds,
        u_bounds,
        objective_functions,
        constraints,
        ode_solver=ode_solver,
    )
示例#13
0
                                index=1,
                                weight=-1)

# Dynamics
dynamics = Dynamics(custom_configure, dynamic_function=custom_dynamic)

# Path constraint
x_bounds = QAndQDotBounds(m)
x_bounds[:, 0] = [0] * m.nbQ() + [0] * m.nbQdot()
x_bounds.min[:, 1] = [-1] * m.nbQ() + [-100] * m.nbQdot()
x_bounds.max[:, 1] = [1] * m.nbQ() + [100] * m.nbQdot()
x_bounds.min[:, 2] = [-1] * m.nbQ() + [-100] * m.nbQdot()
x_bounds.max[:, 2] = [1] * m.nbQ() + [100] * m.nbQdot()

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

# Define control path constraint
u_bounds = Bounds([-100] * m.nbGeneralizedTorque(),
                  [0] * m.nbGeneralizedTorque())

u_init = InitialGuess([0] * m.nbGeneralizedTorque())
ocp = OptimalControlProgram(
    m,
    dynamics,
    number_shooting_points=30,
    phase_time=0.5,
    x_init=x_init,
    u_init=u_init,
    x_bounds=x_bounds,
    u_bounds=u_bounds,
示例#14
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_CONTROL,
                            key="tau",
                            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,
    )
示例#15
0
def generate_state(model_path, T, Ns, nb_phase, x_phase):
    # Parameters of the problem
    biorbd_model = biorbd.Model(model_path)
    X_est = np.zeros((biorbd_model.nbQ() * 2 + biorbd_model.nbMuscleTotal(), nb_phase * Ns + 1))
    U_est = np.zeros((biorbd_model.nbMuscleTotal(), nb_phase * Ns))

    # Set the joint angles target for each phase
    x0 = x_phase[0, :]
    # Build graph
    ocp = prepare_ocp(biorbd_model=biorbd_model, final_time=T, number_shooting_points=Ns, x0=x0, use_sx=True)
    x0 = np.concatenate((x0, np.array([0.2] * biorbd_model.nbMuscles())))
    # Solve for each phase
    for phase in range(1, nb_phase + 1):
        # impose it as first state of next solve
        ocp.nlp[0].x_bounds.min[:, 0] = x0
        ocp.nlp[0].x_bounds.max[:, 0] = x0

        # update initial guess on states
        x_init = InitialGuess(np.tile(x0, (ocp.nlp[0].ns + 1, 1)).T, interpolation=InterpolationType.EACH_FRAME)
        ocp.update_initial_guess(x_init=x_init)

        # Update objectives functions
        objectives = ObjectiveList()
        objectives.add(ObjectiveFcn.Lagrange.MINIMIZE_STATE, weight=10, index=np.array(range(biorbd_model.nbQ())))
        objectives.add(
            ObjectiveFcn.Lagrange.MINIMIZE_STATE,
            weight=10,
            index=np.array(range(biorbd_model.nbQ(), biorbd_model.nbQ() * 2)),
        )
        objectives.add(
            ObjectiveFcn.Lagrange.MINIMIZE_STATE,
            weight=10,
            index=np.array(range(biorbd_model.nbQ() * 2, biorbd_model.nbQ() * 2 + biorbd_model.nbMuscles())),
        )
        objectives.add(ObjectiveFcn.Lagrange.MINIMIZE_MUSCLES_CONTROL, weight=10)

        objectives.add(
            ObjectiveFcn.Mayer.TRACK_STATE,
            weight=10000,
            target=np.array([x_phase[phase, : biorbd_model.nbQ() * 2]]).T,
            index=np.array(range(biorbd_model.nbQ() * 2)),
        )
        ocp.update_objectives(objectives)
        sol = ocp.solve(
            solver=Solver.ACADOS,
            show_online_optim=False,
            solver_options={
                # "nlp_solver_max_iter": 50,
                "nlp_solver_tol_comp": 1e-7,
                "nlp_solver_tol_eq": 1e-7,
                "nlp_solver_tol_stat": 1e-7,
            },
        )

        # get last state of previous solve
        x_out, u_out, x0 = switch_phase(ocp, sol)

        # Store optimal solution
        X_est[:, (phase - 1) * Ns : phase * Ns] = x_out
        U_est[:, (phase - 1) * Ns : phase * Ns] = u_out

    # Collect last state
    X_est[:, -1] = x0

    return X_est
示例#16
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_idx=0,
                    second_marker_idx=1,
                    phase=0)
    constraints.add(ConstraintFcn.SUPERIMPOSE_MARKERS,
                    node=Node.END,
                    first_marker_idx=0,
                    second_marker_idx=2,
                    phase=0)
    constraints.add(ConstraintFcn.SUPERIMPOSE_MARKERS,
                    node=Node.END,
                    first_marker_idx=0,
                    second_marker_idx=1,
                    phase=1)
    constraints.add(ConstraintFcn.SUPERIMPOSE_MARKERS,
                    node=Node.END,
                    first_marker_idx=0,
                    second_marker_idx=2,
                    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):
            biorbd_model.setGravity(biorbd.Vector3d(0, 0, 2))

        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,
    )
示例#17
0
def prepare_ocp(
    biorbd_model_path: str,
    n_shooting: int,
    final_time: float,
    interpolation_type: InterpolationType = InterpolationType.CONSTANT_WITH_FIRST_AND_LAST_DIFFERENT,
) -> OptimalControlProgram:
    """
    Prepare the ocp for the specified interpolation type

    Parameters
    ----------
    biorbd_model_path: str
        The path to the biorbd model
    n_shooting: int
        The number of shooting point
    final_time: float
        The movement time
    interpolation_type: InterpolationType
        The requested InterpolationType

    Returns
    -------
    The OCP fully prepared and ready to be solved
    """

    # Model path
    biorbd_model = biorbd.Model(biorbd_model_path)
    nq = biorbd_model.nbQ()
    nqdot = biorbd_model.nbQdot()
    ntau = biorbd_model.nbGeneralizedTorque()
    tau_min, tau_max, tau_init = -100, 100, 0

    # Add objective functions
    objective_functions = Objective(ObjectiveFcn.Lagrange.MINIMIZE_TORQUE)

    # Dynamics
    dynamics = Dynamics(DynamicsFcn.TORQUE_DRIVEN)

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

    # Path constraints
    if interpolation_type == InterpolationType.CONSTANT:
        x_min = [-100] * (nq + nqdot)
        x_max = [100] * (nq + nqdot)
        x_bounds = Bounds(x_min, x_max, interpolation=InterpolationType.CONSTANT)
        u_min = [tau_min] * ntau
        u_max = [tau_max] * ntau
        u_bounds = Bounds(u_min, u_max, interpolation=InterpolationType.CONSTANT)
    elif interpolation_type == InterpolationType.CONSTANT_WITH_FIRST_AND_LAST_DIFFERENT:
        x_min = np.random.random((6, 3)) * (-10) - 5
        x_max = np.random.random((6, 3)) * 10 + 5
        x_bounds = Bounds(x_min, x_max, interpolation=InterpolationType.CONSTANT_WITH_FIRST_AND_LAST_DIFFERENT)
        u_min = np.random.random((3, 3)) * tau_min + tau_min / 2
        u_max = np.random.random((3, 3)) * tau_max + tau_max / 2
        u_bounds = Bounds(u_min, u_max, interpolation=InterpolationType.CONSTANT_WITH_FIRST_AND_LAST_DIFFERENT)
    elif interpolation_type == InterpolationType.LINEAR:
        x_min = np.random.random((6, 2)) * (-10) - 5
        x_max = np.random.random((6, 2)) * 10 + 5
        x_bounds = Bounds(x_min, x_max, interpolation=InterpolationType.LINEAR)
        u_min = np.random.random((3, 2)) * tau_min + tau_min / 2
        u_max = np.random.random((3, 2)) * tau_max + tau_max / 2
        u_bounds = Bounds(u_min, u_max, interpolation=InterpolationType.LINEAR)
    elif interpolation_type == InterpolationType.EACH_FRAME:
        x_min = np.random.random((nq + nqdot, n_shooting + 1)) * (-10) - 5
        x_max = np.random.random((nq + nqdot, n_shooting + 1)) * 10 + 5
        x_bounds = Bounds(x_min, x_max, interpolation=InterpolationType.EACH_FRAME)
        u_min = np.random.random((ntau, n_shooting)) * tau_min + tau_min / 2
        u_max = np.random.random((ntau, n_shooting)) * tau_max + tau_max / 2
        u_bounds = Bounds(u_min, u_max, interpolation=InterpolationType.EACH_FRAME)
    elif interpolation_type == InterpolationType.SPLINE:
        spline_time = np.hstack((0, np.sort(np.random.random((3,)) * final_time), final_time))
        x_min = np.random.random((nq + nqdot, 5)) * (-10) - 5
        x_max = np.random.random((nq + nqdot, 5)) * 10 + 5
        u_min = np.random.random((ntau, 5)) * tau_min + tau_min / 2
        u_max = np.random.random((ntau, 5)) * tau_max + tau_max / 2
        x_bounds = Bounds(x_min, x_max, interpolation=InterpolationType.SPLINE, t=spline_time)
        u_bounds = Bounds(u_min, u_max, interpolation=InterpolationType.SPLINE, t=spline_time)
    elif interpolation_type == InterpolationType.CUSTOM:
        # The custom functions refer to the ones at the beginning of the file.
        # For this particular instance, they emulate a Linear interpolation
        extra_params_x = {"n_elements": nq + nqdot, "n_shooting": n_shooting}
        extra_params_u = {"n_elements": ntau, "n_shooting": n_shooting}
        x_bounds = Bounds(
            custom_x_bounds_min, custom_x_bounds_max, interpolation=InterpolationType.CUSTOM, **extra_params_x
        )
        u_bounds = Bounds(
            custom_u_bounds_min, custom_u_bounds_max, interpolation=InterpolationType.CUSTOM, **extra_params_u
        )
    else:
        raise NotImplementedError("Not implemented yet")

    # Initial guess
    x_init = InitialGuess([0] * (nq + nqdot))
    u_init = InitialGuess([tau_init] * ntau)

    return OptimalControlProgram(
        biorbd_model,
        dynamics,
        n_shooting,
        final_time,
        x_init,
        u_init,
        x_bounds,
        u_bounds,
        objective_functions,
        constraints,
    )
示例#18
0
def run_mhe(model_path, ocp, var, conf, fold):
    # Set variables
    Ns, T, Ns_mhe, rt_ratio = var["Ns"], var["T"], var["Ns_mhe"], var[
        "rt_ratio"]
    co, marker_lvl, EMG_lvl = var["co"], var["marker_lvl"], var["EMG_lvl"]
    X_est, U_est = var["X_est"], var["U_est"]
    markers_target, muscles_target = var["markers_target"], var[
        "muscles_target"]
    marker_noise_lvl, EMG_noise_lvl = var["marker_noise_lvl"], var[
        "EMG_noise_lvl"]
    x_ref, u_ref = var["x_ref"], var["u_ref"]
    biorbd_model = biorbd.Model(model_path)
    nbQ, nbMT = biorbd_model.nbQ(), biorbd_model.nbMuscles()
    nbGT = biorbd_model.nbGeneralizedTorque() if conf["use_torque"] else 0
    q_ref, dq_ref, a_ref = x_ref[:nbQ, :], x_ref[nbQ:nbQ * 2, :], x_ref[nbQ *
                                                                        2:, :]
    if "TRACK_LESS_EMG" in conf.keys():
        TRACK_LESS_EMG = conf["TRACK_LESS_EMG"]
        idx = var["idx_muscle_track"] if conf["TRACK_LESS_EMG"] else False
    else:
        idx = None
        TRACK_LESS_EMG = False
    # Set number of tries
    nb_try = var["nb_try"] if conf["use_try"] else 1

    # Set variables' shape for all tries
    X_est_tries = np.ndarray((nb_try, X_est.shape[0], X_est.shape[1]))
    U_est_tries = np.ndarray((nb_try, U_est.shape[0], U_est.shape[1]))
    markers_target_tries = np.ndarray(
        (nb_try, markers_target.shape[0], markers_target.shape[1], Ns + 1))
    muscles_target_tries = np.ndarray(
        (nb_try, muscles_target.shape[0], Ns + 1))
    force_ref = np.ndarray((biorbd_model.nbMuscles(), Ns))
    force_est = np.ndarray(
        (nb_try, biorbd_model.nbMuscles(), int(ceil(Ns / rt_ratio) - Ns_mhe)))

    err_tries = np.ndarray((nb_try, 10))
    # Loop for simulate some tries, generate new random noise to each try
    for tries in range(nb_try):
        # Print current optimisation configuration
        print(
            f"- Ns_mhe = {Ns_mhe}; Co_lvl: {co}; Marker_noise: {marker_lvl}; EMG_noise : {EMG_lvl}; nb_try : {tries} -"
        )
        # Generate data with noise
        if conf["use_noise"]:
            if marker_lvl != 0:
                markers_target = generate_noise(biorbd_model, q_ref, u_ref,
                                                marker_noise_lvl[marker_lvl],
                                                EMG_noise_lvl[EMG_lvl])[0]

            if EMG_lvl != 0:
                muscles_target = generate_noise(biorbd_model, q_ref, u_ref,
                                                marker_noise_lvl[marker_lvl],
                                                EMG_noise_lvl[EMG_lvl])[1]

        # Reload the model with the original markers
        biorbd_model = biorbd.Model(model_path)

        # Update bounds
        x_bounds = BoundsList()
        x_bounds.add(bounds=QAndQDotBounds(biorbd_model))
        if conf["use_activation"] is not True:
            x_bounds[0].concatenate(
                Bounds([0] * biorbd_model.nbMuscles(),
                       [1] * biorbd_model.nbMuscles()))
        x_bounds[0].min[:biorbd_model.nbQ() * 2,
                        0] = x_ref[:biorbd_model.nbQ() * 2, 0] - 0.1
        x_bounds[0].max[:biorbd_model.nbQ() * 2,
                        0] = x_ref[:biorbd_model.nbQ() * 2, 0] + 0.1
        ocp.update_bounds(x_bounds)

        # Update initial guess
        x0 = x_ref[:biorbd_model.nbQ() * 2,
                   0] if conf["use_activation"] else x_ref[:, 0]
        x_init = InitialGuess(x0, interpolation=InterpolationType.CONSTANT)
        u0 = muscles_target
        u_init = InitialGuess(u0[:, 0],
                              interpolation=InterpolationType.CONSTANT)
        ocp.update_initial_guess(x_init, u_init)

        # Update objectives functions
        ocp.update_objectives(
            define_objective(
                conf["use_activation"],
                conf["use_torque"],
                conf["TRACK_EMG"],
                0,
                rt_ratio,
                nbGT,
                Ns_mhe,
                muscles_target,
                markers_target,
                conf["with_low_weight"],
                biorbd_model,
                idx=idx,
                TRACK_LESS_EMG=TRACK_LESS_EMG,
            ))

        # Initialize the solver options
        if co == 0 and marker_lvl == 0 and EMG_lvl == 0 and tries == 0:
            sol = ocp.solve(
                solver=Solver.ACADOS,
                show_online_optim=False,
                solver_options={
                    "nlp_solver_tol_comp": 1e-4,
                    "nlp_solver_tol_eq": 1e-4,
                    "nlp_solver_tol_stat": 1e-4,
                    "integrator_type": "IRK",
                    "nlp_solver_type": "SQP",
                    "sim_method_num_steps": 1,
                    "print_level": 0,
                    "nlp_solver_max_iter": 15,
                },
            )

        # Update all allowed solver options
        else:
            sol = ocp.solve(
                solver=Solver.ACADOS,
                show_online_optim=False,
                solver_options={
                    "nlp_solver_tol_comp": 1e-4,
                    "nlp_solver_tol_eq": 1e-4,
                    "nlp_solver_tol_stat": 1e-4,
                },
            )

        # Save status of optimisation
        if sol["status"] != 0 and conf["save_status"]:
            if conf["TRACK_EMG"]:
                f = open(f"{fold}status_track_rt_EMG{conf['TRACK_EMG']}.txt",
                         "a")
            else:
                f = open(f"{fold}status_track_rt_EMG{conf['TRACK_EMG']}.txt",
                         "a")
            f.write(f"{Ns_mhe}; {co}; {marker_lvl}; {EMG_lvl}; {tries}; "
                    f"'init'\n")
            f.close()

        # Set solutions and set initial guess for next optimisation
        x0, u0, X_est[:, 0], U_est[:, 0] = warm_start_mhe(
            ocp, sol, use_activation=conf["use_activation"])

        tic = time()  # Save initial time
        for iter in range(1, ceil(Ns / rt_ratio - Ns_mhe)):
            # set initial state
            ocp.nlp[0].x_bounds.min[:, 0] = x0[:, 0]
            ocp.nlp[0].x_bounds.max[:, 0] = x0[:, 0]

            # Update initial guess
            x_init = InitialGuess(x0,
                                  interpolation=InterpolationType.EACH_FRAME)
            u_init = InitialGuess(u0,
                                  interpolation=InterpolationType.EACH_FRAME)
            ocp.update_initial_guess(x_init, u_init)

            # Update objectives functions
            ocp.update_objectives(
                define_objective(
                    conf["use_activation"],
                    conf["use_torque"],
                    conf["TRACK_EMG"],
                    iter,
                    rt_ratio,
                    nbGT,
                    Ns_mhe,
                    muscles_target,
                    markers_target,
                    conf["with_low_weight"],
                    biorbd_model,
                    idx,
                    TRACK_LESS_EMG=TRACK_LESS_EMG,
                ))

            # Solve problem
            sol = ocp.solve(
                solver=Solver.ACADOS,
                show_online_optim=False,
                solver_options={
                    "nlp_solver_tol_comp": 1e-4,
                    "nlp_solver_tol_eq": 1e-4,
                    "nlp_solver_tol_stat": 1e-4,
                },
            )
            # Set solutions and set initial guess for next optimisation
            x0, u0, X_est[:, iter], u_out = warm_start_mhe(
                ocp, sol, use_activation=conf["use_activation"])
            if iter < int((Ns / rt_ratio) - Ns_mhe):
                U_est[:, iter] = u_out

            # Compute muscular force at each iteration
            q_est = X_est[:biorbd_model.nbQ(), :]
            dq_est = X_est[biorbd_model.nbQ():biorbd_model.nbQ() * 2, :]
            a_est = np.zeros(
                (nbMT, Ns)) if conf["use_activation"] else X_est[-nbMT:, :]
            for i in range(biorbd_model.nbMuscles()):
                for j in [iter]:
                    force_est[tries, i,
                              j] = var["get_force"](q_est[:, j], dq_est[:, j],
                                                    a_est[:, j],
                                                    U_est[nbGT:, j])[i, :]
            # Save status of optimisation
            if sol["status"] != 0 and conf["save_status"]:
                if conf["TRACK_EMG"]:
                    f = open(
                        f"{fold}status_track_rt_EMG{conf['TRACK_EMG']}.txt",
                        "a")
                else:
                    f = open(
                        f"{fold}status_track_rt_EMG{conf['TRACK_EMG']}.txt",
                        "a")
                f.write(f"{Ns_mhe}; {co}; {marker_lvl}; {EMG_lvl}; {tries}; "
                        f"{iter}\n")
                f.close()

        toc = time() - tic  # Save total time to solve
        # Store data
        X_est_tries[tries, :, :], U_est_tries[tries, :, :] = X_est, U_est
        markers_target_tries[tries, :, :, :] = markers_target
        muscles_target_tries[tries, :, :] = muscles_target

        # Compute reference muscular force
        get_force = force_func(biorbd_model, use_activation=False)
        for i in range(biorbd_model.nbMuscles()):
            for k in range(Ns):
                force_ref[i, k] = get_force(q_ref[:, k], dq_ref[:, k],
                                            a_ref[:, k], u_ref[nbGT:, k])[i, :]

        # Print some informations about optimisations
        print(f"nb loops: {iter}")
        print(f"Total time to solve with ACADOS : {toc} s")
        print(f"Time per MHE iter. : {toc/iter} s")
        tau = np.zeros((nbGT, Ns + 1))
        # Compute and print RMSE
        err_offset = Ns_mhe
        err = compute_err_mhe(
            var["init_offset"],
            var["final_offset"],
            err_offset,
            X_est,
            U_est,
            Ns,
            biorbd_model,
            q_ref,
            dq_ref,
            tau,
            a_ref,
            u_ref,
            nbGT,
            ratio=rt_ratio,
            use_activation=conf["use_activation"],
        )
        err_tries[int(tries), :] = [
            Ns_mhe,
            rt_ratio,
            toc,
            toc / iter,
            err["q"],
            err["q_dot"],
            err["tau"],
            err["muscles"],
            err["markers"],
            err["force"],
        ]
        print(err)
        if conf["plot"]:
            plot_MHE_results(
                biorbd_model,
                X_est,
                q_ref,
                Ns,
                rt_ratio,
                nbQ,
                dq_ref,
                U_est,
                u_ref,
                nbGT,
                muscles_target,
                force_est,
                force_ref,
                tries,
                markers_target,
                conf["use_torque"],
            )

    return err_tries, force_est, force_ref, X_est_tries, U_est_tries, muscles_target_tries, markers_target_tries, toc
示例#19
0
from bioptim import InitialGuess, Solution, Shooting, InterpolationType
import numpy as np
import pendulum


if __name__ == "__main__":
    # --- Load pendulum --- #
    ocp = pendulum.prepare_ocp(
        biorbd_model_path="pendulum.bioMod",
        final_time=2,
        n_shooting=10,
    )

    # Simulation the Initial Guess
    # Interpolation: Constant
    X = InitialGuess([0, 0, 0, 0])
    U = InitialGuess([-1, 1])

    sol_from_initial_guess = Solution(ocp, [X, U])
    s = sol_from_initial_guess.integrate(shooting_type=Shooting.SINGLE_CONTINUOUS)
    print(f"Final position of q from single shooting of initial guess = {s.states['q'][:, -1]}")
    # Uncomment the next line to animate the integration
    # s.animate()

    # Interpolation: Each frame (for instance, values from a previous optimization or from measured data)
    U = np.random.rand(2, 11)
    U = InitialGuess(U, interpolation=InterpolationType.EACH_FRAME)

    sol_from_initial_guess = Solution(ocp, [X, U])
    s = sol_from_initial_guess.integrate(shooting_type=Shooting.SINGLE_CONTINUOUS)
    print(f"Final position of q from single shooting of initial guess = {s.states['q'][:, -1]}")
示例#20
0
def prepare_ocp(
    biorbd_model_path, final_time, number_shooting_points, min_g, max_g, target_g, ode_solver=OdeSolver.RK, use_SX=False
):
    # --- 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 = Objective(ObjectiveFcn.Lagrange.MINIMIZE_TORQUE, 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
    x_init = InitialGuess([0] * (n_q + n_qdot))

    # Define control path constraint
    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
    # Give the parameter some min and max bounds
    parameters = ParameterList()
    bound_gravity = Bounds(min_g, max_g, interpolation=InterpolationType.CONSTANT)
    # and an initial condition
    initial_gravity = InitialGuess((min_g + max_g) / 2)
    parameter_objective_functions = Objective(
        my_target_function, weight=10, quadratic=True, custom_type=ObjectiveFcn.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,  # ObjectiveFcn 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,
        ode_solver=ode_solver,
        use_SX=use_SX,
    )
示例#21
0
def generate_table(out):
    root_path = "/".join(__file__.split("/")[:-1])
    model_path = root_path + "/models/arm_wt_rot_scap.bioMod"
    biorbd_model = biorbd.Model(model_path)

    # --- Prepare and solve MHE --- #
    t = 8
    ns = 800
    ns_mhe = 7
    rt_ratio = 3
    t_mhe = t / (ns / rt_ratio) * ns_mhe

    # --- Prepare reference data --- #
    with open(
            f"{root_path}/data/sim_ac_8000ms_800sn_REACH2_co_level_0_step5_ERK.bob",
            "rb") as file:
        data = pickle.load(file)
    states = data["data"][0]
    controls = data["data"][1]
    q_ref, dq_ref, u_ref = states["q"], states["qdot"], controls["muscles"]

    ocp = prepare_ocp(biorbd_model=biorbd_model,
                      final_time=t_mhe,
                      n_shooting=ns_mhe)
    q_noise = 5
    x_ref = np.concatenate((generate_noise(biorbd_model, q_ref,
                                           q_noise), dq_ref))
    x_est = np.zeros(
        (biorbd_model.nbQ() * 2, x_ref[:, ::rt_ratio].shape[1] - ns_mhe))
    u_est = np.zeros(
        (biorbd_model.nbMuscles(), u_ref[:, ::rt_ratio].shape[1] - ns_mhe))

    # Update bounds
    x_bounds = BoundsList()
    x_bounds.add(bounds=QAndQDotBounds(biorbd_model))
    x_bounds[0].min[:biorbd_model.nbQ(),
                    0] = x_ref[:biorbd_model.nbQ(), 0] - 0.1
    x_bounds[0].max[:biorbd_model.nbQ(),
                    0] = x_ref[:biorbd_model.nbQ(), 0] + 0.1
    ocp.update_bounds(x_bounds)

    # Update initial guess
    x_init = InitialGuess(x_ref[:, :ns_mhe + 1],
                          interpolation=InterpolationType.EACH_FRAME)
    u_init = InitialGuess([0.2] * biorbd_model.nbMuscles(),
                          interpolation=InterpolationType.CONSTANT)
    ocp.update_initial_guess(x_init, u_init)

    # Update objectives functions
    objectives = define_objective(q_ref, 0, rt_ratio, ns_mhe, biorbd_model)
    ocp.update_objectives(objectives)

    # Initialize the solver options
    sol = ocp.solve(
        solver=Solver.ACADOS,
        show_online_optim=False,
        solver_options={
            "nlp_solver_tol_comp": 1e-10,
            "nlp_solver_tol_eq": 1e-10,
            "nlp_solver_tol_stat": 1e-8,
            "integrator_type": "IRK",
            "nlp_solver_type": "SQP",
            "sim_method_num_steps": 1,
            "print_level": 0,
            "nlp_solver_max_iter": 30,
        },
    )

    # Set solutions and set initial guess for next optimisation
    x0, u0, x_est[:, 0], u_est[:, 0] = warm_start_mhe(sol)
    tic = time()  # Save initial time
    for i in range(1, x_est.shape[1]):
        # set initial state
        ocp.nlp[0].x_bounds.min[:, 0] = x0[:, 0]
        ocp.nlp[0].x_bounds.max[:, 0] = x0[:, 0]

        # Update initial guess
        x_init = InitialGuess(x0, interpolation=InterpolationType.EACH_FRAME)
        u_init = InitialGuess(u0, interpolation=InterpolationType.EACH_FRAME)
        ocp.update_initial_guess(x_init, u_init)

        # Update objectives functions
        objectives = define_objective(q_ref, i, rt_ratio, ns_mhe, biorbd_model)
        ocp.update_objectives(objectives)

        # Solve problem
        sol = ocp.solve(
            solver=Solver.ACADOS,
            show_online_optim=False,
            solver_options={
                "nlp_solver_tol_comp": 1e-6,
                "nlp_solver_tol_eq": 1e-6,
                "nlp_solver_tol_stat": 1e-5
            },
        )
        # Set solutions and set initial guess for next optimisation
        x0, u0, x_out, u_out = warm_start_mhe(sol)
        x_est[:, i] = x_out
        if i < u_est.shape[1]:
            u_est[:, i] = u_out

    toc = time() - tic
    n = x_est.shape[1] - 1
    tf = (ns - ns % rt_ratio) / (ns / t)
    final_time = tf - (ns_mhe * (tf / (n + ns_mhe)))
    short_ocp = prepare_short_ocp(biorbd_model,
                                  final_time=final_time,
                                  n_shooting=n)
    x_init_guess = InitialGuess(x_est,
                                interpolation=InterpolationType.EACH_FRAME)
    u_init_guess = InitialGuess(u_est,
                                interpolation=InterpolationType.EACH_FRAME)
    sol = Solution(short_ocp, [x_init_guess, u_init_guess])

    out.solver.append(out.Solver("Acados"))
    out.nx = x_est.shape[0]
    out.nu = u_est.shape[0]
    out.ns = n
    out.solver[0].n_iteration = "N.A."
    out.solver[0].cost = "N.A."
    out.solver[0].convergence_time = toc
    out.solver[0].compute_error_single_shooting(sol, 1)
示例#22
0
def test_double_update_bounds_and_init():
    PROJECT_FOLDER = Path(__file__).parent / ".."
    biorbd_model = biorbd.Model(
        str(PROJECT_FOLDER) + "/examples/align/cube_and_line.bioMod")
    nq = biorbd_model.nbQ()
    ns = 10

    dynamics = DynamicsList()
    dynamics.add(DynamicsFcn.TORQUE_DRIVEN)
    ocp = OptimalControlProgram(biorbd_model, dynamics, ns, 1.0)

    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.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, expected.reshape(128, 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, expected.reshape(128, 1))

    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.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, expected.reshape(128, 1))

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

    expected = np.append(
        np.tile(
            np.append(-2.0 * np.ones((nq * 2, 1)), -4.0 * np.ones((nq, 1))),
            ns), -2.0 * np.ones((nq * 2, 1)))
    np.testing.assert_almost_equal(ocp.V_bounds.min, expected.reshape(128, 1))
    expected = np.append(
        np.tile(np.append(2.0 * np.ones((nq * 2, 1)), 4.0 * np.ones((nq, 1))),
                ns), 2.0 * np.ones((nq * 2, 1)))
    np.testing.assert_almost_equal(ocp.V_bounds.max, expected.reshape(128, 1))

    x_init = InitialGuess(0.25 * np.ones((nq * 2, 1)))
    u_init = InitialGuess(-0.25 * np.ones((nq, 1)))
    ocp.update_initial_guess(x_init, u_init)
    expected = np.append(
        np.tile(
            np.append(0.25 * np.ones((nq * 2, 1)), -0.25 * np.ones((nq, 1))),
            ns), 0.25 * np.ones((nq * 2, 1)))
    np.testing.assert_almost_equal(ocp.V_init.init, expected.reshape(128, 1))

    with pytest.raises(
            RuntimeError,
            match=
            "x_init should be built from a InitialGuess or InitialGuessList"):
        ocp.update_initial_guess(x_bounds, u_bounds)
    with pytest.raises(
            RuntimeError,
            match="x_bounds should be built from a Bounds or BoundsList"):
        ocp.update_bounds(x_init, u_init)
示例#23
0
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,
        )
示例#24
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 = 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.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 = 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.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))
示例#25
0
def prepare_ocp(
        biorbd_model_path: str,
        n_shooting: int,
        final_time: float,
        loop_from_constraint: bool,
        ode_solver: OdeSolver = OdeSolver.RK4(),
) -> 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
    loop_from_constraint: bool
        If the looping cost should be a constraint [True] or an objective [False]
    ode_solver: OdeSolver
        The type of ode solver used

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

    biorbd_model = biorbd.Model(biorbd_model_path)

    # Add objective functions
    objective_functions = Objective(ObjectiveFcn.Lagrange.MINIMIZE_CONTROL,
                                    key="tau",
                                    weight=100)

    # Dynamics
    expand = False if isinstance(ode_solver, OdeSolver.IRK) else True
    dynamics = Dynamics(DynamicsFcn.TORQUE_DRIVEN, expand=expand)

    # Constraints
    constraints = ConstraintList()
    constraints.add(ConstraintFcn.SUPERIMPOSE_MARKERS,
                    node=Node.MID,
                    first_marker="m0",
                    second_marker="m2")
    constraints.add(ConstraintFcn.TRACK_STATE, key="q", node=Node.MID, index=2)
    constraints.add(ConstraintFcn.SUPERIMPOSE_MARKERS,
                    node=Node.END,
                    first_marker="m0",
                    second_marker="m1")

    # Path constraint
    x_bounds = QAndQDotBounds(biorbd_model)
    # First node is free but mid and last are constrained to be exactly at a certain point.
    # The cyclic penalty ensures that the first node and the last node are the same.
    x_bounds[2:6, -1] = [1.57, 0, 0, 0]

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

    # Define control path constraint
    tau_min, tau_max, tau_init = -100, 100, 0
    u_bounds = Bounds([tau_min] * biorbd_model.nbGeneralizedTorque(),
                      [tau_max] * biorbd_model.nbGeneralizedTorque())

    u_init = InitialGuess([tau_init] * biorbd_model.nbGeneralizedTorque())

    # ------------- #
    # A phase transition loop constraint is treated as
    # hard penalty (constraint) if weight is <= 0 [or if no weight is provided], or
    # as a soft penalty (objective) otherwise
    phase_transitions = PhaseTransitionList()
    if loop_from_constraint:
        phase_transitions.add(PhaseTransitionFcn.CYCLIC, weight=0)
    else:
        phase_transitions.add(PhaseTransitionFcn.CYCLIC, weight=10000)

    return OptimalControlProgram(
        biorbd_model,
        dynamics,
        n_shooting,
        final_time,
        x_init,
        u_init,
        x_bounds,
        u_bounds,
        objective_functions,
        constraints,
        ode_solver=ode_solver,
        phase_transitions=phase_transitions,
    )
示例#26
0
def generate_exc_low_bounds(rate, model_path, X_est, low_exc):
    # Variable of the problem
    biorbd_model = biorbd.Model(model_path)
    q_ref = X_est[: biorbd_model.nbQ(), :]
    dq_ref = X_est[biorbd_model.nbQ() : biorbd_model.nbQ() * 2, :]
    Ns = q_ref.shape[1] - 1
    T = Ns / rate
    # Set lower bounds for excitations on muscles in co-contraction (here triceps). Depends on co-contraction level
    excitations_max = [1] * biorbd_model.nbMuscleTotal()
    excitations_init = []
    excitations_min = []
    for i in range(len(low_exc)):
        excitations_init.append([[0.05] * 6 + [low_exc[i]] * 3 + [0.05] * 10])
        excitations_min.append([[0] * 6 + [low_exc[i]] * 3 + [0] * 10])
    x0 = np.hstack([q_ref[:, 0], dq_ref[:, 0]])
    # Build the graph
    ocp = prepare_ocp(biorbd_model=biorbd_model, final_time=T, x0=x0, number_shooting_points=Ns, use_sx=True)
    X_est_co = np.ndarray((len(excitations_init), biorbd_model.nbQ() * 2 + biorbd_model.nbMuscles(), X_est.shape[1]))
    U_est_co = np.ndarray((len(excitations_init), biorbd_model.nbMuscles(), Ns + 1))
    # Solve for all co-contraction levels
    for co in range(len(excitations_init)):
        # Update excitations and to correspond to the co-contraction level
        u_i = excitations_init[co]
        u_mi = excitations_min[co]
        u_ma = excitations_max

        # Update initial guess
        u_init = InitialGuess(np.tile(u_i, (ocp.nlp[0].ns, 1)).T, interpolation=InterpolationType.EACH_FRAME)
        x_init = InitialGuess(
            np.tile(X_est[:, 0], (ocp.nlp[0].ns + 1, 1)).T, interpolation=InterpolationType.EACH_FRAME
        )
        ocp.update_initial_guess(x_init, u_init=u_init)

        # Update bounds
        u_bounds = BoundsList()
        u_bounds.add(u_mi[0], u_ma, interpolation=InterpolationType.CONSTANT)
        ocp.update_bounds(u_bounds=u_bounds)

        # Update objectives functions
        objectives = ObjectiveList()
        objectives.add(ObjectiveFcn.Lagrange.MINIMIZE_MUSCLES_CONTROL, weight=1000)
        objectives.add(
            ObjectiveFcn.Lagrange.TRACK_STATE,
            weight=100000,
            target=X_est[: biorbd_model.nbQ(), :],
            index=range(biorbd_model.nbQ()),
        )
        objectives.add(
            ObjectiveFcn.Lagrange.MINIMIZE_STATE,
            weight=100,
            index=range(biorbd_model.nbQ() * 2, biorbd_model.nbQ() * 2 + biorbd_model.nbMuscles()),
        )
        objectives.add(
            ObjectiveFcn.Lagrange.MINIMIZE_STATE, weight=1000, index=range(biorbd_model.nbQ(), biorbd_model.nbQ() * 2)
        )
        ocp.update_objectives(objectives)

        # Solve the OCP
        tic = time()
        sol = ocp.solve(
            solver=Solver.ACADOS,
            show_online_optim=False,
            solver_options={
                # "nlp_solver_max_iter": 50,
                "nlp_solver_tol_comp": 1e-5,
                "nlp_solver_tol_eq": 1e-5,
                "nlp_solver_tol_stat": 1e-5,
            },
        )
        print(f"Time to solve with ACADOS : {time() - tic} s")
        toc = time() - tic
        print(f"Total time to solve with ACADOS : {toc} s")

        # Get optimal solution
        data_est = Data.get_data(ocp, sol)

        X_est_co[co, :, :] = np.vstack([data_est[0]["q"], data_est[0]["qdot"], data_est[0]["muscles"]])
        U_est_co[co, :, :] = data_est[1]["muscles"]
    return X_est_co, U_est_co
示例#27
0
def prepare_ocp(biorbd_model_path,
                final_time,
                n_shooting,
                x_warm=None,
                use_sx=False,
                n_threads=1):
    # --- Options --- #
    # Model path
    biorbd_model = biorbd.Model(biorbd_model_path)
    tau_min, tau_max, tau_init = -50, 50, 0
    muscle_min, muscle_max, muscle_init = 0, 1, 0.5

    # Add objective functions
    objective_functions = ObjectiveList()
    objective_functions.add(ObjectiveFcn.Lagrange.MINIMIZE_STATE,
                            key="q",
                            weight=10,
                            multi_thread=False)
    objective_functions.add(ObjectiveFcn.Lagrange.MINIMIZE_STATE,
                            key="qdot",
                            weight=10,
                            multi_thread=False)
    objective_functions.add(ObjectiveFcn.Lagrange.MINIMIZE_CONTROL,
                            key="tau",
                            weight=10,
                            multi_thread=False)
    objective_functions.add(ObjectiveFcn.Lagrange.MINIMIZE_CONTROL,
                            key="muscles",
                            weight=10,
                            multi_thread=False)
    objective_functions.add(ObjectiveFcn.Mayer.SUPERIMPOSE_MARKERS,
                            weight=100000,
                            first_marker="target",
                            second_marker="COM_hand")

    # Dynamics
    dynamics = DynamicsList()
    dynamics.add(DynamicsFcn.MUSCLE_DRIVEN, with_torque=True)

    # Path constraint
    x_bounds = BoundsList()
    x_bounds.add(bounds=QAndQDotBounds(biorbd_model))
    x_bounds[0][:, 0] = (1.0, 1.0, 0, 0)

    # Initial guess
    if x_warm is None:
        x_init = InitialGuess([1.57] * biorbd_model.nbQ() +
                              [0] * biorbd_model.nbQdot())
    else:
        x_init = InitialGuess(x_warm,
                              interpolation=InterpolationType.EACH_FRAME)

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

    u_init = InitialGuessList()
    u_init.add([tau_init] * biorbd_model.nbGeneralizedTorque() +
               [muscle_init] * biorbd_model.nbMuscleTotal())
    # ------------- #

    return OptimalControlProgram(
        biorbd_model,
        dynamics,
        n_shooting,
        final_time,
        x_init,
        u_init,
        x_bounds,
        u_bounds,
        objective_functions,
        use_sx=use_sx,
        n_threads=n_threads,
    )
示例#28
0
def generate_final_data(rate, X_ref, U_ref, save_data, plot):
    # Variable of the problem
    biorbd_model = biorbd.Model("arm_wt_rot_scap.bioMod")
    Ns = X_ref.shape[2] - 1
    T = int(Ns / rate)
    x0 = X_ref[0, : -biorbd_model.nbMuscles(), 0]

    # Build the graph
    ocp = prepare_ocp(biorbd_model=biorbd_model, final_time=T, number_shooting_points=Ns, x0=x0, use_SX=True)
    X_ref_fin = X_ref
    U_ref_fin = U_ref
    q_init = X_ref[0, : biorbd_model.nbQ(), :]
    # Run problem for all co-contraction level
    for co in range(X_ref.shape[0]):
        # Get reference data for co-contraction level ranging from 1 to 3
        q_ref = X_ref[co, : biorbd_model.nbQ(), :]
        dq_ref = X_ref[co, biorbd_model.nbQ() : biorbd_model.nbQ() * 2, :]
        u_ref = U_ref[co, :, :]
        x_ref_0 = np.hstack([q_ref[:, 0], dq_ref[:, 0], [0.3] * biorbd_model.nbMuscles()])

        # Update initial guess
        x_init = InitialGuess(np.tile(x_ref_0, (Ns + 1, 1)).T, interpolation=InterpolationType.EACH_FRAME)
        u_init = InitialGuess(u_ref[:, :-1], interpolation=InterpolationType.EACH_FRAME)
        ocp.update_initial_guess(x_init, u_init)

        # Update bounds on state
        x_bounds = BoundsList()
        x_bounds.add(bounds=QAndQDotBounds(biorbd_model))
        x_bounds[0].concatenate(Bounds([0] * biorbd_model.nbMuscles(), [1] * biorbd_model.nbMuscles()))
        x_bounds[0].min[: biorbd_model.nbQ() * 2, 0] = x_ref_0[: biorbd_model.nbQ() * 2]
        x_bounds[0].max[: biorbd_model.nbQ() * 2, 0] = x_ref_0[: biorbd_model.nbQ() * 2]
        x_bounds[0].min[biorbd_model.nbQ() * 2 : biorbd_model.nbQ() * 2 + biorbd_model.nbMuscles(), 0] = [
            0.1
        ] * biorbd_model.nbMuscles()
        x_bounds[0].max[biorbd_model.nbQ() * 2 : biorbd_model.nbQ() * 2 + biorbd_model.nbMuscles(), 0] = [
            1
        ] * biorbd_model.nbMuscles()
        ocp.update_bounds(x_bounds=x_bounds)

        # Update Objectives
        objective_functions = ObjectiveList()
        objective_functions.add(
            ObjectiveFcn.Lagrange.MINIMIZE_STATE, weight=10, index=np.array(range(biorbd_model.nbQ()))
        )
        objective_functions.add(
            ObjectiveFcn.Lagrange.MINIMIZE_STATE,
            weight=100,
            index=np.array(range(biorbd_model.nbQ(), biorbd_model.nbQ() * 2)),
        )
        objective_functions.add(
            ObjectiveFcn.Lagrange.MINIMIZE_STATE,
            weight=100,
            index=np.array(range(biorbd_model.nbQ() * 2, biorbd_model.nbQ() * 2 + biorbd_model.nbMuscles())),
        )
        objective_functions.add(ObjectiveFcn.Lagrange.MINIMIZE_MUSCLES_CONTROL, weight=100)
        objective_functions.add(
            ObjectiveFcn.Lagrange.TRACK_MUSCLES_CONTROL,
            weight=10000,
            target=u_ref[[9, 10, 17, 18], :-1],
            index=np.array([9, 10, 17, 18]),
        )
        objective_functions.add(
            ObjectiveFcn.Lagrange.TRACK_STATE, weight=100000, target=q_init, index=np.array(range(biorbd_model.nbQ()))
        )

        # Solve OCP
        ocp.update_objectives(objective_functions)
        sol = ocp.solve(
            solver=Solver.ACADOS,
            show_online_optim=False,
            solver_options={
                # "nlp_solver_max_iter": 40,
                "nlp_solver_tol_comp": 1e-4,
                "nlp_solver_tol_eq": 1e-4,
                "nlp_solver_tol_stat": 1e-4,
            },
        )

        # Store optimal solutions
        states, controls = Data.get_data(ocp, sol)
        X_ref_fin[co, :, :] = np.concatenate((states["q"], states["qdot"], states["muscles"]))
        U_ref_fin[co, :, :] = controls["muscles"]
        # Save results in .bob file if flag is True
        if save_data:
            ocp.save_get_data(sol, f"solutions/sim_ac_{int(T * 1000)}ms_{Ns}sn_REACH2_co_level_{co}.bob")
    if plot:
        t = np.linspace(0, T, Ns + 1)
        plt.figure("Muscles controls")
        for i in range(biorbd_model.nbMuscles()):
            plt.subplot(4, 5, i + 1)
            for k in range(X_ref_fin.shape[0]):
                plt.step(t, U_ref[k, i, :])

        plt.figure("Q")
        for i in range(biorbd_model.nbQ()):
            plt.subplot(2, 3, i + 1)
            for k in range(X_ref_fin.shape[0]):
                plt.plot(X_ref[k, i, :])
            plt.figure("Q")

        plt.figure("dQ")
        for i in range(biorbd_model.nbQ()):
            plt.subplot(2, 3, i + 1)
            for k in range(X_ref_fin.shape[0]):
                plt.plot(X_ref[k, i + biorbd_model.nbQ(), :])
        plt.show()

    return X_ref_fin, U_ref_fin
示例#29
0
def prepare_ocp(
        biorbd_model_path: str,
        n_shooting: int,
        final_time: float,
        initial_guess: InterpolationType = InterpolationType.CONSTANT,
        ode_solver=OdeSolver.RK4(),
) -> OptimalControlProgram:
    """
    Prepare the program

    Parameters
    ----------
    biorbd_model_path: str
        The path of the biorbd model
    n_shooting: int
        The number of shooting points
    final_time: float
        The time at the final node
    initial_guess: InterpolationType
        The type of interpolation to use for the initial guesses
    ode_solver: OdeSolver
        The type of ode solver used

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

    # --- Options --- #
    # Model path
    biorbd_model = biorbd.Model(biorbd_model_path)
    nq = biorbd_model.nbQ()
    nqdot = biorbd_model.nbQdot()
    ntau = biorbd_model.nbGeneralizedTorque()
    tau_min, tau_max, tau_init = -100, 100, 0

    # Add objective functions
    objective_functions = Objective(ObjectiveFcn.Lagrange.MINIMIZE_CONTROL,
                                    key="tau",
                                    weight=100)

    # Dynamics
    expand = False if isinstance(ode_solver, OdeSolver.IRK) else True
    dynamics = Dynamics(DynamicsFcn.TORQUE_DRIVEN, expand=expand)

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

    # Path constraint and control path constraints
    x_bounds = QAndQDotBounds(biorbd_model)
    x_bounds[1:6, [0, -1]] = 0
    x_bounds[2, -1] = 1.57
    u_bounds = Bounds([tau_min] * ntau, [tau_max] * ntau)

    # Initial guesses
    t = None
    extra_params_x = {}
    extra_params_u = {}
    if initial_guess == InterpolationType.CONSTANT:
        x = [0] * (nq + nqdot)
        u = [tau_init] * ntau
    elif initial_guess == InterpolationType.CONSTANT_WITH_FIRST_AND_LAST_DIFFERENT:
        x = np.array([[1.0, 0.0, 0.0, 0, 0, 0], [1.5, 0.0, 0.785, 0, 0, 0],
                      [2.0, 0.0, 1.57, 0, 0, 0]]).T
        u = np.array([[1.45, 9.81, 2.28], [0, 9.81, 0], [-1.45, 9.81,
                                                         -2.28]]).T
    elif initial_guess == InterpolationType.LINEAR:
        x = np.array([[1.0, 0.0, 0.0, 0, 0, 0], [2.0, 0.0, 1.57, 0, 0, 0]]).T
        u = np.array([[1.45, 9.81, 2.28], [-1.45, 9.81, -2.28]]).T
    elif initial_guess == InterpolationType.EACH_FRAME:
        x = np.random.random((nq + nqdot, n_shooting + 1))
        u = np.random.random((ntau, n_shooting))
    elif initial_guess == InterpolationType.SPLINE:
        # Bound spline assume the first and last point are 0 and final respectively
        t = np.hstack((0, np.sort(np.random.random(
            (3, )) * final_time), final_time))
        x = np.random.random((nq + nqdot, 5))
        u = np.random.random((ntau, 5))
    elif initial_guess == InterpolationType.CUSTOM:
        # The custom function refers to the one at the beginning of the file. It emulates a Linear interpolation
        x = custom_init_func
        u = custom_init_func
        extra_params_x = {
            "my_values": np.random.random((nq + nqdot, 2)),
            "n_shooting": n_shooting
        }
        extra_params_u = {
            "my_values": np.random.random((ntau, 2)),
            "n_shooting": n_shooting
        }
    else:
        raise RuntimeError("Initial guess not implemented yet")
    x_init = InitialGuess(x,
                          t=t,
                          interpolation=initial_guess,
                          **extra_params_x)

    u_init = InitialGuess(u,
                          t=t,
                          interpolation=initial_guess,
                          **extra_params_u)
    # ------------- #

    return OptimalControlProgram(
        biorbd_model,
        dynamics,
        n_shooting,
        final_time,
        x_init,
        u_init,
        x_bounds,
        u_bounds,
        objective_functions,
        constraints,
        ode_solver=ode_solver,
    )
def prepare_ocp(
    biorbd_model_path: str,
    final_time: float,
    n_shooting: int,
    ode_solver: OdeSolver = OdeSolver.RK1(n_integration_steps=1),
    use_sx: bool = False,
    n_threads: int = 1,
    implicit_dynamics: bool = False,
) -> OptimalControlProgram:
    """
    The initialization of an ocp

    Parameters
    ----------
    biorbd_model_path: str
        The path to the biorbd model
    final_time: float
        The time in second required to perform the task
    n_shooting: int
        The number of shooting points to define int the direct multiple shooting program
    ode_solver: OdeSolver = OdeSolver.RK4()
        Which type of OdeSolver to use
    use_sx: bool
        If the SX variable should be used instead of MX (can be extensive on RAM)
    n_threads: int
        The number of threads to use in the paralleling (1 = no parallel computing)
    implicit_dynamics: bool
        implicit
    Returns
    -------
    The OptimalControlProgram ready to be solved
    """

    biorbd_model = biorbd.Model(biorbd_model_path)

    objective_functions = ObjectiveList()
    objective_functions.add(ObjectiveFcn.Lagrange.MINIMIZE_CONTROL, key="tau")

    # Dynamics
    dynamics = Dynamics(DynamicsFcn.TORQUE_DRIVEN,
                        implicit_dynamics=implicit_dynamics)

    # Path constraint
    tau_min, tau_max, tau_init = -100, 100, 0

    # Be careful to let the accelerations not to much bounded to find the same solution in implicit dynamics
    if implicit_dynamics:
        qddot_min, qddot_max, qddot_init = -1000, 1000, 0

    x_bounds = BoundsList()
    x_bounds.add(bounds=QAndQDotBounds(biorbd_model))
    x_bounds[0][:, [0, -1]] = 0
    x_bounds[0][1, -1] = 3.14

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

    # Define control path constraint
    # There are extra controls in implicit dynamics which are joint acceleration qddot.
    if implicit_dynamics:
        u_bounds = Bounds([tau_min] * n_tau + [qddot_min] * n_qddot,
                          [tau_max] * n_tau + [qddot_max] * n_qddot)
    else:
        u_bounds = Bounds([tau_min] * n_tau, [tau_max] * n_tau)

    u_bounds[1, :] = 0  # Prevent the model from actively rotate

    if implicit_dynamics:
        u_init = InitialGuess([0] * (n_tau + n_qddot))
    else:
        u_init = InitialGuess([0] * n_tau)

    return OptimalControlProgram(
        biorbd_model,
        dynamics,
        n_shooting,
        final_time,
        x_init=x_init,
        u_init=u_init,
        x_bounds=x_bounds,
        u_bounds=u_bounds,
        objective_functions=objective_functions,
        ode_solver=ode_solver,
        use_sx=use_sx,
        n_threads=n_threads,
    )