Пример #1
0
def test_penalty_custom(penalty_origin, value):
    def custom(ocp, nlp, t, x, u, p, mult):
        my_values = DM.zeros((12, 1)) + x[0] * mult
        return my_values

    ocp = prepare_test_ocp()
    x = [DM.ones((12, 1)) * value]
    penalty_type = penalty_origin.CUSTOM

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        penalty = ObjectiveOption(penalty_type, index=0)
    else:
        penalty = ConstraintOption(penalty_type, index=0)

    penalty.custom_function = custom
    mult = 2
    penalty_type.value[0](penalty, ocp, ocp.nlp[0], [], x, [], [], mult=mult)

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        res = ocp.nlp[0].J[0][0]["val"]
    else:
        res = ocp.nlp[0].g[0][0]

    np.testing.assert_almost_equal(res, np.array([[value * mult]] * 12))

    if isinstance(penalty_type, Constraint):
        np.testing.assert_almost_equal(ocp.nlp[0].g_bounds[0][0].min,
                                       np.array([[0]] * 12))
        np.testing.assert_almost_equal(ocp.nlp[0].g_bounds[0][0].max,
                                       np.array([[0]] * 12))
Пример #2
0
def prepare_ocp(biorbd_model_path, final_time, number_shooting_points, min_g, max_g, target_g):
    # --- Options --- #
    biorbd_model = biorbd.Model(biorbd_model_path)
    tau_min, tau_max, tau_init = -30, 30, 0
    n_q = biorbd_model.nbQ()
    n_qdot = biorbd_model.nbQdot()
    n_tau = biorbd_model.nbGeneralizedTorque()

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

    # Dynamics
    dynamics = DynamicsTypeOption(DynamicsType.TORQUE_DRIVEN)

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

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

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

    u_init = InitialGuessOption([tau_init] * n_tau)

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

    return OptimalControlProgram(
        biorbd_model,
        dynamics,
        number_shooting_points,
        final_time,
        x_init,
        u_init,
        x_bounds,
        u_bounds,
        objective_functions,
        parameters=parameters,
    )
Пример #3
0
def test_penalty_custom_fail(penalty_origin, value):
    def custom_no_mult(ocp, nlp, t, x, u, p):
        my_values = DM.zeros((12, 1)) + x[0]
        return my_values

    def custom_with_mult(ocp, nlp, t, x, u, p, mult):
        my_values = DM.zeros((12, 1)) + x[0] * mult
        return my_values

    ocp = prepare_test_ocp()
    x = [DM.ones((12, 1)) * value]
    penalty_type = penalty_origin.CUSTOM

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        penalty = ObjectiveOption(penalty_type)
    else:
        penalty = ConstraintOption(penalty_type)

    with pytest.raises(TypeError):
        penalty.custom_function = custom_no_mult
        penalty_type.value[0](penalty, ocp, ocp.nlp[0], [], x, [], [], mult=2)

    with pytest.raises(TypeError):
        penalty.custom_function = custom_with_mult
        penalty_type.value[0](penalty, ocp, ocp.nlp[0], [], x, [], [])

    with pytest.raises(TypeError):
        keywords = [
            "phase",
            "list_index",
            "name",
            "type",
            "params",
            "node",
            "quadratic",
            "index",
            "target",
            "sliced_target",
            "min_bound",
            "max_bound",
            "custom_function",
            "weight",
        ]
        for keyword in keywords:
            exec(f"""def custom_with_keyword(ocp, nlp, t, x, u, p, {keyword}):
                            my_values = DM.zeros((12, 1)) + x[index]
                            return my_values""")
            exec("""penalty.custom_function = custom_with_keyword""")
            exec(
                f"""penalty_type.value[0](penalty, ocp, ocp.nlp[0], [], x, [], [], {keyword}=0)"""
            )
