Skip to content

Commit 5acb304

Browse files
authored
Merge pull request #651 from EveCharbie/corrections_track_vectors
Correction to TRACK_VECTOR_ORIENTAION_FROM_MARKERS
2 parents 8acc724 + 6a8e60f commit 5acb304

File tree

3 files changed

+15
-13
lines changed

3 files changed

+15
-13
lines changed

bioptim/limits/penalty.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import inspect
44

55
import biorbd_casadi as biorbd
6-
from casadi import horzcat, vertcat, SX, Function, acos, norm_2, dot
6+
from casadi import horzcat, vertcat, SX, Function, atan2, dot, cross, sqrt
77

88
from .penalty_option import PenaltyOption
99
from .penalty_node import PenaltyNodeList
@@ -799,6 +799,7 @@ def track_vector_orientations_from_markers(
799799
The second vector is defined by vector_1_marker_1 - vector_1_marker_0.
800800
Note that is minimizes the angle between the two vectors, thus it is not possible ti specify an axis.
801801
By default, this function is quadratic, meaning that it minimizes the angle between the two vectors.
802+
WARNING: please be careful as there is a discontinuity when the two vectors are orthogonal.
802803
803804
Parameters
804805
----------
@@ -839,10 +840,11 @@ def track_vector_orientations_from_markers(
839840

840841
vector_0 = vector_0_marker_1_position - vector_0_marker_0_position
841842
vector_1 = vector_1_marker_1_position - vector_1_marker_0_position
843+
cross_prod = cross(vector_0, vector_1)
844+
cross_prod_norm = sqrt(cross_prod[0] ** 2 + cross_prod[1] ** 2 + cross_prod[2] ** 2)
845+
out = atan2(cross_prod_norm, dot(vector_0, vector_1))
842846

843-
angle = acos(dot(vector_0, vector_1) ** 2 / (norm_2(vector_0) * norm_2(vector_1)))
844-
845-
angle_objective = nlp.mx_to_cx("vector_orientations_difference", angle, nlp.states["q"])
847+
angle_objective = nlp.mx_to_cx("vector_orientations_difference", out, nlp.states["q"])
846848

847849
return angle_objective
848850

tests/test_global_align.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ def test_track_vector_orientation():
118118
# Check objective function value
119119
f = np.array(sol.cost)
120120
np.testing.assert_equal(f.shape, (1, 1))
121-
np.testing.assert_almost_equal(f[0, 0], 1206.2849823554816)
121+
np.testing.assert_almost_equal(f[0, 0], 2.614556858357712e-08)
122122

123123
# Check constraints
124124
g = np.array(sol.constraints)
@@ -129,17 +129,17 @@ def test_track_vector_orientation():
129129
q, qdot, tau = sol.states["q"], sol.states["qdot"], sol.controls["tau"]
130130

131131
# initial and final position
132-
np.testing.assert_almost_equal(q[:, 0], np.array([0.80000001, -0.68299837, -1.57, -1.56999931]))
133-
np.testing.assert_almost_equal(q[:, -1], np.array([0.80000001, -0.68299837, 1.57, 1.56999966]))
132+
np.testing.assert_almost_equal(q[:, 0], np.array([0.80000001, -0.68299837, -1.57, -1.56999089]))
133+
np.testing.assert_almost_equal(q[:, -1], np.array([0.80000001, -0.68299837, 1.57, 1.56999138]))
134134
# initial and final velocities
135-
np.testing.assert_almost_equal(qdot[:, 0], np.array((-5.62939992e-16, 4.90499998e00, 3.14000113e00, 3.13999784e00)))
135+
np.testing.assert_almost_equal(qdot[:, 0], np.array((3.37753150e-16, 4.90499995e00, 3.14001172e00, 3.13997056e00)))
136136
np.testing.assert_almost_equal(
137-
qdot[:, -1], np.array((-5.62940009e-16, -4.90499998e00, 3.14000029e00, 3.13999868e00))
137+
qdot[:, -1], np.array((3.37753131e-16, -4.90499995e00, 3.14001059e00, 3.13997170e00))
138138
)
139139
# initial and final controls
140140
np.testing.assert_almost_equal(
141-
tau[:, 0], np.array([1.05886391e-25, 6.28215525e-09, -2.53398134e-06, 2.52582173e-06])
141+
tau[:, 0], np.array([-1.27269674e-24, 1.97261036e-08, -3.01420965e-05, 3.01164220e-05])
142142
)
143143
np.testing.assert_almost_equal(
144-
tau[:, -2], np.array([-6.38733211e-24, 6.28215525e-09, 1.31751960e-06, -1.30936553e-06])
144+
tau[:, -2], np.array([-2.10041085e-23, 1.97261036e-08, 2.86303889e-05, -2.86047182e-05])
145145
)

tests/test_penalty.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -694,9 +694,9 @@ def test_penalty_minimize_vector_orientation(penalty_origin, value):
694694
res = get_penalty_value(ocp, penalty, t, x, u, [])
695695

696696
if value == 0.1:
697-
np.testing.assert_almost_equal(float(res), 1.0529423391195598)
697+
np.testing.assert_almost_equal(float(res), 0.09999999999999999)
698698
else:
699-
np.testing.assert_almost_equal(float(res), 1.2110674089002156)
699+
np.testing.assert_almost_equal(float(res), 2.566370614359173)
700700

701701

702702
@pytest.mark.parametrize("penalty_origin", [ConstraintFcn])

0 commit comments

Comments
 (0)