Skip to content

Commit 56e0b7a

Browse files
committed
DWA code clean up
1 parent 6fbb3cb commit 56e0b7a

File tree

1 file changed

+58
-43
lines changed

1 file changed

+58
-43
lines changed

PathPlanning/DynamicWindowApproach/dynamic_window_approach.py

Lines changed: 58 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,26 @@
1010
import numpy as np
1111
import matplotlib.pyplot as plt
1212

13-
import sys
14-
sys.path.append("../../")
15-
1613

1714
show_animation = True
1815

1916

17+
def dwa_control(x, u, config, goal, ob):
18+
"""
19+
Dynamic Window Approach control
20+
"""
21+
22+
dw = calc_dynamic_window(x, config)
23+
24+
u, traj = calc_final_input(x, u, dw, config, goal, ob)
25+
26+
return u, traj
27+
28+
2029
class Config():
21-
# simulation parameters
30+
"""
31+
simulation parameter class
32+
"""
2233

2334
def __init__(self):
2435
# robot parameter
@@ -29,15 +40,19 @@ def __init__(self):
2940
self.max_dyawrate = 40.0 * math.pi / 180.0 # [rad/ss]
3041
self.v_reso = 0.01 # [m/s]
3142
self.yawrate_reso = 0.1 * math.pi / 180.0 # [rad/s]
32-
self.dt = 0.1 # [s]
43+
self.dt = 0.1 # [s] Time tick for motion prediction
3344
self.predict_time = 3.0 # [s]
3445
self.to_goal_cost_gain = 0.15
3546
self.speed_cost_gain = 1.0
36-
self.robot_radius = 1.0 # [m]
47+
self.obstacle_cost_gain = 1.0
48+
self.robot_radius = 1.0 # [m] for collision check
49+
3750

3851

3952
def motion(x, u, dt):
40-
# motion model
53+
"""
54+
motion model
55+
"""
4156

4257
x[2] += u[1] * dt
4358
x[0] += u[0] * math.cos(x[2]) * dt
@@ -49,6 +64,9 @@ def motion(x, u, dt):
4964

5065

5166
def calc_dynamic_window(x, config):
67+
"""
68+
calculation dynamic window based on current state x
69+
"""
5270