Пример #4
0
def test_penalty_minimize_markers_velocity(penalty_origin, value):
    ocp = prepare_test_ocp()
    x = [DM.ones((12, 1)) * value]
    penalty_type = penalty_origin.MINIMIZE_MARKERS_VELOCITY
    penalty = ObjectiveOption(penalty_type)
    penalty_type.value[0](penalty, ocp, ocp.nlp[0], [], x, [], [])

    if value == 0.1:
        np.testing.assert_almost_equal(
            ocp.nlp[0].J[0][6]["val"],
            np.array([
                [-0.00499167],
                [0],
                [-0.0497502],
            ]),
        )
    else:
        np.testing.assert_almost_equal(
            ocp.nlp[0].J[0][6]["val"],
            np.array([
                [2.7201056],
                [0],
                [-4.1953576],
            ]),
        )
Пример #5
0
def test_penalty_track_torque(penalty_origin, value):
    ocp = prepare_test_ocp()
    u = [DM.ones((12, 1)) * value]
    penalty_type = penalty_origin.TRACK_TORQUE

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        penalty = ObjectiveOption(penalty_type, target=np.ones((4, 1)) * value)
    else:
        penalty = ConstraintOption(penalty_type,
                                   target=np.ones((4, 1)) * value)

    penalty_type.value[0](penalty, ocp, ocp.nlp[0], [4], [], u, [])

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        res = ocp.nlp[0].J[0][0]["val"]
    else:
        res = ocp.nlp[0].g[0][0]

    np.testing.assert_almost_equal(
        res,
        np.array([[value, value, value, value]]).T,
    )

    if isinstance(penalty_type, Constraint):
        np.testing.assert_almost_equal(ocp.nlp[0].g_bounds[0][0].min,
                                       np.zeros((4, 1)))
        np.testing.assert_almost_equal(ocp.nlp[0].g_bounds[0][0].max,
                                       np.zeros((4, 1)))
Пример #6
0
def test_penalty_align_marker_with_segment_axis(penalty_origin, value):
    ocp = prepare_test_ocp()
    x = [DM.ones((12, 1)) * value]
    penalty_type = penalty_origin.ALIGN_MARKER_WITH_SEGMENT_AXIS

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        penalty = ObjectiveOption(penalty_type)
    else:
        penalty = ConstraintOption(penalty_type)

    penalty_type.value[0](penalty,
                          ocp,
                          ocp.nlp[0], [],
                          x, [], [],
                          marker_idx=0,
                          segment_idx=1,
                          axis=Axe.X)

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        res = ocp.nlp[0].J[0][0]["val"]
    else:
        res = ocp.nlp[0].g[0][0]

    np.testing.assert_almost_equal(
        res,
        np.array([[0]]),
    )

    if isinstance(penalty_type, Constraint):
        np.testing.assert_almost_equal(ocp.nlp[0].g_bounds[0][0].min,
                                       np.array([[0]]))
        np.testing.assert_almost_equal(ocp.nlp[0].g_bounds[0][0].max,
                                       np.array([[0]]))
Пример #7
0
def test_penalty_track_state(penalty_origin, value):
    ocp = prepare_test_ocp()
    x = [DM.ones((12, 1)) * value]
    penalty_type = penalty_origin.TRACK_STATE
    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        penalty = ObjectiveOption(penalty_type, target=np.ones((8, 1)) * value)
    else:
        penalty = ConstraintOption(penalty_type,
                                   target=np.ones((8, 1)) * value)
    penalty_type.value[0](penalty, ocp, ocp.nlp[0], [1], x, [], [])

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        res = ocp.nlp[0].J[0][0]["val"]
    else:
        res = ocp.nlp[0].g[0][0]

    expected = np.array([[value]] * 8)

    np.testing.assert_almost_equal(
        res,
        expected,
    )

    if isinstance(penalty_type, Constraint):
        np.testing.assert_almost_equal(ocp.nlp[0].g_bounds[0][0].min,
                                       np.array([[0]] * 8))
        np.testing.assert_almost_equal(
            ocp.nlp[0].g_bounds[0][0].max,
            np.array([[0]] * 8),
        )
