1212import math
1313import matplotlib .pyplot as plt
1414import random
15+ import numpy as np
1516
1617show_animation = True
1718pause_time = 0.001
@@ -62,32 +63,40 @@ def __init__(self, ox: list, oy: list):
6263 self .y_max = int (abs (max (oy ) - self .y_min_world ))
6364 self .obstacles = [Node (x - self .x_min_world , y - self .y_min_world )
6465 for x , y in zip (ox , oy )]
66+ self .obstacles_xy = np .array (
67+ [[obstacle .x , obstacle .y ] for obstacle in self .obstacles ]
68+ )
6569 self .start = Node (0 , 0 )
6670 self .goal = Node (0 , 0 )
6771 self .U = list () # type: ignore
6872 self .km = 0.0
6973 self .kold = 0.0
70- self .rhs = list () # type: ignore
71- self .g = list () # type: ignore
72- self .detected_obstacles = list () # type: ignore
74+ self .rhs = self .create_grid (float ("inf" ))
75+ self .g = self .create_grid (float ("inf" ))
76+ self .detected_obstacles_xy = np .empty ((0 , 2 ))
77+ self .xy = np .empty ((0 , 2 ))
7378 if show_animation :
7479 self .detected_obstacles_for_plotting_x = list () # type: ignore
7580 self .detected_obstacles_for_plotting_y = list () # type: ignore
81+ self .initialized = False
7682
7783 def create_grid (self , val : float ):
78- grid = list ()
79- for _ in range (0 , self .x_max ):
80- grid_row = list ()
81- for _ in range (0 , self .y_max ):
82- grid_row .append (val )
83- grid .append (grid_row )
84- return grid
84+ return np .full ((self .x_max , self .y_max ), val )
8585
8686 def is_obstacle (self , node : Node ):
87- return any ([compare_coordinates (node , obstacle )
88- for obstacle in self .obstacles ]) or \
89- any ([compare_coordinates (node , obstacle )
90- for obstacle in self .detected_obstacles ])
87+ x = np .array ([node .x ])
88+ y = np .array ([node .y ])
89+ obstacle_x_equal = self .obstacles_xy [:, 0 ] == x
90+ obstacle_y_equal = self .obstacles_xy [:, 1 ] == y
91+ is_in_obstacles = (obstacle_x_equal & obstacle_y_equal ).any ()
92+
93+ is_in_detected_obstacles = False
94+ if self .detected_obstacles_xy .shape [0 ] > 0 :
95+ is_x_equal = self .detected_obstacles_xy [:, 0 ] == x
96+ is_y_equal = self .detected_obstacles_xy [:, 1 ] == y
97+ is_in_detected_obstacles = (is_x_equal & is_y_equal ).any ()
98+
99+ return is_in_obstacles or is_in_detected_obstacles
91100
92101 def c (self , node1 : Node , node2 : Node ):
93102 if self .is_obstacle (node2 ):
@@ -139,13 +148,16 @@ def initialize(self, start: Node, goal: Node):
139148 self .start .y = start .y - self .y_min_world
140149 self .goal .x = goal .x - self .x_min_world
141150 self .goal .y = goal .y - self .y_min_world
142- self .U = list () # Would normally be a priority queue
143- self .km = 0.0
144- self .rhs = self .create_grid (math .inf )
145- self .g = self .create_grid (math .inf )
146- self .rhs [self .goal .x ][self .goal .y ] = 0
147- self .U .append ((self .goal , self .calculate_key (self .goal )))
148- self .detected_obstacles = list ()
151+ if not self .initialized :
152+ self .initialized = True
153+ print ('Initializing' )
154+ self .U = list () # Would normally be a priority queue
155+ self .km = 0.0
156+ self .rhs = self .create_grid (math .inf )
157+ self .g = self .create_grid (math .inf )
158+ self .rhs [self .goal .x ][self .goal .y ] = 0
159+ self .U .append ((self .goal , self .calculate_key (self .goal )))
160+ self .detected_obstacles_xy = np .empty ((0 , 2 ))
149161
150162 def update_vertex (self , u : Node ):
151163 if not compare_coordinates (u , self .goal ):
@@ -167,26 +179,33 @@ def compare_keys(self, key_pair1: tuple[float, float],
167179
168180 def compute_shortest_path (self ):
169181 self .U .sort (key = lambda x : x [1 ])
170- while (len (self .U ) > 0 and
171- self .compare_keys (self .U [0 ][1 ],
172- self .calculate_key (self .start ))) or \
173- self .rhs [self .start .x ][self .start .y ] != \
174- self .g [self .start .x ][self .start .y ]:
182+ has_elements = len (self .U ) > 0
183+ start_key_not_updated = self .compare_keys (
184+ self .U [0 ][1 ], self .calculate_key (self .start )
185+ )
186+ rhs_not_equal_to_g = self .rhs [self .start .x ][self .start .y ] != \
187+ self .g [self .start .x ][self .start .y ]
188+ while has_elements and start_key_not_updated or rhs_not_equal_to_g :
175189 self .kold = self .U [0 ][1 ]
176190 u = self .U [0 ][0 ]
177191 self .U .pop (0 )
178192 if self .compare_keys (self .kold , self .calculate_key (u )):
179193 self .U .append ((u , self .calculate_key (u )))
180194 self .U .sort (key = lambda x : x [1 ])
181- elif self .g [u .x ][ u .y ] > self .rhs [u .x ][ u .y ]:
182- self .g [u .x ][ u .y ] = self .rhs [u .x ][ u .y ]
195+ elif ( self .g [u .x , u .y ] > self .rhs [u .x , u .y ]). any () :
196+ self .g [u .x , u .y ] = self .rhs [u .x , u .y ]
183197 for s in self .pred (u ):
184198 self .update_vertex (s )
185199 else :
186- self .g [u .x ][ u .y ] = math .inf
200+ self .g [u .x , u .y ] = math .inf
187201 for s in self .pred (u ) + [u ]:
188202 self .update_vertex (s )
189203 self .U .sort (key = lambda x : x [1 ])
204+ start_key_not_updated = self .compare_keys (
205+ self .U [0 ][1 ], self .calculate_key (self .start )
206+ )
207+ rhs_not_equal_to_g = self .rhs [self .start .x ][self .start .y ] != \
208+ self .g [self .start .x ][self .start .y ]
190209
191210 def detect_changes (self ):
192211 changed_vertices = list ()
@@ -196,7 +215,12 @@ def detect_changes(self):
196215 compare_coordinates (spoofed_obstacle , self .goal ):
197216 continue
198217 changed_vertices .append (spoofed_obstacle )
199- self .detected_obstacles .append (spoofed_obstacle )
218+ self .detected_obstacles_xy = np .concatenate (
219+ (
220+ self .detected_obstacles_xy ,
221+ [[spoofed_obstacle .x , spoofed_obstacle .y ]]
222+ )
223+ )
200224 if show_animation :
201225 self .detected_obstacles_for_plotting_x .append (
202226 spoofed_obstacle .x + self .x_min_world )
@@ -210,14 +234,19 @@ def detect_changes(self):
210234 # Allows random generation of obstacles
211235 random .seed ()
212236 if random .random () > 1 - p_create_random_obstacle :
213- x = random .randint (0 , self .x_max )
214- y = random .randint (0 , self .y_max )
237+ x = random .randint (0 , self .x_max - 1 )
238+ y = random .randint (0 , self .y_max - 1 )
215239 new_obs = Node (x , y )
216240 if compare_coordinates (new_obs , self .start ) or \
217241 compare_coordinates (new_obs , self .goal ):
218242 return changed_vertices
219243 changed_vertices .append (Node (x , y ))
220- self .detected_obstacles .append (Node (x , y ))
244+ self .detected_obstacles_xy = np .concatenate (
245+ (
246+ self .detected_obstacles_xy ,
247+ [[x , y ]]
248+ )
249+ )
221250 if show_animation :
222251 self .detected_obstacles_for_plotting_x .append (x +
223252 self .x_min_world )
0 commit comments