1010import numpy as np
1111import matplotlib .pyplot as plt
1212
13- import sys
14- sys .path .append ("../../" )
15-
1613
1714show_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+
2029class 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
3952def 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
5166def 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
83104def 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
116137def 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
139162def 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-
160175def 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