1111
1212show_animation = True
1313
14+
1415class Dijkstra :
1516
16- def __init__ (self , ox , oy , reso , rr ):
17+ def __init__ (self , ox , oy , resolution , robot_radius ):
1718 """
1819 Initialize map for a star planning
1920
2021 ox: x position list of Obstacles [m]
2122 oy: y position list of Obstacles [m]
22- reso : grid resolution [m]
23+ resolution : grid resolution [m]
2324 rr: robot radius[m]
2425 """
2526
26- self .reso = reso
27- self .rr = rr
27+ self .resolution = resolution
28+ self .robot_radius = robot_radius
2829 self .calc_obstacle_map (ox , oy )
2930 self .motion = self .get_motion_model ()
3031
32+ self .min_x = None
33+ self .min_y = None
34+ self .max_x = None
35+ self .max_y = None
36+ self .x_width = None
37+ self .y_width = None
38+ self .obstacle_map = None
39+
3140 class Node :
32- def __init__ (self , x , y , cost , pind ):
41+ def __init__ (self , x , y , cost , parent ):
3342 self .x = x # index of grid
3443 self .y = y # index of grid
3544 self .cost = cost
36- self .pind = pind # index of previous Node
45+ self .parent = parent # index of previous Node
3746
3847 def __str__ (self ):
39- return str (self .x ) + "," + str (self .y ) + "," + str (self .cost ) + "," + str (self .pind )
48+ return str (self .x ) + "," + str (self .y ) + "," + str (
49+ self .cost ) + "," + str (self .parent )
4050
4151 def planning (self , sx , sy , gx , gy ):
4252 """
@@ -53,39 +63,40 @@ def planning(self, sx, sy, gx, gy):
5363 ry: y position list of the final path
5464 """
5565
56- nstart = self .Node (self .calc_xyindex (sx , self .minx ),
57- self .calc_xyindex (sy , self .miny ), 0.0 , - 1 )
58- ngoal = self .Node (self .calc_xyindex (gx , self .minx ),
59- self .calc_xyindex (gy , self .miny ), 0.0 , - 1 )
66+ start_node = self .Node (self .calc_xy_index (sx , self .min_x ),
67+ self .calc_xy_index (sy , self .min_y ), 0.0 , - 1 )
68+ goal_node = self .Node (self .calc_xy_index (gx , self .min_x ),
69+ self .calc_xy_index (gy , self .min_y ), 0.0 , - 1 )
6070
61- openset , closedset = dict (), dict ()
62- openset [self .calc_index (nstart )] = nstart
71+ open_set , closed_set = dict (), dict ()
72+ open_set [self .calc_index (start_node )] = start_node
6373
6474 while 1 :
65- c_id = min (openset , key = lambda o : openset [o ].cost )
66- current = openset [c_id ]
75+ c_id = min (open_set , key = lambda o : open_set [o ].cost )
76+ current = open_set [c_id ]
6777
6878 # show graph
6979 if show_animation : # pragma: no cover
70- plt .plot (self .calc_position (current .x , self .minx ),
71- self .calc_position (current .y , self .miny ), "xc" )
80+ plt .plot (self .calc_position (current .x , self .min_x ),
81+ self .calc_position (current .y , self .min_y ), "xc" )
7282 # for stopping simulation with the esc key.
73- plt .gcf ().canvas .mpl_connect ('key_release_event' ,
74- lambda event : [exit (0 ) if event .key == 'escape' else None ])
75- if len (closedset .keys ()) % 10 == 0 :
83+ plt .gcf ().canvas .mpl_connect (
84+ 'key_release_event' ,
85+ lambda event : [exit (0 ) if event .key == 'escape' else None ])
86+ if len (closed_set .keys ()) % 10 == 0 :
7687 plt .pause (0.001 )
7788
78- if current .x == ngoal .x and current .y == ngoal .y :
89+ if current .x == goal_node .x and current .y == goal_node .y :
7990 print ("Find goal" )
80- ngoal . pind = current .pind
81- ngoal .cost = current .cost
91+ goal_node . parent = current .parent
92+ goal_node .cost = current .cost
8293 break
8394
8495 # Remove the item from the open set
85- del openset [c_id ]
96+ del open_set [c_id ]
8697
8798 # Add it to the closed set
88- closedset [c_id ] = current
99+ closed_set [c_id ] = current
89100
90101 # expand search grid based on motion model
91102 for move_x , move_y , move_cost in self .motion :
@@ -94,94 +105,95 @@ def planning(self, sx, sy, gx, gy):
94105 current .cost + move_cost , c_id )
95106 n_id = self .calc_index (node )
96107
97- if n_id in closedset :
108+ if n_id in closed_set :
98109 continue
99110
100111 if not self .verify_node (node ):
101112 continue
102113
103- if n_id not in openset :
104- openset [n_id ] = node # Discover a new node
114+ if n_id not in open_set :
115+ open_set [n_id ] = node # Discover a new node
105116 else :
106- if openset [n_id ].cost >= node .cost :
117+ if open_set [n_id ].cost >= node .cost :
107118 # This path is the best until now. record it!
108- openset [n_id ] = node
119+ open_set [n_id ] = node
109120
110- rx , ry = self .calc_final_path (ngoal , closedset )
121+ rx , ry = self .calc_final_path (goal_node , closed_set )
111122
112123 return rx , ry
113124
114- def calc_final_path (self , ngoal , closedset ):
125+ def calc_final_path (self , goal_node , closed_set ):
115126 # generate final course
116- rx , ry = [self .calc_position (ngoal .x , self .minx )], [
117- self .calc_position (ngoal .y , self .miny )]
118- pind = ngoal . pind
119- while pind != - 1 :
120- n = closedset [ pind ]
121- rx .append (self .calc_position (n .x , self .minx ))
122- ry .append (self .calc_position (n .y , self .miny ))
123- pind = n .pind
127+ rx , ry = [self .calc_position (goal_node .x , self .min_x )], [
128+ self .calc_position (goal_node .y , self .min_y )]
129+ parent = goal_node . parent
130+ while parent != - 1 :
131+ n = closed_set [ parent ]
132+ rx .append (self .calc_position (n .x , self .min_x ))
133+ ry .append (self .calc_position (n .y , self .min_y ))
134+ parent = n .parent
124135
125136 return rx , ry
126137
127138 def calc_position (self , index , minp ):
128- pos = index * self .reso + minp
139+ pos = index * self .resolution + minp
129140 return pos
130141
131- def calc_xyindex (self , position , minp ):
132- return round ((position - minp )/ self .reso )
142+ def calc_xy_index (self , position , minp ):
143+ return round ((position - minp ) / self .resolution )
133144
134145 def calc_index (self , node ):
135- return (node .y - self .miny ) * self .xwidth + (node .x - self .minx )
146+ return (node .y - self .min_y ) * self .x_width + (node .x - self .min_x )
136147
137148 def verify_node (self , node ):
138- px = self .calc_position (node .x , self .minx )
139- py = self .calc_position (node .y , self .miny )
149+ px = self .calc_position (node .x , self .min_x )
150+ py = self .calc_position (node .y , self .min_y )
140151
141- if px < self .minx :
152+ if px < self .min_x :
142153 return False
143- elif py < self .miny :
154+ elif py < self .min_y :
144155 return False
145- elif px >= self .maxx :
156+ elif px >= self .max_x :
146157 return False
147- elif py >= self .maxy :
158+ elif py >= self .max_y :
148159 return False
149160
150- if self .obmap [node .x ][node .y ]:
161+ if self .obstacle_map [node .x ][node .y ]:
151162 return False
152163
153164 return True
154165
155166 def calc_obstacle_map (self , ox , oy ):
156167
157- self .minx = round (min (ox ))
158- self .miny = round (min (oy ))
159- self .maxx = round (max (ox ))
160- self .maxy = round (max (oy ))
161- print ("minx:" , self .minx )
162- print ("miny:" , self .miny )
163- print ("maxx:" , self .maxx )
164- print ("maxy:" , self .maxy )
168+ self .min_x = round (min (ox ))
169+ self .min_y = round (min (oy ))
170+ self .max_x = round (max (ox ))
171+ self .max_y = round (max (oy ))
172+ print ("minx:" , self .min_x )
173+ print ("miny:" , self .min_y )
174+ print ("maxx:" , self .max_x )
175+ print ("maxy:" , self .max_y )
165176
166- self .xwidth = round ((self .maxx - self .minx ) / self .reso )
167- self .ywidth = round ((self .maxy - self .miny ) / self .reso )
168- print ("xwidth:" , self .xwidth )
169- print ("ywidth:" , self .ywidth )
177+ self .x_width = round ((self .max_x - self .min_x ) / self .resolution )
178+ self .y_width = round ((self .max_y - self .min_y ) / self .resolution )
179+ print ("xwidth:" , self .x_width )
180+ print ("ywidth:" , self .y_width )
170181
171182 # obstacle map generation
172- self .obmap = [[False for i in range (self .ywidth )]
173- for i in range (self .xwidth )]
174- for ix in range (self .xwidth ):
175- x = self .calc_position (ix , self .minx )
176- for iy in range (self .ywidth ):
177- y = self .calc_position (iy , self .miny )
183+ self .obstacle_map = [[False for _ in range (self .y_width )]
184+ for _ in range (self .x_width )]
185+ for ix in range (self .x_width ):
186+ x = self .calc_position (ix , self .min_x )
187+ for iy in range (self .y_width ):
188+ y = self .calc_position (iy , self .min_y )
178189 for iox , ioy in zip (ox , oy ):
179190 d = math .hypot (iox - x , ioy - y )
180- if d <= self .rr :
181- self .obmap [ix ][iy ] = True
191+ if d <= self .robot_radius :
192+ self .obstacle_map [ix ][iy ] = True
182193 break
183194
184- def get_motion_model (self ):
195+ @staticmethod
196+ def get_motion_model ():
185197 # dx, dy, cost
186198 motion = [[1 , 0 , 1 ],
187199 [0 , 1 , 1 ],
@@ -239,6 +251,7 @@ def main():
239251
240252 if show_animation : # pragma: no cover
241253 plt .plot (rx , ry , "-r" )
254+ plt .pause (0.01 )
242255 plt .show ()
243256
244257
0 commit comments