Пример #8
0
def test_penalty_track_all_controls(penalty_origin, value):
    ocp = prepare_test_ocp(with_muscles=True)
    u = [DM.ones((12, 1)) * value]
    penalty_type = penalty_origin.TRACK_ALL_CONTROLS

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        penalty = ObjectiveOption(penalty_type, target=np.ones((8, 1)) * value)
    else:
        penalty = ConstraintOption(penalty_type,
                                   target=np.ones((8, 1)) * value)

    penalty_type.value[0](penalty, ocp, ocp.nlp[0], [6], [], u, [])

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        res = ocp.nlp[0].J[0][0]["val"]
    else:
        res = ocp.nlp[0].g[0][0]

    np.testing.assert_almost_equal(
        res,
        np.array([[value, value, value, value, value, value, value, value]]).T,
    )

    if isinstance(penalty_type, Constraint):
        np.testing.assert_almost_equal(
            ocp.nlp[0].g_bounds[0][0].min,
            np.array([[0.0, 0, 0, 0, 0, 0, 0, 0]]).T)
        np.testing.assert_almost_equal(
            ocp.nlp[0].g_bounds[0][0].max,
            np.array([[0.0, 0, 0, 0, 0, 0, 0, 0]]).T)
Пример #9
0
def test_penalty_proportional_state(penalty_origin, value):
    ocp = prepare_test_ocp()
    x = [DM.ones((12, 1)) * value]
    penalty_type = penalty_origin.PROPORTIONAL_STATE

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        penalty = ObjectiveOption(penalty_type)
    else:
        penalty = ConstraintOption(penalty_type)

    penalty_type.value[0](penalty,
                          ocp,
                          ocp.nlp[0], [],
                          x, [], [],
                          which_var="states",
                          first_dof=0,
                          second_dof=1,
                          coef=2)

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        res = ocp.nlp[0].J[0][0]["val"]
    else:
        res = ocp.nlp[0].g[0][0]

    np.testing.assert_almost_equal(
        res,
        np.array([[-value]]),
    )

    if isinstance(penalty_type, Constraint):
        np.testing.assert_almost_equal(ocp.nlp[0].g_bounds[0][0].min,
                                       np.array([[0]]))
        np.testing.assert_almost_equal(ocp.nlp[0].g_bounds[0][0].max,
                                       np.array([[0]]))
Пример #10
0
def test_penalty_minimize_contact_forces(penalty_origin, value):
    ocp = prepare_test_ocp(with_contact=True)
    x = [DM.ones((8, 1)) * value]
    u = [DM.ones((4, 1)) * value]
    penalty_type = penalty_origin.MINIMIZE_CONTACT_FORCES
    penalty = ObjectiveOption(penalty_type)
    penalty_type.value[0](penalty, ocp, ocp.nlp[0], [], x, u, [])

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        res = ocp.nlp[0].J[0][0]["val"]
    else:
        res = ocp.nlp[0].g[0][0]

    if value == 0.1:
        np.testing.assert_almost_equal(
            res,
            np.array([[-9.6680105, 127.2360329, 5.0905995]]).T,
        )
    else:
        np.testing.assert_almost_equal(
            res,
            np.array([[25.6627161, 462.7973306, -94.0182191]]).T,
        )

    if isinstance(penalty_type, Constraint):
        np.testing.assert_almost_equal(ocp.nlp[0].g_bounds[0][0].min,
                                       np.array([[0.0]]).T)
        np.testing.assert_almost_equal(ocp.nlp[0].g_bounds[0][0].max,
                                       np.array([[0.0]]).T)
