Skip to content

Commit 6edd3df

Browse files
committed
Update move_to_pose for cases where alpha > pi/2 or alpha < -pi/2
1 parent 2b70809 commit 6edd3df

File tree

1 file changed

+52
-25
lines changed

1 file changed

+52
-25
lines changed

Control/move_to_pose/move_to_pose.py

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,21 @@
55
Author: Daniel Ingram (daniel-s-ingram)
66
Atsushi Sakai (@Atsushi_twi)
77
Seied Muhammad Yazdian (@Muhammad-Yazdian)
8+
Wang Zheng (@Aglargil)
89
910
P. I. Corke, "Robotics, Vision & Control", Springer 2017, ISBN 978-3-319-54413-7
1011
1112
"""
1213

1314
import matplotlib.pyplot as plt
1415
import numpy as np
15-
from random import random
16+
import sys
17+
import pathlib
18+
19+
sys.path.append(str(pathlib.Path(__file__).parent.parent.parent))
1620
from utils.angle import angle_mod
21+
from random import random
22+
1723

1824
class PathFinderController:
1925
"""
@@ -71,13 +77,18 @@ def calc_control_command(self, x_diff, y_diff, theta, theta_goal):
7177
# from 0 rad to 2*pi rad with slight turn
7278

7379
rho = np.hypot(x_diff, y_diff)
74-
alpha = angle_mod(np.arctan2(y_diff, x_diff) - theta)
75-
beta = angle_mod(theta_goal - theta - alpha)
7680
v = self.Kp_rho * rho
77-
w = self.Kp_alpha * alpha - self.Kp_beta * beta
7881

82+
alpha = angle_mod(np.arctan2(y_diff, x_diff) - theta)
83+
beta = angle_mod(theta_goal - theta - alpha)
7984
if alpha > np.pi / 2 or alpha < -np.pi / 2:
85+
# recalculate alpha to make alpha in the range of [-pi/2, pi/2]
86+
alpha = angle_mod(np.arctan2(-y_diff, -x_diff) - theta)
87+
beta = angle_mod(theta_goal - theta - alpha)
88+
w = self.Kp_alpha * alpha - self.Kp_beta * beta
8089
v = -v
90+
else:
91+
w = self.Kp_alpha * alpha - self.Kp_beta * beta
8192

8293
return rho, v, w
8394

@@ -111,8 +122,7 @@ def move_to_pose(x_start, y_start, theta_start, x_goal, y_goal, theta_goal):
111122
x_diff = x_goal - x
112123
y_diff = y_goal - y
113124

114-
rho, v, w = controller.calc_control_command(
115-
x_diff, y_diff, theta, theta_goal)
125+
rho, v, w = controller.calc_control_command(x_diff, y_diff, theta, theta_goal)
116126

117127
if abs(v) > MAX_LINEAR_SPEED:
118128
v = np.sign(v) * MAX_LINEAR_SPEED
@@ -126,10 +136,22 @@ def move_to_pose(x_start, y_start, theta_start, x_goal, y_goal, theta_goal):
126136

127137
if show_animation: # pragma: no cover
128138
plt.cla()
129-
plt.arrow(x_start, y_start, np.cos(theta_start),
130-
np.sin(theta_start), color='r', width=0.1)
131-
plt.arrow(x_goal, y_goal, np.cos(theta_goal),
132-
np.sin(theta_goal), color='g', width=0.1)
139+
plt.arrow(
140+
x_start,
141+
y_start,
142+
np.cos(theta_start),
143+
np.sin(theta_start),
144+
color="r",
145+
width=0.1,
146+
)
147+
plt.arrow(
148+
x_goal,
149+
y_goal,
150+
np.cos(theta_goal),
151+
np.sin(theta_goal),
152+
color="g",
153+
width=0.1,
154+
)
133155
plot_vehicle(x, y, theta, x_traj, y_traj)
134156

135157

@@ -144,16 +166,16 @@ def plot_vehicle(x, y, theta, x_traj, y_traj): # pragma: no cover
144166
p2 = np.matmul(T, p2_i)
145167
p3 = np.matmul(T, p3_i)
146168

147-
plt.plot([p1[0], p2[0]], [p1[1], p2[1]], 'k-')
148-
plt.plot([p2[0], p3[0]], [p2[1], p3[1]], 'k-')
149-
plt.plot([p3[0], p1[0]], [p3[1], p1[1]], 'k-')
169+
plt.plot([p1[0], p2[0]], [p1[1], p2[1]], "k-")
170+
plt.plot([p2[0], p3[0]], [p2[1], p3[1]], "k-")
171+
plt.plot([p3[0], p1[0]], [p3[1], p1[1]], "k-")
150172

151-
plt.plot(x_traj, y_traj, 'b--')
173+
plt.plot(x_traj, y_traj, "b--")
152174

153175
# for stopping simulation with the esc key.
154176
plt.gcf().canvas.mpl_connect(
155-
'key_release_event',
156-
lambda event: [exit(0) if event.key == 'escape' else None])
177+
"key_release_event", lambda event: [exit(0) if event.key == "escape" else None]
178+
)
157179

158180
plt.xlim(0, 20)
159181
plt.ylim(0, 20)
@@ -162,26 +184,31 @@ def plot_vehicle(x, y, theta, x_traj, y_traj): # pragma: no cover
162184

163185

164186
def transformation_matrix(x, y, theta):
165-
return np.array([
166-
[np.cos(theta), -np.sin(theta), x],
167-
[np.sin(theta), np.cos(theta), y],
168-
[0, 0, 1]
169-
])
187+
return np.array(
188+
[
189+
[np.cos(theta), -np.sin(theta), x],
190+
[np.sin(theta), np.cos(theta), y],
191+
[0, 0, 1],
192+
]
193+
)
170194

171195

172196
def main():
173-
174197
for i in range(5):
175198
x_start = 20.0 * random()
176199
y_start = 20.0 * random()
177200
theta_start: float = 2 * np.pi * random() - np.pi
178201
x_goal = 20 * random()
179202
y_goal = 20 * random()
180203
theta_goal = 2 * np.pi * random() - np.pi
181-
print(f"Initial x: {round(x_start, 2)} m\nInitial y: {round(y_start, 2)} m\nInitial theta: {round(theta_start, 2)} rad\n")
182-
print(f"Goal x: {round(x_goal, 2)} m\nGoal y: {round(y_goal, 2)} m\nGoal theta: {round(theta_goal, 2)} rad\n")
204+
print(
205+
f"Initial x: {round(x_start, 2)} m\nInitial y: {round(y_start, 2)} m\nInitial theta: {round(theta_start, 2)} rad\n"
206+
)
207+
print(
208+
f"Goal x: {round(x_goal, 2)} m\nGoal y: {round(y_goal, 2)} m\nGoal theta: {round(theta_goal, 2)} rad\n"
209+
)
183210
move_to_pose(x_start, y_start, theta_start, x_goal, y_goal, theta_goal)
184211

185212

186-
if __name__ == '__main__':
213+
if __name__ == "__main__":
187214
main()

0 commit comments

Comments
 (0)