Skip to content

Commit 89749b2

Browse files
committed
Add move_to_pose test
1 parent eab4d46 commit 89749b2

File tree

2 files changed

+79
-21
lines changed

2 files changed

+79
-21
lines changed

Control/move_to_pose/move_to_pose.py

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -81,29 +81,19 @@ def calc_control_command(self, x_diff, y_diff, theta, theta_goal):
8181
# from 0 rad to 2*pi rad with slight turn
8282

8383
# Ref: The velocity v always has a constant sign which depends on the initial value of α.
84-
if self.direction == 0:
85-
alpha = angle_mod(np.arctan2(y_diff, x_diff) - theta)
86-
if alpha > np.pi / 2 or alpha < -np.pi / 2:
87-
print(f"alpha: {alpha}, direction: -1")
88-
self.direction = -1
89-
else:
90-
print(f"alpha: {alpha}, direction: 1")
91-
self.direction = 1
92-
9384
rho = np.hypot(x_diff, y_diff)
9485
v = self.Kp_rho * rho
9586

96-
if self.direction == 1:
97-
alpha = angle_mod(np.arctan2(y_diff, x_diff) - theta)
98-
alpha = np.clip(alpha, -np.pi / 2, np.pi / 2)
99-
else:
100-
# backward direction should calculate alpha from the opposite direction
87+
alpha = angle_mod(np.arctan2(y_diff, x_diff) - theta)
88+
beta = angle_mod(theta_goal - theta - alpha)
89+
if alpha > np.pi / 2 or alpha < -np.pi / 2:
90+
# recalculate alpha to make alpha in the range of [-pi/2, pi/2]
10191
alpha = angle_mod(np.arctan2(-y_diff, -x_diff) - theta)
102-
alpha = np.clip(alpha, -np.pi / 2, np.pi / 2)
92+
beta = angle_mod(theta_goal - theta - alpha)
93+
w = self.Kp_alpha * alpha - self.Kp_beta * beta
10394
v = -v
104-
105-
beta = angle_mod(theta_goal - theta - alpha)
106-
w = self.Kp_alpha * alpha - self.Kp_beta * beta
95+
else:
96+
w = self.Kp_alpha * alpha - self.Kp_beta * beta
10797

10898
return rho, v, w
10999

tests/test_move_to_pose.py

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,81 @@
1+
import itertools
2+
import numpy as np
13
import conftest # Add root path to sys.path
24
from Control.move_to_pose import move_to_pose as m
35

46

5-
def test_1():
7+
def test_random():
68
m.show_animation = False
79
m.main()
810

911

10-
def test_2():
12+
def test_stability():
13+
"""
14+
This unit test tests the move_to_pose.py program for stability
15+
"""
16+
m.show_animation = False
17+
x_start = 5
18+
y_start = 5
19+
theta_start = 0
20+
x_goal = 1
21+
y_goal = 4
22+
theta_goal = 0
23+
_, _, v_traj, w_traj = m.move_to_pose(
24+
x_start, y_start, theta_start, x_goal, y_goal, theta_goal
25+
)
26+
27+
def v_is_change(current, previous):
28+
return abs(current - previous) > m.MAX_LINEAR_SPEED
29+
30+
def w_is_change(current, previous):
31+
return abs(current - previous) > m.MAX_ANGULAR_SPEED
32+
33+
# Check if the speed is changing too much
34+
window_size = 10
35+
count_threshold = 4
36+
v_change = [v_is_change(v_traj[i], v_traj[i - 1]) for i in range(1, len(v_traj))]
37+
w_change = [w_is_change(w_traj[i], w_traj[i - 1]) for i in range(1, len(w_traj))]
38+
for i in range(len(v_change) - window_size + 1):
39+
v_window = v_change[i : i + window_size]
40+
w_window = w_change[i : i + window_size]
41+
42+
v_unstable = sum(v_window) > count_threshold
43+
w_unstable = sum(w_window) > count_threshold
44+
45+
assert not v_unstable, (
46+
f"v_unstable in window [{i}, {i + window_size}], unstable count: {sum(v_window)}"
47+
)
48+
assert not w_unstable, (
49+
f"w_unstable in window [{i}, {i + window_size}], unstable count: {sum(w_window)}"
50+
)
51+
52+
53+
def test_reach_goal():
54+
"""
55+
This unit test tests the move_to_pose.py program for reaching the goal
56+
"""
57+
m.show_animation = False
58+
x_start = 5
59+
y_start = 5
60+
theta_start_list = [0, np.pi / 2, np.pi, 3 * np.pi / 2]
61+
x_goal_list = [0, 5, 10]
62+
y_goal_list = [0, 5, 10]
63+
theta_goal = 0
64+
for theta_start, x_goal, y_goal in itertools.product(
65+
theta_start_list, x_goal_list, y_goal_list
66+
):
67+
x_traj, y_traj, _, _ = m.move_to_pose(
68+
x_start, y_start, theta_start, x_goal, y_goal, theta_goal
69+
)
70+
x_diff = x_goal - x_traj[-1]
71+
y_diff = y_goal - y_traj[-1]
72+
rho = np.hypot(x_diff, y_diff)
73+
assert rho < 0.001, (
74+
f"start:[{x_start}, {y_start}, {theta_start}], goal:[{x_goal}, {y_goal}, {theta_goal}], rho: {rho} is too large"
75+
)
76+
77+
78+
def test_max_speed():
1179
"""
1280
This unit test tests the move_to_pose.py program for a MAX_LINEAR_SPEED and
1381
MAX_ANGULAR_SPEED
@@ -18,5 +86,5 @@ def test_2():
1886
m.main()
1987

2088

21-
if __name__ == '__main__':
89+
if __name__ == "__main__":
2290
conftest.run_this_test(__file__)

0 commit comments

Comments
 (0)