1414
1515show_animation = True
1616
17-
1817class Node :
1918
2019 def __init__ (self , x , y , cost , pind ):
21- self .x = x
22- self .y = y
20+ self .x = x # index of grid
21+ self .y = y # index of grid
2322 self .cost = cost
2423 self .pind = pind
2524
2625 def __str__ (self ):
2726 return str (self .x ) + "," + str (self .y ) + "," + str (self .cost ) + "," + str (self .pind )
2827
29-
30- def calc_final_path (ngoal , closedset , reso ):
31- # generate final course
32- rx , ry = [ngoal .x * reso ], [ngoal .y * reso ]
33- pind = ngoal .pind
34- while pind != - 1 :
35- n = closedset [pind ]
36- rx .append (n .x * reso )
37- ry .append (n .y * reso )
38- pind = n .pind
39-
40- return rx , ry
41-
42-
4328def a_star_planning (sx , sy , gx , gy , ox , oy , reso , rr ):
4429 """
45- gx: goal x position [m]
46- gx: goal x position [m]
47- ox: x position list of Obstacles [m]
48- oy: y position list of Obstacles [m]
49- reso: grid resolution [m]
50- rr: robot radius[m]
30+ A star path search
31+
32+ input:
33+ sx: start x position [m]
34+ sy: start y position [m]
35+ gx: goal x position [m]
36+ gx: goal x position [m]
37+ ox: x position list of Obstacles [m]
38+ oy: y position list of Obstacles [m]
39+ reso: grid resolution [m]
40+ rr: robot radius[m]
41+
42+ output:
43+ rx: x position list of the final path
44+ ry: y position list of the final path
5145 """
5246
53- nstart = Node (round (sx / reso ), round (sy / reso ), 0.0 , - 1 )
54- ngoal = Node (round (gx / reso ), round (gy / reso ), 0.0 , - 1 )
5547 ox = [iox / reso for iox in ox ]
5648 oy = [ioy / reso for ioy in oy ]
5749
5850 obmap , minx , miny , maxx , maxy , xw , yw = calc_obstacle_map (ox , oy , reso , rr )
5951
6052 motion = get_motion_model ()
6153
54+ nstart = Node (calc_xyindex (sx , minx , reso ), calc_xyindex (sy , minx , reso ), 0.0 , - 1 )
55+ ngoal = Node (calc_xyindex (gx , minx , reso ), calc_xyindex (gy , minx , reso ), 0.0 , - 1 )
56+
6257 openset , closedset = dict (), dict ()
6358 openset [calc_index (nstart , xw , minx , miny )] = nstart
6459
@@ -69,7 +64,7 @@ def a_star_planning(sx, sy, gx, gy, ox, oy, reso, rr):
6964
7065 # show graph
7166 if show_animation : # pragma: no cover
72- plt .plot (current .x * reso , current .y * reso , "xc" )
67+ plt .plot (calc_position ( current .x , minx , reso ), calc_position ( current .y , miny , reso ) , "xc" )
7368 if len (closedset .keys ()) % 10 == 0 :
7469 plt .pause (0.001 )
7570
@@ -81,6 +76,7 @@ def a_star_planning(sx, sy, gx, gy, ox, oy, reso, rr):
8176
8277 # Remove the item from the open set
8378 del openset [c_id ]
79+
8480 # Add it to the closed set
8581 closedset [c_id ] = current
8682
@@ -94,7 +90,7 @@ def a_star_planning(sx, sy, gx, gy, ox, oy, reso, rr):
9490 if n_id in closedset :
9591 continue
9692
97- if not verify_node (node , obmap , minx , miny , maxx , maxy ):
93+ if not verify_node (node , obmap , minx , miny , maxx , maxy , reso ):
9894 continue
9995
10096 if n_id not in openset :
@@ -104,26 +100,49 @@ def a_star_planning(sx, sy, gx, gy, ox, oy, reso, rr):
104100 # This path is the best until now. record it!
105101 openset [n_id ] = node
106102
107- rx , ry = calc_final_path (ngoal , closedset , reso )
103+ rx , ry = calc_final_path (ngoal , closedset , reso , minx , miny )
108104
109105 return rx , ry
110106
111107
108+
109+ def calc_final_path (ngoal , closedset , reso , minx , miny ):
110+ # generate final course
111+ rx , ry = [calc_position (ngoal .x , minx , reso )], [calc_position (ngoal .y , miny , reso )]
112+ pind = ngoal .pind
113+ while pind != - 1 :
114+ n = closedset [pind ]
115+ rx .append (calc_position (n .x , minx , reso ))
116+ ry .append (calc_position (n .y , miny , reso ))
117+ pind = n .pind
118+
119+ return rx , ry
120+
121+
122+
112123def calc_heuristic (n1 , n2 ):
113124 w = 1.0 # weight of heuristic
114125 d = w * math .sqrt ((n1 .x - n2 .x )** 2 + (n1 .y - n2 .y )** 2 )
115126 return d
116127
128+ def calc_position (index , minp , reso ):
129+ return index * reso + minp
117130
118- def verify_node (node , obmap , minx , miny , maxx , maxy ):
131+ def calc_xyindex (position , minp , reso ):
132+ return round ((position - minp )/ reso )
119133
120- if node .x < minx :
134+ def verify_node (node , obmap , minx , miny , maxx , maxy , reso ):
135+
136+ px = calc_position (node .x , minx , reso )
137+ py = calc_position (node .y , miny , reso )
138+
139+ if px < minx :
121140 return False
122- elif node . y < miny :
141+ elif py < miny :
123142 return False
124- elif node . x >= maxx :
143+ elif px >= maxx :
125144 return False
126- elif node . y >= maxy :
145+ elif py >= maxy :
127146 return False
128147
129148 if obmap [node .x ][node .y ]:
@@ -132,32 +151,31 @@ def verify_node(node, obmap, minx, miny, maxx, maxy):
132151 return True
133152
134153
135- def calc_obstacle_map (ox , oy , reso , vr ):
154+ def calc_obstacle_map (ox , oy , reso , rr ):
136155
137156 minx = round (min (ox ))
138157 miny = round (min (oy ))
139158 maxx = round (max (ox ))
140159 maxy = round (max (oy ))
141- # print("minx:", minx)
142- # print("miny:", miny)
143- # print("maxx:", maxx)
144- # print("maxy:", maxy)
160+ print ("minx:" , minx )
161+ print ("miny:" , miny )
162+ print ("maxx:" , maxx )
163+ print ("maxy:" , maxy )
145164
146165 xwidth = round (maxx - minx )
147166 ywidth = round (maxy - miny )
148- # print("xwidth:", xwidth)
149- # print("ywidth:", ywidth)
167+ print ("xwidth:" , xwidth )
168+ print ("ywidth:" , ywidth )
150169
151170 # obstacle map generation
152171 obmap = [[False for i in range (ywidth )] for i in range (xwidth )]
153172 for ix in range (xwidth ):
154173 x = ix + minx
155174 for iy in range (ywidth ):
156175 y = iy + miny
157- # print(x, y)
158176 for iox , ioy in zip (ox , oy ):
159177 d = math .sqrt ((iox - x )** 2 + (ioy - y )** 2 )
160- if d <= vr / reso :
178+ if d <= rr :
161179 obmap [ix ][iy ] = True
162180 break
163181
@@ -191,37 +209,37 @@ def main():
191209 gx = 50.0 # [m]
192210 gy = 50.0 # [m]
193211 grid_size = 1.0 # [m]
194- robot_size = 1.0 # [m]
212+ robot_radius = 1.0 # [m]
195213
214+ # set obstable positions
196215 ox , oy = [], []
197-
198- for i in range (60 ):
216+ for i in range (- 10 , 60 ):
199217 ox .append (i )
200- oy .append (0 .0 )
201- for i in range (60 ):
218+ oy .append (- 10 .0 )
219+ for i in range (- 10 , 60 ):
202220 ox .append (60.0 )
203221 oy .append (i )
204- for i in range (61 ):
222+ for i in range (- 10 , 61 ):
205223 ox .append (i )
206224 oy .append (60.0 )
207- for i in range (61 ):
208- ox .append (0 .0 )
225+ for i in range (- 10 , 61 ):
226+ ox .append (- 10 .0 )
209227 oy .append (i )
210- for i in range (40 ):
228+ for i in range (- 10 , 40 ):
211229 ox .append (20.0 )
212230 oy .append (i )
213- for i in range (40 ):
231+ for i in range (0 , 40 ):
214232 ox .append (40.0 )
215233 oy .append (60.0 - i )
216234
217235 if show_animation : # pragma: no cover
218236 plt .plot (ox , oy , ".k" )
219- plt .plot (sx , sy , "xr " )
237+ plt .plot (sx , sy , "og " )
220238 plt .plot (gx , gy , "xb" )
221239 plt .grid (True )
222240 plt .axis ("equal" )
223241
224- rx , ry = a_star_planning (sx , sy , gx , gy , ox , oy , grid_size , robot_size )
242+ rx , ry = a_star_planning (sx , sy , gx , gy , ox , oy , grid_size , robot_radius )
225243
226244 if show_animation : # pragma: no cover
227245 plt .plot (rx , ry , "-r" )
0 commit comments