5371
# Dynamic window from robot specification
5472
Vs = [config.min_speed, config.max_speed,
@@ -67,9 +85,12 @@ def calc_dynamic_window(x, config):
6785
return dw
6886

6987

70-
def calc_trajectory(xinit, v, y, config):
88+
def predict_trajectory(x_init, v, y, config):
89+
"""
90+
predict trajectory with an input
91+
"""
7192

72-
x = np.array(xinit)
93+
x = np.array(x_init)
7394
traj = np.array(x)
7495
time = 0
7596
while time <= config.predict_time:
@@ -81,42 +102,44 @@ def calc_trajectory(xinit, v, y, config):
81102

82103

83104
def calc_final_input(x, u, dw, config, goal, ob):
105+
"""
106+
calculation final input with dinamic window
107+
"""
84108

85-
xinit = x[:]
86-
min_cost = 10000.0
87-
min_u = u
88-
min_u[0] = 0.0
109+
x_init = x[:]
110+
min_cost = float("inf")
111+
best_u = [0.0, 0.0]
89112
best_traj = np.array([x])
90113

91114
# evalucate all trajectory with sampled input in dynamic window
92115
for v in np.arange(dw[0], dw[1], config.v_reso):
93116
for y in np.arange(dw[2], dw[3], config.yawrate_reso):
94-
traj = calc_trajectory(xinit, v, y, config)
117+
118+
traj = predict_trajectory(x_init, v, y, config)
95119

96120
# calc cost
97-
to_goal_cost = calc_to_goal_cost(traj, goal, config)
121+
to_goal_cost = config.to_goal_cost_gain * calc_to_goal_cost(traj, goal, config)
98122
speed_cost = config.speed_cost_gain * \
99123
(config.max_speed - traj[-1, 3])
100-
ob_cost = calc_obstacle_cost(traj, ob, config)
101-
# print(ob_cost)
124+
ob_cost = config.obstacle_cost_gain*calc_obstacle_cost(traj, ob, config)
102125

103126
final_cost = to_goal_cost + speed_cost + ob_cost
104127

105-
#print (final_cost)
106-
107128
# search minimum trajectory
108129
if min_cost >= final_cost:
109130
min_cost = final_cost
110-
min_u = [v, y]
131+
best_u = [v, y]
111132
best_traj = traj
112133

113-
return min_u, best_traj
134+
return best_u, best_traj
114135

115136

116137
def calc_obstacle_cost(traj, ob, config):
117-
# calc obstacle cost inf: collistion, 0:free
138+
"""
139+
calc obstacle cost inf: collision
140+
"""
118141

119-
skip_n = 2
142+
skip_n = 2 # for speed up
120143
minr = float("inf")
121144

122145
for ii in range(0, len(traj[:, 1]), skip_n):
@@ -137,26 +160,18 @@ def calc_obstacle_cost(traj, ob, config):
137160

138161

139162
def calc_to_goal_cost(traj, goal, config):
140-
# calc to goal cost.
163+
"""
164+
calc to goal cost with angle difference
165+
"""
141166

142167
dx = goal[0] - traj[-1, 0]
143168
dy = goal[1] - traj[-1, 1]
144169
error_angle = math.atan2(dy, dx)
145-
cost = config.to_goal_cost_gain * abs(error_angle - traj[-1, 2])
170+
cost = abs(error_angle - traj[-1, 2])
146171

147172
return cost
148173

149174

150-
def dwa_control(x, u, config, goal, ob):
151-
# Dynamic Window control
152-
153-
dw = calc_dynamic_window(x, config)
154-
155-
u, traj = calc_final_input(x, u, dw, config, goal, ob)
156-
157-
return u, traj
158-
159-
160175
def plot_arrow(x, y, yaw, length=0.5, width=0.1): # pragma: no cover
161176
plt.arrow(x, y, length * math.cos(yaw), length * math.sin(yaw),
162177
head_length=width, head_width=width)
@@ -182,21 +197,20 @@ def main(gx=10, gy=10):
182197
[12.0, 12.0]
183198
])
184199

200+
# input [forward speed, yawrate]
185201
u = np.array([0.0, 0.0])
186202
config = Config()
187203
traj = np.array(x)
188204

189-
for i in range(1000):
190-
u, ltraj = dwa_control(x, u, config, goal, ob)
205+
while True:
206+
u, ptraj = dwa_control(x, u, config, goal, ob)
191207

192-
x = motion(x, u, config.dt)
208+
x = motion(x, u, config.dt) # simulate robot
193209
traj = np.vstack((traj, x)) # store state history
194210

195-
# print(traj)
196-
197211
if show_animation:
198212
plt.cla()
199-
plt.plot(ltraj[:, 0], ltraj[:, 1], "-g")
213+
plt.plot(ptraj[:, 0], ptraj[:, 1], "-g")
200214
plt.plot(x[0], x[1], "xr")
201215
plt.plot(goal[0], goal[1], "xb")
202216
plt.plot(ob[:, 0], ob[:, 1], "ok")
@@ -205,8 +219,9 @@ def main(gx=10, gy=10):
205219
plt.grid(True)
206220
plt.pause(0.0001)
207221

208-
# check goal
209-
if math.sqrt((x[0] - goal[0])**2 + (x[1] - goal[1])**2) <= config.robot_radius:
222+
# check reaching goal
223+
dist_to_goal = math.sqrt((x[0] - goal[0])**2 + (x[1] - goal[1])**2)
224+
if dist_to_goal <= config.robot_radius:
210225
print("Goal!!")
211226
break
212227

0 commit comments

Comments
 (0)