Пример #11
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 = ObjectiveOption(Objective.Lagrange.MINIMIZE_TORQUE,
                                          weight=100)

    # Dynamics
    dynamics = DynamicsTypeOption(DynamicsType.TORQUE_DRIVEN)

    # Constraints
    constraints = ConstraintList()
    constraints.add(custom_func_align_markers,
                    node=Node.START,
                    first_marker_idx=0,
                    second_marker_idx=1)
    constraints.add(custom_func_align_markers,
                    node=Node.END,
                    first_marker_idx=0,
                    second_marker_idx=2)

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

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

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

    u_init = InitialGuessOption([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,
        constraints,
        ode_solver=ode_solver,
    )
Пример #12
0
def test_penalty_minimize_time(penalty_origin, value):
    ocp = prepare_test_ocp()
    penalty_type = penalty_origin.MINIMIZE_TIME
    penalty = ObjectiveOption(penalty_type)
    penalty_type.value[0](penalty, ocp, ocp.nlp[0], [], [], [], [])

    np.testing.assert_almost_equal(
        ocp.nlp[0].J[0][0]["val"],
        np.array(1),
    )
Пример #13
0
def test_penalty_minimize_markers_displacement(penalty_origin, value):
    ocp = prepare_test_ocp()
    x = [DM.ones((12, 1)) * value]
    penalty_type = penalty_origin.MINIMIZE_MARKERS_DISPLACEMENT
    penalty = ObjectiveOption(penalty_type)
    penalty_type.value[0](penalty, ocp, ocp.nlp[0], [], x, [], [])

    np.testing.assert_almost_equal(
        ocp.nlp[0].J[0],
        np.array([]),
    )
Пример #14
0
def test_penalty_minimize_state(penalty_origin, value):
    ocp = prepare_test_ocp()
    x = [DM.ones((12, 1)) * value]
    penalty_type = penalty_origin.MINIMIZE_STATE
    penalty = ObjectiveOption(penalty_type)
    penalty_type.value[0](penalty, ocp, ocp.nlp[0], [], x, [], [])

    np.testing.assert_almost_equal(
        ocp.nlp[0].J[0][0]["val"],
        np.array([[value]] * 8),
    )
Пример #15
0
def prepare_ocp(biorbd_model_path, final_time, number_shooting_points,
                time_min, time_max):
    # --- Options --- #
    biorbd_model = biorbd.Model(biorbd_model_path)
    tau_min, tau_max, tau_init = -100, 100, 0
    n_q = biorbd_model.nbQ()
    n_qdot = biorbd_model.nbQdot()
    n_tau = biorbd_model.nbGeneralizedTorque()

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

    # Dynamics
    dynamics = DynamicsTypeOption(DynamicsType.TORQUE_DRIVEN)

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

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

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

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

    u_init = InitialGuessOption([tau_init] * n_tau)

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

    return OptimalControlProgram(
        biorbd_model,
        dynamics,
        number_shooting_points,
        final_time,
        x_init,
        u_init,
        x_bounds,
        u_bounds,
        objective_functions,
        constraints,
    )
Пример #16
0
def test_penalty_minimize_predicted_com_height(value):
    ocp = prepare_test_ocp()
    x = [DM.ones((12, 1)) * value]
    penalty_type = Objective.Mayer.MINIMIZE_PREDICTED_COM_HEIGHT
    penalty = ObjectiveOption(penalty_type)
    penalty_type.value[0](penalty, ocp, ocp.nlp[0], [], x, [], [])

    res = np.array(0.0501274)
    if value == -10:
        res = np.array([[-3.72579]])

    np.testing.assert_almost_equal(
        ocp.nlp[0].J[0][0]["val"],
        res,
    )
Пример #17
0
def test_penalty_align_markers(penalty_origin, value):
    ocp = prepare_test_ocp()
    x = [DM.ones((12, 1)) * value]
    penalty_type = penalty_origin.ALIGN_MARKERS

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        penalty = ObjectiveOption(penalty_type)
    else:
        penalty = ConstraintOption(penalty_type)

    penalty_type.value[0](penalty,
                          ocp,
                          ocp.nlp[0], [],
                          x, [], [],
                          first_marker_idx=0,
                          second_marker_idx=1)

    expected = np.array([
        [-0.8951707],
        [0],
        [1.0948376],
    ])
    if value == -10:
        expected = np.array([
            [1.3830926],
            [0],
            [-0.2950504],
        ])

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        res = ocp.nlp[0].J[0][0]["val"]
    else:
        res = ocp.nlp[0].g[0][0]

    np.testing.assert_almost_equal(
        res,
        expected,
    )

    if isinstance(penalty_type, Constraint):
        np.testing.assert_almost_equal(
            ocp.nlp[0].g_bounds[0][0].min,
            np.array([[0]] * 3),
        )
        np.testing.assert_almost_equal(
            ocp.nlp[0].g_bounds[0][0].max,
            np.array([[0]] * 3),
        )
Пример #18
0
def test_penalty_track_markers_velocity(penalty_origin, value):
    ocp = prepare_test_ocp()
    x = [DM.ones((12, 1)) * value]
    penalty_type = penalty_origin.TRACK_MARKERS_VELOCITY

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        penalty = ObjectiveOption(penalty_type,
                                  target=np.ones((3, 7, 1)) * value)
    else:
        penalty = ConstraintOption(penalty_type,
                                   target=np.ones((3, 7, 1)) * value)

    penalty_type.value[0](penalty, ocp, ocp.nlp[0], [3], x, [], [])

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        res = ocp.nlp[0].J[0][6]["val"]
    else:
        res = ocp.nlp[0].g[0][6]

    if value == 0.1:
        np.testing.assert_almost_equal(
            res,
            np.array([
                [-0.00499167],
                [0],
                [-0.0497502],
            ]),
        )
    else:
        np.testing.assert_almost_equal(
            res,
            np.array([
                [2.7201056],
                [0],
                [-4.1953576],
            ]),
        )

    if isinstance(penalty_type, Constraint):
        np.testing.assert_almost_equal(
            ocp.nlp[0].g_bounds[0][0].min,
            np.array([[0]] * 3),
        )
        np.testing.assert_almost_equal(
            ocp.nlp[0].g_bounds[0][0].max,
            np.array([[0]] * 3),
        )
Пример #19
0
def test_penalty_track_markers(penalty_origin, value):
    ocp = prepare_test_ocp()
    x = [DM.ones((12, 1)) * value]
    penalty_type = penalty_origin.TRACK_MARKERS

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        penalty = ObjectiveOption(penalty_type,
                                  target=np.ones((3, 7, 1)) * value)
    else:
        penalty = ConstraintOption(penalty_type,
                                   target=np.ones((3, 7, 1)) * value)

    penalty_type.value[0](penalty, ocp, ocp.nlp[0], [2], x, [], [])

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        res = ocp.nlp[0].J[0][0]["val"]
    else:
        res = ocp.nlp[0].g[0][0]

    expected = np.array([
        [0.1, 0.99517075, 1.9901749, 1.0950042, 1, 2, 0.49750208],
        [0, 0, 0, 0, 0, 0, 0],
        [0.1, -0.9948376, -1.094671, 0.000166583, 0, 0, -0.0499167],
    ])
    if value == -10:
        expected = np.array([
            [-10, -11.3830926, -12.2221642, -10.8390715, 1.0, 2.0, -0.4195358],
            [0, 0, 0, 0, 0, 0, 0],
            [-10, -9.7049496, -10.2489707, -10.5440211, 0, 0, -0.2720106],
        ])

    np.testing.assert_almost_equal(
        res,
        expected,
    )

    if isinstance(penalty_type, Constraint):
        np.testing.assert_almost_equal(
            ocp.nlp[0].g_bounds[0][0].min,
            np.array([[0]] * 3),
        )
        np.testing.assert_almost_equal(
            ocp.nlp[0].g_bounds[0][0].max,
            np.array([[0]] * 3),
        )
Пример #20
0
def test_penalty_minimize_muscles_control(penalty_origin, value):
    ocp = prepare_test_ocp(with_muscles=True)
    u = [DM.ones((12, 1)) * value]
    penalty_type = penalty_origin.MINIMIZE_MUSCLES_CONTROL
    penalty = ObjectiveOption(penalty_type)
    penalty_type.value[0](penalty, ocp, ocp.nlp[0], [], [], u, [])

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        res = ocp.nlp[0].J[0][0]["val"]
    else:
        res = ocp.nlp[0].g[0][0]

    np.testing.assert_almost_equal(
        res,
        np.array([[value, value, value, value, value, value]]).T,
    )

    if isinstance(penalty_type, Constraint):
        np.testing.assert_almost_equal(ocp.nlp[0].g_bounds[0][0].min,
                                       np.array([[0.0, 0, 0, 0, 0, 0]]))
        np.testing.assert_almost_equal(ocp.nlp[0].g_bounds[0][0].max,
                                       np.array([[0.0, 0, 0, 0, 0, 0]]))
Пример #21
0
def test_penalty_minimize_torque_derivative(value):
    ocp = prepare_test_ocp()
    u = [DM.ones((12, 1)) * value, DM.ones((12, 1)) * value * 3]
    penalty_type = Objective.Lagrange.MINIMIZE_TORQUE_DERIVATIVE
    penalty = ObjectiveOption(penalty_type)
    penalty_type.value[0](penalty, ocp, ocp.nlp[0], [], [], u, [])

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        res = ocp.nlp[0].J[0][0]["val"]
    else:
        res = ocp.nlp[0].g[0][0]

    np.testing.assert_almost_equal(
        res,
        np.array([[value * 2, value * 2, value * 2, value * 2]]).T,
    )

    if isinstance(penalty_type, Constraint):
        np.testing.assert_almost_equal(ocp.nlp[0].g_bounds[0][0].min,
                                       np.array([[0.0, 0, 0, 0]]))
        np.testing.assert_almost_equal(ocp.nlp[0].g_bounds[0][0].max,
                                       np.array([[0.0, 0, 0, 0]]))
Пример #22
0
def test_penalty_track_contact_forces(penalty_origin, value):
    ocp = prepare_test_ocp(with_contact=True)
    x = [DM.ones((8, 1)) * value]
    u = [DM.ones((4, 1)) * value]
    penalty_type = penalty_origin.TRACK_CONTACT_FORCES

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        penalty = ObjectiveOption(penalty_type,
                                  target=np.ones((1, 1)) * value,
                                  index=0)
    else:
        penalty = ConstraintOption(penalty_type,
                                   target=np.ones((1, 1)) * value,
                                   index=0)

    penalty_type.value[0](penalty, ocp, ocp.nlp[0], [7], x, u, [])

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        res = ocp.nlp[0].J[0][0]["val"]
    else:
        res = ocp.nlp[0].g[0][0]

    if value == 0.1:
        np.testing.assert_almost_equal(
            res,
            np.array([[-9.6680105]]),
        )
    else:
        np.testing.assert_almost_equal(
            res,
            np.array([[25.6627161]]),
        )

    if isinstance(penalty_type, Constraint):
        np.testing.assert_almost_equal(ocp.nlp[0].g_bounds[0][0].min,
                                       np.array([[0.0]]).T)
        np.testing.assert_almost_equal(ocp.nlp[0].g_bounds[0][0].max,
                                       np.array([[0.0]]).T)
Пример #23
0
def test_penalty_minimize_markers(penalty_origin, value):
    ocp = prepare_test_ocp()
    x = [DM.ones((12, 1)) * value]
    penalty_type = penalty_origin.MINIMIZE_MARKERS
    penalty = ObjectiveOption(penalty_type)
    penalty_type.value[0](penalty, ocp, ocp.nlp[0], [], x, [], [])

    res = np.array([
        [0.1, 0.99517075, 1.9901749, 1.0950042, 1, 2, 0.49750208],
        [0, 0, 0, 0, 0, 0, 0],
        [0.1, -0.9948376, -1.094671, 0.000166583, 0, 0, -0.0499167],
    ])
    if value == -10:
        res = np.array([
            [-10, -11.3830926, -12.2221642, -10.8390715, 1.0, 2.0, -0.4195358],
            [0, 0, 0, 0, 0, 0, 0],
            [-10, -9.7049496, -10.2489707, -10.5440211, 0, 0, -0.2720106],
        ])

    np.testing.assert_almost_equal(
        ocp.nlp[0].J[0][0]["val"],
        res,
    )
Пример #24
0
def test_penalty_proportional_control(penalty_origin, value):
    ocp = prepare_test_ocp()
    u = [DM.ones((12, 1)) * value]
    penalty_type = penalty_origin.PROPORTIONAL_CONTROL

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        penalty = ObjectiveOption(penalty_type)
    else:
        penalty = ConstraintOption(penalty_type)

    first = 0
    second = 1
    coef = 2
    penalty_type.value[0](penalty,
                          ocp,
                          ocp.nlp[0], [], [],
                          u, [],
                          which_var="controls",
                          first_dof=first,
                          second_dof=second,
                          coef=coef)

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        res = ocp.nlp[0].J[0][0]["val"]
    else:
        res = ocp.nlp[0].g[0][0]

    np.testing.assert_almost_equal(
        res,
        np.array(u[0][first] - coef * u[0][second]),
    )

    if isinstance(penalty_type, Constraint):
        np.testing.assert_almost_equal(ocp.nlp[0].g_bounds[0][0].min,
                                       np.array([[0.0]]))
        np.testing.assert_almost_equal(ocp.nlp[0].g_bounds[0][0].max,
                                       np.array([[0.0]]))
Пример #25
0
def test_penalty_align_segment_with_custom_rt(penalty_origin, value):
    ocp = prepare_test_ocp()
    x = [DM.ones((12, 1)) * value]
    penalty_type = penalty_origin.ALIGN_SEGMENT_WITH_CUSTOM_RT

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        penalty = ObjectiveOption(penalty_type)
    else:
        penalty = ConstraintOption(penalty_type)

    penalty_type.value[0](penalty,
                          ocp,
                          ocp.nlp[0], [],
                          x, [], [],
                          segment_idx=1,
                          rt_idx=0)

    if isinstance(penalty_type, (Objective.Lagrange, Objective.Mayer)):
        res = ocp.nlp[0].J[0][0]["val"]
    else:
        res = ocp.nlp[0].g[0][0]

    expected = np.array([[0], [0.1], [0]])
    if value == -10:
        expected = np.array([[3.1415927], [0.575222], [3.1415927]])

    np.testing.assert_almost_equal(
        res,
        expected,
    )

    if isinstance(penalty_type, Constraint):
        np.testing.assert_almost_equal(ocp.nlp[0].g_bounds[0][0].min,
                                       np.array([[0], [0], [0]]))
        np.testing.assert_almost_equal(ocp.nlp[0].g_bounds[0][0].max,
                                       np.array([[0], [0], [0]]))
Пример #26
0
def prepare_ocp(
    biorbd_model_path,
    number_shooting_points,
    final_time,
    initial_guess=InterpolationType.CONSTANT,
):
    # --- 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 = ObjectiveOption(Objective.Lagrange.MINIMIZE_TORQUE,
                                          weight=100)

    # Dynamics
    dynamics = DynamicsTypeOption(DynamicsType.TORQUE_DRIVEN)

    # Constraints
    constraints = ConstraintList()
    constraints.add(Constraint.ALIGN_MARKERS,
                    node=Node.START,
                    first_marker_idx=0,
                    second_marker_idx=1)
    constraints.add(Constraint.ALIGN_MARKERS,
                    node=Node.END,
                    first_marker_idx=0,
                    second_marker_idx=2)

    # Path constraint and control path constraints
    x_bounds = BoundsOption(QAndQDotBounds(biorbd_model))
    x_bounds[1:6, [0, -1]] = 0
    x_bounds[2, -1] = 1.57
    u_bounds = BoundsOption([[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, number_shooting_points + 1))
        u = np.random.random((ntau, number_shooting_points))
    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)),
            "nb_shooting": number_shooting_points
        }
        extra_params_u = {
            "my_values": np.random.random((ntau, 2)),
            "nb_shooting": number_shooting_points
        }
    else:
        raise RuntimeError("Initial guess not implemented yet")
    x_init = InitialGuessOption(x,
                                t=t,
                                interpolation=initial_guess,
                                **extra_params_x)

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

    return OptimalControlProgram(
        biorbd_model,
        dynamics,
        number_shooting_points,
        final_time,
        x_init,
        u_init,
        x_bounds,
        u_bounds,
        objective_functions,
        constraints,
    )
