Skip to content

Commit 51e03f0

Browse files
committed
Clamp built-in predicted CoM height to positive vertical velocity
1 parent fdafe4d commit 51e03f0

3 files changed

Lines changed: 12 additions & 4 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1335,7 +1335,7 @@ Here a list of objective function with its type (Lagrange and/or Mayer) in alpha
13351335
- **MINIMIZE_MARKERS_VELOCITY or MINIMIZE_MARKERS_ACCELERATION** (Lagrange and Mayer) — Minimizes the marker velocities or accelerations toward zero (or a target).
13361336
- **MINIMIZE_MARKERS** (Lagrange and Mayer) — Minimizes the position of the markers toward zero (or a target). The extra parameter `axis_to_track: Axis = (Axis.X, Axis.Y, Axis.Z)` can be sent to specify the axes along which the markers should be minimized.
13371337
- **MINIMIZE_MUSCLES_CONTROL** (Lagrange) — Minimizes the muscles' controls (part of the control variables) toward zero (or a target).
1338-
- **MINIMIZE_PREDICTED_COM_HEIGHT** (Mayer) — Minimizes the maximal height of the center of mass, predicted from the parabolic equation, assuming vertical axis is Z (2): CoM_dot[2]**2 / (2 * -g) + CoM[2]. To maximize a jump, one can use this function at the end of the push-off phase and declare a weight of -1.
1338+
- **MINIMIZE_PREDICTED_COM_HEIGHT** (Mayer) — Minimizes the maximal height of the center of mass, predicted from the parabolic equation, assuming vertical axis is Z (2): max(CoM_dot[2], 0)**2 / (2 * -g) + CoM[2]. To maximize a jump, one can use this function at the end of the push-off phase and declare a weight of -1.
13391339
- **MINIMIZE_SOFT_CONTACT_FORCES** (Lagrange) — Minimizes the external forces induced by soft contacts (or a target).
13401340
- **MINIMIZE_STATE_DERIVATIVE** (Lagrange) — Minimizes the difference between a state at a node and the same state at the next node, i.e., minimizes the generalized state derivative.
13411341
- **MINIMIZE_STATE** (Lagrange and Mayer) — Minimizes the state variable towards zero (or a target).

bioptim/limits/penalty.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,7 @@ def minimize_qddot(penalty: PenaltyOption, controller: PenaltyController):
606606
def minimize_predicted_com_height(_: PenaltyOption, controller: PenaltyController):
607607
"""
608608
Minimize the prediction of the center of mass maximal height from the parabolic equation,
609-
assuming vertical axis is Z (2): CoM_dot[2]**2 / (2 * -g) + com[2]
609+
assuming vertical axis is Z (2): max(CoM_dot[2], 0)**2 / (2 * -g) + com[2]
610610
By default this function is not quadratic, meaning that it minimizes towards infinity.
611611
612612
Parameters
@@ -622,7 +622,8 @@ def minimize_predicted_com_height(_: PenaltyOption, controller: PenaltyControlle
622622
com_dot = controller.model.center_of_mass_velocity()(
623623
controller.q, controller.qdot, controller.parameters.cx
624624
)
625-
com_height = (com_dot[2] * com_dot[2]) / (2 * -g) + com[2]
625+
com_dot_z = if_else(com_dot[2] > 0, com_dot[2], 0)
626+
com_height = (com_dot_z * com_dot_z) / (2 * -g) + com[2]
626627
return com_height
627628

628629
@staticmethod

tests/shard4/test_penalty.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -858,7 +858,14 @@ def test_penalty_minimize_predicted_com_height(value, phase_dynamics):
858858
penalty = Objective(penalty_type)
859859
res = get_penalty_value(ocp, penalty, t, phases_dt, x, u, p, a, d)
860860

861-
expected = np.array(0.0501274 if value == 0.1 else -3.72579)
861+
q = x[0][: ocp.nlp[0].model.nb_q]
862+
qdot = x[0][ocp.nlp[0].model.nb_q :]
863+
com = ocp.nlp[0].model.center_of_mass()(q, DM())
864+
com_dot = ocp.nlp[0].model.center_of_mass_velocity()(q, qdot, DM())
865+
gravity_z = ocp.nlp[0].model.gravity()(DM())[2]
866+
positive_vertical_velocity = max(float(com_dot[2]), 0.0)
867+
expected = float(com[2]) + positive_vertical_velocity**2 / (2 * -float(gravity_z))
868+
862869
npt.assert_almost_equal(res, expected)
863870

864871

0 commit comments

Comments
 (0)