1414show_animation  =  True 
1515
1616
17+ def  dubins_path_planning (s_x , s_y , s_yaw , g_x , g_y , g_yaw , curvature ,
18+                          step_size = 0.1 ):
19+     """ 
20+     Dubins path planner 
21+ 
22+     :param s_x: x position of start point [m] 
23+     :param s_y: y position of start point [m] 
24+     :param s_yaw: yaw angle of start point [rad] 
25+     :param g_x: x position of end point [m] 
26+     :param g_y: y position of end point [m] 
27+     :param g_yaw: yaw angle of end point [rad] 
28+     :param curvature: curvature for curve [1/m] 
29+     :param step_size: (optional) step size between two path points [m] 
30+     :return: 
31+         x_list: x positions of a path 
32+         y_list: y positions of a path 
33+         yaw_list: yaw angles of a path 
34+         modes: mode list of a path 
35+         lengths: length of path segments. 
36+     """ 
37+ 
38+     g_x  -=  s_x 
39+     g_y  -=  s_y 
40+ 
41+     l_rot  =  Rot .from_euler ('z' , s_yaw ).as_matrix ()[0 :2 , 0 :2 ]
42+     le_xy  =  np .stack ([g_x , g_y ]).T  @ l_rot 
43+     le_yaw  =  g_yaw  -  s_yaw 
44+ 
45+     lp_x , lp_y , lp_yaw , modes , lengths  =  dubins_path_planning_from_origin (
46+         le_xy [0 ], le_xy [1 ], le_yaw , curvature , step_size )
47+ 
48+     rot  =  Rot .from_euler ('z' , - s_yaw ).as_matrix ()[0 :2 , 0 :2 ]
49+     converted_xy  =  np .stack ([lp_x , lp_y ]).T  @ rot 
50+     x_list  =  converted_xy [:, 0 ] +  s_x 
51+     y_list  =  converted_xy [:, 1 ] +  s_y 
52+     yaw_list  =  [pi_2_pi (i_yaw  +  s_yaw ) for  i_yaw  in  lp_yaw ]
53+ 
54+     return  x_list , y_list , yaw_list , modes , lengths 
55+ 
56+ 
1757def  mod2pi (theta ):
1858    return  theta  -  2.0  *  math .pi  *  math .floor (theta  /  2.0  /  math .pi )
1959
@@ -148,14 +188,14 @@ def dubins_path_planning_from_origin(end_x, end_y, end_yaw, curvature,
148188    alpha  =  mod2pi (-  theta )
149189    beta  =  mod2pi (end_yaw  -  theta )
150190
151-     planners  =  [left_straight_left , right_straight_right ,  left_straight_right ,
152-                 right_straight_left ,  right_left_right ,
153-                 left_right_left ]
191+     planning_funcs  =  [left_straight_left , right_straight_right ,
192+                        left_straight_right ,  right_straight_left ,
193+                        right_left_right ,  left_right_left ]
154194
155195    best_cost  =  float ("inf" )
156196    bt , bp , bq , best_mode  =  None , None , None , None 
157197
158-     for  planner  in  planners :
198+     for  planner  in  planning_funcs :
159199        t , p , q , mode  =  planner (alpha , beta , d )
160200        if  t  is  None :
161201            continue 
@@ -166,10 +206,15 @@ def dubins_path_planning_from_origin(end_x, end_y, end_yaw, curvature,
166206            best_cost  =  cost 
167207    lengths  =  [bt , bp , bq ]
168208
169-     x_list , y_list , yaw_list , directions  =  generate_local_course (
170-         sum (lengths ), lengths , best_mode , curvature , step_size )
209+     x_list , y_list , yaw_list , directions  =  generate_local_course (sum (lengths ),
210+                                                                  lengths ,
211+                                                                  best_mode ,
212+                                                                  curvature ,
213+                                                                  step_size )
214+ 
215+     lengths  =  [length  /  curvature  for  length  in  lengths ]
171216
172-     return  x_list , y_list , yaw_list , best_mode , best_cost 
217+     return  x_list , y_list , yaw_list , best_mode , lengths 
173218
174219
175220def  interpolate (ind , length , mode , max_curvature , origin_x , origin_y ,
@@ -203,49 +248,15 @@ def interpolate(ind, length, mode, max_curvature, origin_x, origin_y,
203248    return  path_x , path_y , path_yaw , directions 
204249
205250
206- def  dubins_path_planning (s_x , s_y , s_yaw , g_x , g_y , g_yaw , c , step_size = 0.1 ):
207-     """ 
208-     Dubins path planner 
209- 
210-     input: 
211-         s_x x position of start point [m] 
212-         s_y y position of start point [m] 
213-         s_yaw yaw angle of start point [rad] 
214-         g_x x position of end point [m] 
215-         g_y y position of end point [m] 
216-         g_yaw yaw angle of end point [rad] 
217-         c curvature [1/m] 
218- 
219-     """ 
220- 
221-     g_x  =  g_x  -  s_x 
222-     g_y  =  g_y  -  s_y 
223- 
224-     l_rot  =  Rot .from_euler ('z' , s_yaw ).as_matrix ()[0 :2 , 0 :2 ]
225-     le_xy  =  np .stack ([g_x , g_y ]).T  @ l_rot 
226-     le_yaw  =  g_yaw  -  s_yaw 
227- 
228-     lp_x , lp_y , lp_yaw , mode , lengths  =  dubins_path_planning_from_origin (
229-         le_xy [0 ], le_xy [1 ], le_yaw , c , step_size )
230- 
231-     rot  =  Rot .from_euler ('z' , - s_yaw ).as_matrix ()[0 :2 , 0 :2 ]
232-     converted_xy  =  np .stack ([lp_x , lp_y ]).T  @ rot 
233-     x_list  =  converted_xy [:, 0 ] +  s_x 
234-     y_list  =  converted_xy [:, 1 ] +  s_y 
235-     yaw_list  =  [pi_2_pi (i_yaw  +  s_yaw ) for  i_yaw  in  lp_yaw ]
236- 
237-     return  x_list , y_list , yaw_list , mode , lengths 
238- 
239- 
240- def  generate_local_course (total_length , lengths , mode , max_curvature ,
251+ def  generate_local_course (total_length , lengths , modes , max_curvature ,
241252                          step_size ):
242253    n_point  =  math .trunc (total_length  /  step_size ) +  len (lengths ) +  4 
243254
244-     path_x  =  [0.0  for  _  in  range (n_point )]
245-     path_y  =  [0.0  for  _  in  range (n_point )]
246-     path_yaw  =  [0.0  for  _  in  range (n_point )]
255+     p_x  =  [0.0  for  _  in  range (n_point )]
256+     p_y  =  [0.0  for  _  in  range (n_point )]
257+     p_yaw  =  [0.0  for  _  in  range (n_point )]
247258    directions  =  [0.0  for  _  in  range (n_point )]
248-     index  =  1 
259+     ind  =  1 
249260
250261    if  lengths [0 ] >  0.0 :
251262        directions [0 ] =  1 
@@ -254,7 +265,7 @@ def generate_local_course(total_length, lengths, mode, max_curvature,
254265
255266    ll  =  0.0 
256267
257-     for  (m , length , i ) in  zip (mode , lengths , range (len (mode ))):
268+     for  (m , length , i ) in  zip (modes , lengths , range (len (modes ))):
258269        if  length  ==  0.0 :
259270            continue 
260271        elif  length  >  0.0 :
@@ -263,54 +274,57 @@ def generate_local_course(total_length, lengths, mode, max_curvature,
263274            dist  =  - step_size 
264275
265276        # set origin state 
266-         origin_x , origin_y , origin_yaw  =  \
267-             path_x [index ], path_y [index ], path_yaw [index ]
277+         origin_x , origin_y , origin_yaw  =  p_x [ind ], p_y [ind ], p_yaw [ind ]
268278
269-         index  -=  1 
279+         ind  -=  1 
270280        if  i  >=  1  and  (lengths [i  -  1 ] *  lengths [i ]) >  0 :
271281            pd  =  -  dist  -  ll 
272282        else :
273283            pd  =  dist  -  ll 
274284
275285        while  abs (pd ) <=  abs (length ):
276-             index  +=  1 
277-             path_x , path_y , path_yaw , directions  =  interpolate (
278-                 index , pd , m , max_curvature , origin_x , origin_y , origin_yaw ,
279-                 path_x , path_y , path_yaw , directions )
286+             ind  +=  1 
287+             p_x , p_y , p_yaw , directions  =  interpolate (ind , pd , m ,
288+                                                       max_curvature ,
289+                                                       origin_x ,
290+                                                       origin_y ,
291+                                                       origin_yaw ,
292+                                                       p_x , p_y ,
293+                                                       p_yaw ,
294+                                                       directions )
280295            pd  +=  dist 
281296
282297        ll  =  length  -  pd  -  dist   # calc remain length 
283298
284-         index  +=  1 
285-         path_x , path_y , path_yaw , directions  =  interpolate (
286-             index , length , m , max_curvature , origin_x , origin_y , origin_yaw ,
287-             path_x , path_y , path_yaw , directions )
299+         ind  +=  1 
300+         p_x , p_y , p_yaw , directions  =  interpolate (ind , length , m ,
301+                                                   max_curvature ,
302+                                                   origin_x , origin_y ,
303+                                                   origin_yaw ,
304+                                                   p_x , p_y , p_yaw ,
305+                                                   directions )
288306
289-     if  len (path_x ) <=  1 :
307+     if  len (p_x ) <=  1 :
290308        return  [], [], [], []
291309
292310    # remove unused data 
293-     while  len (path_x ) >=  1  and  path_x [- 1 ] ==  0.0 :
294-         path_x .pop ()
295-         path_y .pop ()
296-         path_yaw .pop ()
311+     while  len (p_x ) >=  1  and  p_x [- 1 ] ==  0.0 :
312+         p_x .pop ()
313+         p_y .pop ()
314+         p_yaw .pop ()
297315        directions .pop ()
298316
299-     return  path_x ,  path_y ,  path_yaw , directions 
317+     return  p_x ,  p_y ,  p_yaw , directions 
300318
301319
302320def  plot_arrow (x , y , yaw , length = 1.0 , width = 0.5 , fc = "r" ,
303321               ec = "k" ):  # pragma: no cover 
304-     """ 
305-     Plot arrow 
306-     """ 
307- 
308322    if  not  isinstance (x , float ):
309323        for  (i_x , i_y , i_yaw ) in  zip (x , y , yaw ):
310324            plot_arrow (i_x , i_y , i_yaw )
311325    else :
312-         plt .arrow (x , y , length  *  math .cos (yaw ), length  *  math .sin (yaw ),
313-                   fc = fc ,  ec = ec , head_width = width , head_length = width )
326+         plt .arrow (x , y , length  *  math .cos (yaw ), length  *  math .sin (yaw ),  fc = fc , 
327+                   ec = ec , head_width = width , head_length = width )
314328        plt .plot (x , y )
315329
316330
@@ -327,9 +341,13 @@ def main():
327341
328342    curvature  =  1.0 
329343
330-     path_x , path_y , path_yaw , mode , path_length  =  dubins_path_planning (
331-         start_x , start_y , start_yaw ,
332-         end_x , end_y , end_yaw , curvature )
344+     path_x , path_y , path_yaw , mode , lengths  =  dubins_path_planning (start_x ,
345+                                                                    start_y ,
346+                                                                    start_yaw ,
347+                                                                    end_x ,
348+                                                                    end_y ,
349+                                                                    end_yaw ,
350+                                                                    curvature )
333351
334352    if  show_animation :
335353        plt .plot (path_x , path_y , label = "final course "  +  "" .join (mode ))
0 commit comments