Пример #27
0
def prepare_ocp(biorbd_model_path,
                number_shooting_points,
                final_time,
                loop_from_constraint,
                ode_solver=OdeSolver.RK):
    # --- Options --- #
    # Model path
    biorbd_model = biorbd.Model(biorbd_model_path)

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

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

    # Dynamics
    dynamics = DynamicsTypeOption(DynamicsType.TORQUE_DRIVEN)

    # Constraints
    constraints = ConstraintList()
    constraints.add(Constraint.ALIGN_MARKERS,
                    node=Node.MID,
                    first_marker_idx=0,
                    second_marker_idx=2)
    constraints.add(Constraint.TRACK_STATE, node=Node.MID, index=2)
    constraints.add(Constraint.ALIGN_MARKERS,
                    node=Node.END,
                    first_marker_idx=0,
                    second_marker_idx=1)

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

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

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

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

    # ------------- #
    # A state 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
    state_transitions = StateTransitionList()
    if loop_from_constraint:
        state_transitions.add(StateTransition.CYCLIC, weight=0)
    else:
        state_transitions.add(StateTransition.CYCLIC, weight=10000)

    return OptimalControlProgram(
        biorbd_model,
        dynamics,
        number_shooting_points,
        final_time,
        x_init,
        u_init,
        x_bounds,
        u_bounds,
        objective_functions,
        constraints,
        ode_solver=ode_solver,
        state_transitions=state_transitions,
    )
Пример #28
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(min_bound=g_min,
                            max_bound=g_max,
                            interpolation=InterpolationType.CONSTANT)
    parameter_objective_functions = ObjectiveOption(
        my_target_function,
        weight=10,
        quadratic=True,
        custom_type=Objective.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,
            InitialGuess(),
            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,
            Bounds(),
            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,
        )
Пример #29
0
def test_update_bounds_and_init_with_param():
    def my_parameter_function(biorbd_model, value, extra_value):
        biorbd_model.setGravity(biorbd.Vector3d(0, 0, value + extra_value))

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

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

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

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

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

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

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

    x_init = InitialGuessOption(0.5 * np.ones((nq * 2, 1)))
    u_init = InitialGuessOption(-0.5 * np.ones((nq, 1)))
    ocp.update_initial_guess(x_init, u_init)
    expected = np.append(
        np.tile(np.append(0.5 * np.ones((nq * 2, 1)), -0.5 * np.ones((nq, 1))),
                ns), 0.5 * np.ones((nq * 2, 1)))
    np.testing.assert_almost_equal(
        ocp.V_init.init,
        np.append([g_init], expected).reshape(129, 1))
Пример #30
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)
    PROJECT_FOLDER = Path(__file__).parent / ".."
    biorbd_model_path = str(
        PROJECT_FOLDER) + "/examples/optimal_time_ocp/cube.bioMod"
    ode_solver = OdeSolver.RK

    # --- Options --- #
    nb_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(Objective.Lagrange.MINIMIZE_TORQUE,
                            weight=100,
                            phase=0)
    objective_functions.add(Objective.Lagrange.MINIMIZE_TORQUE,
                            weight=100,
                            phase=1)
    objective_functions.add(Objective.Lagrange.MINIMIZE_TORQUE,
                            weight=100,
                            phase=2)

    # Dynamics
    dynamics = DynamicsTypeList()
    dynamics.add(DynamicsType.TORQUE_DRIVEN, phase=0)
    dynamics.add(DynamicsType.TORQUE_DRIVEN, phase=1)
    dynamics.add(DynamicsType.TORQUE_DRIVEN, phase=2)

    # Constraints
    constraints = ConstraintList()
    constraints.add(Constraint.ALIGN_MARKERS,
                    node=Node.START,
                    first_marker_idx=0,
                    second_marker_idx=1,
                    phase=0)
    constraints.add(Constraint.ALIGN_MARKERS,
                    node=Node.END,
                    first_marker_idx=0,
                    second_marker_idx=2,
                    phase=0)
    constraints.add(Constraint.ALIGN_MARKERS,
                    node=Node.END,
                    first_marker_idx=0,
                    second_marker_idx=1,
                    phase=1)
    constraints.add(Constraint.ALIGN_MARKERS,
                    node=Node.END,
                    first_marker_idx=0,
                    second_marker_idx=2,
                    phase=2)

    constraints.add(
        Constraint.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(QAndQDotBounds(biorbd_model[0]))  # Phase 0
    x_bounds.add(QAndQDotBounds(biorbd_model[0]))  # Phase 1
    x_bounds.add(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_bound=min_g,
                               max_bound=max_g,
                               interpolation=InterpolationType.CONSTANT)
        initial_gravity = InitialGuess((min_g + max_g) / 2)
        parameter_objective_functions = ObjectiveOption(
            my_target_function,
            weight=10,
            quadratic=True,
            custom_type=Objective.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[:nb_phases],
        dynamics,
        ns,
        final_time[:nb_phases],
        x_init,
        u_init,
        x_bounds,
        u_bounds,
        objective_functions,
        constraints,
        ode_solver=ode_solver,
        parameters=parameters,
    )