From 6a4edbe8480a77dbef9da81ae51253fae5b2d13b Mon Sep 17 00:00:00 2001 From: Ujjansh Sundram Date: Tue, 7 Oct 2025 03:29:52 +0530 Subject: [PATCH 01/25] dynamic maze solver --- .../BreadthFirstSearch/dynamic_maze_solver.py | 190 ++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 PathPlanning/BreadthFirstSearch/dynamic_maze_solver.py diff --git a/PathPlanning/BreadthFirstSearch/dynamic_maze_solver.py b/PathPlanning/BreadthFirstSearch/dynamic_maze_solver.py new file mode 100644 index 0000000000..cab236a46c --- /dev/null +++ b/PathPlanning/BreadthFirstSearch/dynamic_maze_solver.py @@ -0,0 +1,190 @@ +import matplotlib.pyplot as plt +import matplotlib.colors as mcolors +import numpy as np +from collections import deque +import random +import matplotlib.animation as animation + +class MazeVisualizer: + """ + A class to create a beautiful and interesting visualization + of a dynamic maze-solving algorithm (BFS). + """ + + def __init__(self, maze, start, target): + self.maze = np.array(maze) + self.start_pos = start + self.target_pos = target + self.solver_pos = start + + self.rows, self.cols = self.maze.shape + + # --- Configurable Parameters --- + self.step_delay_ms = 200 # Animation frame delay in milliseconds + self.target_move_interval = 5 # Target moves every N frames + self.obstacle_change_prob = 0.01 # Probability of a wall changing + + # --- State Tracking --- + self.path = [] + self.visited_nodes = set() + self.breadcrumb_trail = [self.solver_pos] + self.frame_count = 0 + + # --- Plotting Setup --- + self.fig, self.ax = plt.subplots(figsize=(8, 6)) + plt.style.use('seaborn-v0_8-darkgrid') + self.fig.patch.set_facecolor('#2c2c2c') + self.ax.set_facecolor('#1e1e1e') + + # Hide axes ticks and labels for a cleaner look + self.ax.set_xticks([]) + self.ax.set_yticks([]) + + # Maze plot + self.maze_plot = self.ax.imshow(self.maze, cmap='magma', interpolation='nearest') + + # Visited nodes plot (semi-transparent overlay) + self.visited_overlay = np.zeros((*self.maze.shape, 4)) # RGBA + self.visited_plot = self.ax.imshow(self.visited_overlay, interpolation='nearest') + + # Path, solver, target, and breadcrumbs plots + self.path_line, = self.ax.plot([], [], 'g-', linewidth=3, alpha=0.7, label='Path') + self.breadcrumbs_plot = self.ax.scatter([], [], c=[], cmap='viridis_r', s=50, alpha=0.6, label='Trail') + self.solver_plot, = self.ax.plot(self.solver_pos[1], self.solver_pos[0], 'o', markersize=15, color='#00ffdd', label='Solver') + self.target_plot, = self.ax.plot(self.target_pos[1], self.target_pos[0], '*', markersize=20, color='#ff006a', label='Target') + + self.ax.legend(facecolor='gray', framealpha=0.5, loc='upper right') + self.title = self.ax.set_title("Initializing Maze...", color='white', fontsize=14) + + def _bfs(self): + """Performs BFS to find the shortest path and returns path and visited nodes.""" + queue = deque([(self.solver_pos, [self.solver_pos])]) + visited = {self.solver_pos} + + while queue: + (r, c), path = queue.popleft() + + if (r, c) == self.target_pos: + return path, visited + + for dr, dc in [(-1, 0), (1, 0), (0, -1), (0, 1)]: + nr, nc = r + dr, c + dc + if 0 <= nr < self.rows and 0 <= nc < self.cols and \ + self.maze[nr][nc] == 0 and (nr, nc) not in visited: + visited.add((nr, nc)) + new_path = list(path) + new_path.append((nr, nc)) + queue.append(((nr, nc), new_path)) + + return None, visited # No path found + + def _update_target(self): + """Moves the target to a random adjacent valid cell.""" + tr, tc = self.target_pos + moves = [(-1, 0), (1, 0), (0, -1), (0, 1)] + random.shuffle(moves) + for dr, dc in moves: + nr, nc = tr + dr, tc + dc + if 0 <= nr < self.rows and 0 <= nc < self.cols and self.maze[nr][nc] == 0: + self.target_pos = (nr, nc) + break + + def _update_obstacles(self): + """Randomly toggles a few obstacle cells.""" + for r in range(self.rows): + for c in range(self.cols): + # Avoid changing start/target positions + if (r,c) == self.solver_pos or (r,c) == self.target_pos: + continue + if random.random() < self.obstacle_change_prob: + self.maze[r, c] = 1 - self.maze[r, c] # Toggle 0 to 1 or 1 to 0 + + def _update_frame(self, frame): + """Main animation loop function.""" + self.frame_count += 1 + + # --- Update Game State --- + if self.frame_count % self.target_move_interval == 0: + self._update_target() + + self._update_obstacles() + + self.path, self.visited_nodes = self._bfs() + + if self.path and len(self.path) > 1: + self.solver_pos = self.path[1] # Move solver one step + self.breadcrumb_trail.append(self.solver_pos) + + # --- Update Visuals --- + # Update maze and visited nodes overlay + self.maze_plot.set_data(self.maze) + self.visited_overlay.fill(0) # Reset overlay + visited_color = mcolors.to_rgba('#0077b6', alpha=0.3) + for r, c in self.visited_nodes: + self.visited_overlay[r, c] = visited_color + self.visited_plot.set_data(self.visited_overlay) + + # Update path line + if self.path: + path_y, path_x = zip(*self.path) + self.path_line.set_data(path_x, path_y) + else: + self.path_line.set_data([], []) + + # Update solver and target positions + self.solver_plot.set_data(self.solver_pos[1], self.solver_pos[0]) + self.target_plot.set_data(self.target_pos[1], self.target_pos[0]) + + # Update breadcrumbs + if self.breadcrumb_trail: + trail_y, trail_x = zip(*self.breadcrumb_trail) + colors = np.linspace(0.1, 1.0, len(trail_y)) + self.breadcrumbs_plot.set_offsets(np.c_[trail_x, trail_y]) + self.breadcrumbs_plot.set_array(colors) + + # Update title and check for win condition + if self.solver_pos == self.target_pos: + self.title.set_text("Target Reached! 🎉") + self.title.set_color('lightgreen') + self.anim.event_source.stop() # Stop animation + else: + path_len_str = len(self.path) if self.path else "N/A" + self.title.set_text(f"Frame: {self.frame_count} | Path Length: {path_len_str}") + if not self.path: + self.title.set_color('coral') + else: + self.title.set_color('white') + + return [self.maze_plot, self.visited_plot, self.path_line, self.solver_plot, + self.target_plot, self.breadcrumbs_plot, self.title] + + def run(self): + """Starts the animation.""" + self.anim = animation.FuncAnimation( + self.fig, + self._update_frame, + frames=200, # Can be increased for longer animation + interval=self.step_delay_ms, + blit=True, + repeat=False + ) + plt.show() + +if __name__ == "__main__": + initial_maze = [ + [0, 1, 0, 0, 0, 0, 0, 0, 1, 0], + [0, 1, 0, 1, 1, 0, 1, 0, 1, 0], + [0, 0, 0, 1, 0, 0, 1, 0, 0, 0], + [0, 1, 0, 1, 0, 1, 1, 1, 1, 0], + [0, 1, 0, 0, 0, 0, 0, 0, 1, 0], + [0, 1, 1, 1, 1, 1, 1, 0, 1, 0], + [0, 0, 0, 0, 0, 0, 1, 0, 0, 0], + [1, 1, 1, 1, 0, 1, 1, 1, 1, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + ] + + start_point = (0, 0) + end_point = (8, 9) + + visualizer = MazeVisualizer(maze=initial_maze, start=start_point, target=end_point) + visualizer.run() \ No newline at end of file From b2decb7c76fec9b199792bc80baa02d9ff41afa4 Mon Sep 17 00:00:00 2001 From: Ujjansh Sundram Date: Fri, 10 Oct 2025 21:42:05 +0530 Subject: [PATCH 02/25] updated code --- .../BreadthFirstSearch/dynamic_maze_solver.py | 147 +++++++++--------- 1 file changed, 74 insertions(+), 73 deletions(-) diff --git a/PathPlanning/BreadthFirstSearch/dynamic_maze_solver.py b/PathPlanning/BreadthFirstSearch/dynamic_maze_solver.py index cab236a46c..0eb717d2f0 100644 --- a/PathPlanning/BreadthFirstSearch/dynamic_maze_solver.py +++ b/PathPlanning/BreadthFirstSearch/dynamic_maze_solver.py @@ -5,24 +5,22 @@ import random import matplotlib.animation as animation + class MazeVisualizer: """ - A class to create a beautiful and interesting visualization - of a dynamic maze-solving algorithm (BFS). + Dynamic BFS maze-solving visualizer with moving target and evolving obstacles. """ def __init__(self, maze, start, target): - self.maze = np.array(maze) + self.maze = np.array(maze, dtype=int) self.start_pos = start self.target_pos = target self.solver_pos = start - + self.rows, self.cols = self.maze.shape - - # --- Configurable Parameters --- - self.step_delay_ms = 200 # Animation frame delay in milliseconds - self.target_move_interval = 5 # Target moves every N frames - self.obstacle_change_prob = 0.01 # Probability of a wall changing + self.step_delay_ms = 200 # Animation frame delay + self.target_move_interval = 5 # Target moves every N frames + self.obstacle_change_prob = 0.01 # Random obstacle toggle probability # --- State Tracking --- self.path = [] @@ -30,34 +28,39 @@ def __init__(self, maze, start, target): self.breadcrumb_trail = [self.solver_pos] self.frame_count = 0 - # --- Plotting Setup --- + # --- Plot Setup --- self.fig, self.ax = plt.subplots(figsize=(8, 6)) plt.style.use('seaborn-v0_8-darkgrid') self.fig.patch.set_facecolor('#2c2c2c') self.ax.set_facecolor('#1e1e1e') - - # Hide axes ticks and labels for a cleaner look + self.ax.set_xticks([]) self.ax.set_yticks([]) - - # Maze plot + + # Base maze self.maze_plot = self.ax.imshow(self.maze, cmap='magma', interpolation='nearest') - - # Visited nodes plot (semi-transparent overlay) - self.visited_overlay = np.zeros((*self.maze.shape, 4)) # RGBA + + # Visited overlay + self.visited_overlay = np.zeros((*self.maze.shape, 4)) self.visited_plot = self.ax.imshow(self.visited_overlay, interpolation='nearest') - # Path, solver, target, and breadcrumbs plots + # Path, breadcrumbs, solver, target self.path_line, = self.ax.plot([], [], 'g-', linewidth=3, alpha=0.7, label='Path') self.breadcrumbs_plot = self.ax.scatter([], [], c=[], cmap='viridis_r', s=50, alpha=0.6, label='Trail') - self.solver_plot, = self.ax.plot(self.solver_pos[1], self.solver_pos[0], 'o', markersize=15, color='#00ffdd', label='Solver') - self.target_plot, = self.ax.plot(self.target_pos[1], self.target_pos[0], '*', markersize=20, color='#ff006a', label='Target') - + self.solver_plot, = self.ax.plot( + [self.solver_pos[1]], [self.solver_pos[0]], + 'o', markersize=15, color='#00ffdd', label='Solver' + ) + self.target_plot, = self.ax.plot( + [self.target_pos[1]], [self.target_pos[0]], + '*', markersize=20, color='#ff006a', label='Target' + ) + self.ax.legend(facecolor='gray', framealpha=0.5, loc='upper right') self.title = self.ax.set_title("Initializing Maze...", color='white', fontsize=14) def _bfs(self): - """Performs BFS to find the shortest path and returns path and visited nodes.""" + """Performs BFS to find shortest path.""" queue = deque([(self.solver_pos, [self.solver_pos])]) visited = {self.solver_pos} @@ -70,16 +73,14 @@ def _bfs(self): for dr, dc in [(-1, 0), (1, 0), (0, -1), (0, 1)]: nr, nc = r + dr, c + dc if 0 <= nr < self.rows and 0 <= nc < self.cols and \ - self.maze[nr][nc] == 0 and (nr, nc) not in visited: + self.maze[nr][nc] == 0 and (nr, nc) not in visited: visited.add((nr, nc)) - new_path = list(path) - new_path.append((nr, nc)) - queue.append(((nr, nc), new_path)) - - return None, visited # No path found + queue.append(((nr, nc), path + [(nr, nc)])) + + return None, visited def _update_target(self): - """Moves the target to a random adjacent valid cell.""" + """Moves the target randomly to an adjacent open cell.""" tr, tc = self.target_pos moves = [(-1, 0), (1, 0), (0, -1), (0, 1)] random.shuffle(moves) @@ -90,86 +91,86 @@ def _update_target(self): break def _update_obstacles(self): - """Randomly toggles a few obstacle cells.""" + """Randomly toggle a few obstacles.""" for r in range(self.rows): for c in range(self.cols): - # Avoid changing start/target positions - if (r,c) == self.solver_pos or (r,c) == self.target_pos: + if (r, c) in [self.solver_pos, self.target_pos]: continue if random.random() < self.obstacle_change_prob: - self.maze[r, c] = 1 - self.maze[r, c] # Toggle 0 to 1 or 1 to 0 + self.maze[r, c] = 1 - self.maze[r, c] def _update_frame(self, frame): - """Main animation loop function.""" + """Main animation loop.""" self.frame_count += 1 - - # --- Update Game State --- + + # --- State --- if self.frame_count % self.target_move_interval == 0: self._update_target() - self._update_obstacles() - + self.path, self.visited_nodes = self._bfs() + # Move solver one step if self.path and len(self.path) > 1: - self.solver_pos = self.path[1] # Move solver one step + self.solver_pos = self.path[1] self.breadcrumb_trail.append(self.solver_pos) - # --- Update Visuals --- - # Update maze and visited nodes overlay + # --- Visuals --- self.maze_plot.set_data(self.maze) - self.visited_overlay.fill(0) # Reset overlay + + # Visited overlay + self.visited_overlay.fill(0) visited_color = mcolors.to_rgba('#0077b6', alpha=0.3) for r, c in self.visited_nodes: self.visited_overlay[r, c] = visited_color self.visited_plot.set_data(self.visited_overlay) - - # Update path line + + # Path line if self.path: - path_y, path_x = zip(*self.path) - self.path_line.set_data(path_x, path_y) + y, x = zip(*self.path) + self.path_line.set_data(x, y) else: self.path_line.set_data([], []) - # Update solver and target positions - self.solver_plot.set_data(self.solver_pos[1], self.solver_pos[0]) - self.target_plot.set_data(self.target_pos[1], self.target_pos[0]) + # set_data() now receives sequences + self.solver_plot.set_data([self.solver_pos[1]], [self.solver_pos[0]]) + self.target_plot.set_data([self.target_pos[1]], [self.target_pos[0]]) - # Update breadcrumbs + # Breadcrumbs if self.breadcrumb_trail: - trail_y, trail_x = zip(*self.breadcrumb_trail) - colors = np.linspace(0.1, 1.0, len(trail_y)) - self.breadcrumbs_plot.set_offsets(np.c_[trail_x, trail_y]) + y, x = zip(*self.breadcrumb_trail) + colors = np.linspace(0.1, 1.0, len(y)) + self.breadcrumbs_plot.set_offsets(np.c_[x, y]) self.breadcrumbs_plot.set_array(colors) - # Update title and check for win condition + # Title update if self.solver_pos == self.target_pos: - self.title.set_text("Target Reached! 🎉") + self.title.set_text("Dynamic Maze Solver") self.title.set_color('lightgreen') - self.anim.event_source.stop() # Stop animation + self.anim.event_source.stop() else: - path_len_str = len(self.path) if self.path else "N/A" - self.title.set_text(f"Frame: {self.frame_count} | Path Length: {path_len_str}") - if not self.path: - self.title.set_color('coral') - else: - self.title.set_color('white') - - return [self.maze_plot, self.visited_plot, self.path_line, self.solver_plot, - self.target_plot, self.breadcrumbs_plot, self.title] + path_len = len(self.path) if self.path else "N/A" + self.title.set_text(f"Frame: {self.frame_count} | Path Length: {path_len}") + self.title.set_color('white' if self.path else 'coral') + + return [ + self.maze_plot, self.visited_plot, self.path_line, + self.solver_plot, self.target_plot, self.breadcrumbs_plot, self.title + ] def run(self): """Starts the animation.""" self.anim = animation.FuncAnimation( - self.fig, - self._update_frame, - frames=200, # Can be increased for longer animation - interval=self.step_delay_ms, - blit=True, + self.fig, + self._update_frame, + frames=500, + interval=self.step_delay_ms, + blit=False, repeat=False ) plt.show() + if __name__ == "__main__": initial_maze = [ [0, 1, 0, 0, 0, 0, 0, 0, 1, 0], @@ -182,9 +183,9 @@ def run(self): [1, 1, 1, 1, 0, 1, 1, 1, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ] - + start_point = (0, 0) end_point = (8, 9) - visualizer = MazeVisualizer(maze=initial_maze, start=start_point, target=end_point) - visualizer.run() \ No newline at end of file + visualizer = MazeVisualizer(initial_maze, start_point, end_point) + visualizer.run() From a4a1f6f7f0b9b04549d31cc4a1b549bb02221b8b Mon Sep 17 00:00:00 2001 From: Ujjansh Sundram Date: Tue, 14 Oct 2025 01:08:52 +0530 Subject: [PATCH 03/25] Created the doc file --- .../Dynamic_maze_Slover.rst | 143 ++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Slover.rst diff --git a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Slover.rst b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Slover.rst new file mode 100644 index 0000000000..519a8ff4f4 --- /dev/null +++ b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Slover.rst @@ -0,0 +1,143 @@ +Dynamic Maze Solver using Breadth-First Search (BFS) +==================================================== + +.. contents:: Table of Contents + :local: + :depth: 2 + +Overview +-------- + +This example demonstrates a **dynamic maze-solving algorithm** based on the +**Breadth-First Search (BFS)** strategy. The visualizer dynamically updates a maze +in real-time while the solver attempts to reach a moving target. + +Unlike static pathfinding examples, this version introduces: + +- **A moving target** that relocates periodically. +- **Randomly evolving obstacles** that can appear or disappear. +- **Animated BFS exploration**, showing visited cells, computed paths, and breadcrumbs. + +This simulation provides intuition for dynamic pathfinding problems such as +robot navigation in unpredictable environments. + + +Algorithmic Background +---------------------- + +### Breadth-First Search (BFS) + +The BFS algorithm is a graph traversal method that explores nodes in layers, +guaranteeing the shortest path in an unweighted grid. + +Let the maze be represented as a grid: + +.. math:: + + M = \{ (i, j) \mid 0 \leq i < R, 0 \leq j < C \} + +where each cell is either *free (0)* or *obstacle (1)*. + +The BFS frontier expands as: + +.. math:: + + Q = [(s, [s])] + +where *s* is the start position, and the second term is the path history. + +At each iteration: + +.. math:: + + (r, c), path = Q.pop(0) + + \text{for each neighbor } (r', c') \text{ in } N(r, c): + \text{if } (r', c') \text{ is free and unvisited:} + Q.append((r', c'), path + [(r', c')]) + +The algorithm halts when the target node *t* is reached. + +Because BFS explores all nodes in increasing distance order, the path returned +is the shortest (in terms of number of moves). + + +Dynamic Components +------------------ + +### Moving Target + +Every few frames, the target moves randomly to an adjacent open cell: + +.. math:: + + T_{new} = T_{old} + \Delta + +where :math:`\Delta \in \{ (-1,0), (1,0), (0,-1), (0,1) \}`. + +This simulates dynamic goals or moving entities in robotic navigation. + +### Evolving Obstacles + +With a small probability :math:`p`, each cell toggles between *free* and *blocked*: + +.. math:: + + M_{i,j}^{t+1} = + \begin{cases} + 1 - M_{i,j}^{t} & \text{with probability } p \\ + M_{i,j}^{t} & \text{otherwise} + \end{cases} + +This reflects real-world conditions like temporary obstructions or environment changes. + + +Visualization +------------- + +The maze, solver, target, and BFS layers are visualized using **Matplotlib**. + +Elements include: + +- **Maze cells** – magma colormap (black = wall, bright = open) +- **Visited nodes** – blue overlay with transparency +- **Path line** – green connecting line +- **Solver (robot)** – cyan circle +- **Target** – magenta star +- **Breadcrumbs** – trail of previously visited solver positions + +A sample animation frame: + +.. image:: ezgif.com-crop.jpg + :alt: Maze BFS dynamic visualizer frame + :align: center + :scale: 80 % + + +Mathematical Insights +--------------------- + +- **BFS guarantees optimality** in unweighted grids. +- The evolving maze introduces **non-stationarity**, requiring recomputation per frame. +- The path length :math:`L_t` fluctuates as the environment changes. + +If :math:`E_t` is the set of explored nodes at frame :math:`t`, then: + +.. math:: + + L_t = |P_t|, \quad E_t = |V_t| + +where :math:`P_t` is the discovered path and :math:`V_t` is the visited node set. + +The solver continually re-estimates the path to accommodate new maze configurations. + + +References +---------- + +- **Algorithm:** Breadth-First Search (BFS) :-``_ +- **Visualization:** Matplotlib animation +- **Maze Solver:**:-``__ + + + From 3849184d5f7b60dfbf56fe795ecbfa551abaf85f Mon Sep 17 00:00:00 2001 From: XOXO <142672693+Ujjansh05@users.noreply.github.com> Date: Tue, 21 Oct 2025 23:25:02 +0530 Subject: [PATCH 04/25] Delete docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Slover.rst --- .../Dynamic_maze_Slover.rst | 143 ------------------ 1 file changed, 143 deletions(-) delete mode 100644 docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Slover.rst diff --git a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Slover.rst b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Slover.rst deleted file mode 100644 index 519a8ff4f4..0000000000 --- a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Slover.rst +++ /dev/null @@ -1,143 +0,0 @@ -Dynamic Maze Solver using Breadth-First Search (BFS) -==================================================== - -.. contents:: Table of Contents - :local: - :depth: 2 - -Overview --------- - -This example demonstrates a **dynamic maze-solving algorithm** based on the -**Breadth-First Search (BFS)** strategy. The visualizer dynamically updates a maze -in real-time while the solver attempts to reach a moving target. - -Unlike static pathfinding examples, this version introduces: - -- **A moving target** that relocates periodically. -- **Randomly evolving obstacles** that can appear or disappear. -- **Animated BFS exploration**, showing visited cells, computed paths, and breadcrumbs. - -This simulation provides intuition for dynamic pathfinding problems such as -robot navigation in unpredictable environments. - - -Algorithmic Background ----------------------- - -### Breadth-First Search (BFS) - -The BFS algorithm is a graph traversal method that explores nodes in layers, -guaranteeing the shortest path in an unweighted grid. - -Let the maze be represented as a grid: - -.. math:: - - M = \{ (i, j) \mid 0 \leq i < R, 0 \leq j < C \} - -where each cell is either *free (0)* or *obstacle (1)*. - -The BFS frontier expands as: - -.. math:: - - Q = [(s, [s])] - -where *s* is the start position, and the second term is the path history. - -At each iteration: - -.. math:: - - (r, c), path = Q.pop(0) - - \text{for each neighbor } (r', c') \text{ in } N(r, c): - \text{if } (r', c') \text{ is free and unvisited:} - Q.append((r', c'), path + [(r', c')]) - -The algorithm halts when the target node *t* is reached. - -Because BFS explores all nodes in increasing distance order, the path returned -is the shortest (in terms of number of moves). - - -Dynamic Components ------------------- - -### Moving Target - -Every few frames, the target moves randomly to an adjacent open cell: - -.. math:: - - T_{new} = T_{old} + \Delta - -where :math:`\Delta \in \{ (-1,0), (1,0), (0,-1), (0,1) \}`. - -This simulates dynamic goals or moving entities in robotic navigation. - -### Evolving Obstacles - -With a small probability :math:`p`, each cell toggles between *free* and *blocked*: - -.. math:: - - M_{i,j}^{t+1} = - \begin{cases} - 1 - M_{i,j}^{t} & \text{with probability } p \\ - M_{i,j}^{t} & \text{otherwise} - \end{cases} - -This reflects real-world conditions like temporary obstructions or environment changes. - - -Visualization -------------- - -The maze, solver, target, and BFS layers are visualized using **Matplotlib**. - -Elements include: - -- **Maze cells** – magma colormap (black = wall, bright = open) -- **Visited nodes** – blue overlay with transparency -- **Path line** – green connecting line -- **Solver (robot)** – cyan circle -- **Target** – magenta star -- **Breadcrumbs** – trail of previously visited solver positions - -A sample animation frame: - -.. image:: ezgif.com-crop.jpg - :alt: Maze BFS dynamic visualizer frame - :align: center - :scale: 80 % - - -Mathematical Insights ---------------------- - -- **BFS guarantees optimality** in unweighted grids. -- The evolving maze introduces **non-stationarity**, requiring recomputation per frame. -- The path length :math:`L_t` fluctuates as the environment changes. - -If :math:`E_t` is the set of explored nodes at frame :math:`t`, then: - -.. math:: - - L_t = |P_t|, \quad E_t = |V_t| - -where :math:`P_t` is the discovered path and :math:`V_t` is the visited node set. - -The solver continually re-estimates the path to accommodate new maze configurations. - - -References ----------- - -- **Algorithm:** Breadth-First Search (BFS) :-``_ -- **Visualization:** Matplotlib animation -- **Maze Solver:**:-``__ - - - From 62481b0af47852e31ec2b8407900a77bbd96721e Mon Sep 17 00:00:00 2001 From: Ujjansh Sundram Date: Tue, 21 Oct 2025 23:37:23 +0530 Subject: [PATCH 05/25] update the rst and added the test file --- .../Dynamic_maze_Solver.rst | 177 ++++++++++++++++++ tests/test_dynamic_maze_solver.py | 26 +++ 2 files changed, 203 insertions(+) create mode 100644 docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst create mode 100644 tests/test_dynamic_maze_solver.py diff --git a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst new file mode 100644 index 0000000000..e4a64e18af --- /dev/null +++ b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst @@ -0,0 +1,177 @@ +Dynamic Maze Solver using Breadth-First Search (BFS) +==================================================== + +.. contents:: Table of Contents + :local: + :depth: 2 + +Overview +-------- + +This example demonstrates a **dynamic maze-solving algorithm** based on the +**Breadth-First Search (BFS)** strategy. The visualizer dynamically updates a maze +in real-time while the solver attempts to reach a moving target. + +Unlike static pathfinding examples, this version introduces: + +- **A moving target** that relocates periodically. +- **Randomly evolving obstacles** that can appear or disappear. +- **Animated BFS exploration**, showing visited cells, computed paths, and breadcrumbs. + +This simulation provides intuition for dynamic pathfinding problems such as +robot navigation in unpredictable environments. + + +Algorithmic Background +---------------------- + +### Breadth-First Search (BFS) + +The BFS algorithm is a graph traversal method that explores nodes in layers, +guaranteeing the shortest path in an unweighted grid. + +Let the maze be represented as a grid: + +.. math:: + + M = \{ (i, j) \mid 0 \leq i < R, 0 \leq j < C \} + +where each cell is either *free (0)* or *obstacle (1)*. + +The BFS frontier expands as: + +.. math:: + + Q = [(s, [s])] + +where *s* is the start position, and the second term is the path history. + +At each iteration: + +.. math:: + + (r, c), path = Q.pop(0) + + \text{for each neighbor } (r', c') \text{ in } N(r, c): + \text{if } (r', c') \text{ is free and unvisited:} + Q.append((r', c'), path + [(r', c')]) + +The algorithm halts when the target node *t* is reached. + +Because BFS explores all nodes in increasing distance order, the path returned +is the shortest (in terms of number of moves). + + +Dynamic Components +------------------ + +### Moving Target + +Every few frames, the target moves randomly to an adjacent open cell: + +.. math:: + + T_{new} = T_{old} + \Delta + +where :math:`\Delta \in \{ (-1,0), (1,0), (0,-1), (0,1) \}`. + +This simulates dynamic goals or moving entities in robotic navigation. + +### Evolving Obstacles + +With a small probability :math:`p`, each cell toggles between *free* and *blocked*: + +.. math:: + + M_{i,j}^{t+1} = + \begin{cases} + 1 - M_{i,j}^{t} & \text{with probability } p \\ + M_{i,j}^{t} & \text{otherwise} + \end{cases} + +This reflects real-world conditions like temporary obstructions or environment changes. + + +Visualization +------------- + +The maze, solver, target, and BFS layers are visualized using **Matplotlib**. + +Elements include: + +- **Maze cells** - magma colormap (black = wall, bright = open) +- **Visited nodes** - blue overlay with transparency +- **Path line** - green connecting line +- **Solver (robot)** - cyan circle +- **Target** - magenta star +- **Breadcrumbs** - trail of previously visited solver positions + +A sample animation frame: + +.. image:: https://github.com/AtsushiSakai/PythonRoboticsGifs/raw/master/PathPlanning/dynamic_maze_solver/animation.gif + :alt: Maze BFS dynamic visualizer frame + :align: center + :scale: 80 % + + +Mathematical Insights +--------------------- + +- **BFS guarantees optimality** in unweighted grids. +- The evolving maze introduces **non-stationarity**, requiring recomputation per frame. +- The path length :math:`L_t` fluctuates as the environment changes. + +If :math:`E_t` is the set of explored nodes at frame :math:`t`, then: + +.. math:: + + L_t = |P_t|, \quad E_t = |V_t| + +where :math:`P_t` is the discovered path and :math:`V_t` is the visited node set. + +The solver continually re-estimates the path to accommodate new maze configurations. + + +Code Link +++++++++ + +.. automodule:: PathPlanning.BreadthFirstSearch.dynamic_maze_solver + :members: + :undoc-members: + :show-inheritance: + +Usage Example +++++++++++++ + +.. code-block:: python + import matplotlib.pyplot as plt + from PathPlanning.BreadthFirstSearch.dynamic_maze_solver import MazeVisualizer + + initial_maze = [ + [0, 1, 0, 0, 0, 0, 0, 0, 1, 0], + [0, 1, 0, 1, 1, 0, 1, 0, 1, 0], + [0, 0, 0, 1, 0, 0, 1, 0, 0, 0], + [0, 1, 0, 1, 0, 1, 1, 1, 1, 0], + [0, 1, 0, 0, 0, 0, 0, 0, 1, 0], + [0, 1, 1, 1, 1, 1, 1, 0, 1, 0], + [0, 0, 0, 0, 0, 0, 1, 0, 0, 0], + [1, 1, 1, 1, 0, 1, 1, 1, 1, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + ] + + start_point = (0, 0) + end_point = (8, 9) + + visualizer = MazeVisualizer(initial_maze, start_point, end_point) + visualizer.run() + + +References +---------- + +- **Algorithm:** Breadth-First Search (BFS) :-``_ +- **Visualization:** Matplotlib animation +- **Maze Solver:**:-``__ + + + diff --git a/tests/test_dynamic_maze_solver.py b/tests/test_dynamic_maze_solver.py new file mode 100644 index 0000000000..bfb3d73c93 --- /dev/null +++ b/tests/test_dynamic_maze_solver.py @@ -0,0 +1,26 @@ +import conftest +from PathPlanning.BreadthFirstSearch.dynamic_maze_solver import MazeVisualizer + + +def test_bfs_finds_path(): + # small maze: 0=open, 1=wall + maze = [ + [0, 0, 0], + [1, 1, 0], + [0, 0, 0] + ] + + start = (0, 0) + target = (2, 2) + + viz = MazeVisualizer(maze, start, target) + + path, visited = viz._bfs() + + assert path is not None + assert path[0] == start + assert path[-1] == target + + +if __name__ == '__main__': + conftest.run_this_test(__file__) From 7cceb35f003c0c39dd37282f6363ea5d8c5fa06a Mon Sep 17 00:00:00 2001 From: Ujjansh Sundram Date: Wed, 22 Oct 2025 00:25:46 +0530 Subject: [PATCH 06/25] update some mathematical equations --- .../Dynamic_maze_Solver.rst | 75 +++++++------------ 1 file changed, 26 insertions(+), 49 deletions(-) diff --git a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst index e4a64e18af..4d3bdf19d3 100644 --- a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst +++ b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst @@ -42,38 +42,40 @@ The BFS frontier expands as: .. math:: - Q = [(s, [s])] + Q = [(s, [s])], \qquad s \in M -where *s* is the start position, and the second term is the path history. +where each element of \(Q\) is a pair \((v, P)\) with a current node \(v\) and +its path history \(P\). -At each iteration: +The BFS expansion step (pseudocode): .. math:: - (r, c), path = Q.pop(0) + \begin{aligned} + (r,c),\;P &= Q.pop(0), \\ + ext{for each } (r',c') \in N(r,c):\quad &\text{if } 0\le r' Date: Wed, 22 Oct 2025 16:37:12 +0530 Subject: [PATCH 07/25] fix the single letter words and update the rst --- .../BreadthFirstSearch/dynamic_maze_solver.py | 48 +++++++++++-------- .../Dynamic_maze_Solver.rst | 20 ++++---- 2 files changed, 40 insertions(+), 28 deletions(-) diff --git a/PathPlanning/BreadthFirstSearch/dynamic_maze_solver.py b/PathPlanning/BreadthFirstSearch/dynamic_maze_solver.py index 0eb717d2f0..891daf2ba3 100644 --- a/PathPlanning/BreadthFirstSearch/dynamic_maze_solver.py +++ b/PathPlanning/BreadthFirstSearch/dynamic_maze_solver.py @@ -1,3 +1,13 @@ +""" +Dynamic Maze Solver + +Dynamic BFS maze visualizer demonstrating breadth-first search on a grid. + +author: Ujjansh Sundram + +See Wikipedia: https://en.wikipedia.org/wiki/Breadth-first_search +""" + import matplotlib.pyplot as plt import matplotlib.colors as mcolors import numpy as np @@ -65,39 +75,39 @@ def _bfs(self): visited = {self.solver_pos} while queue: - (r, c), path = queue.popleft() + (row, col), path = queue.popleft() - if (r, c) == self.target_pos: + if (row, col) == self.target_pos: return path, visited - for dr, dc in [(-1, 0), (1, 0), (0, -1), (0, 1)]: - nr, nc = r + dr, c + dc - if 0 <= nr < self.rows and 0 <= nc < self.cols and \ - self.maze[nr][nc] == 0 and (nr, nc) not in visited: - visited.add((nr, nc)) - queue.append(((nr, nc), path + [(nr, nc)])) + for d_row, d_col in [(-1, 0), (1, 0), (0, -1), (0, 1)]: + n_row, n_col = row + d_row, col + d_col + if 0 <= n_row < self.rows and 0 <= n_col < self.cols and \ + self.maze[n_row][n_col] == 0 and (n_row, n_col) not in visited: + visited.add((n_row, n_col)) + queue.append(((n_row, n_col), path + [(n_row, n_col)])) return None, visited def _update_target(self): """Moves the target randomly to an adjacent open cell.""" - tr, tc = self.target_pos + t_row, t_col = self.target_pos moves = [(-1, 0), (1, 0), (0, -1), (0, 1)] random.shuffle(moves) - for dr, dc in moves: - nr, nc = tr + dr, tc + dc - if 0 <= nr < self.rows and 0 <= nc < self.cols and self.maze[nr][nc] == 0: - self.target_pos = (nr, nc) + for d_row, d_col in moves: + n_row, n_col = t_row + d_row, t_col + d_col + if 0 <= n_row < self.rows and 0 <= n_col < self.cols and self.maze[n_row][n_col] == 0: + self.target_pos = (n_row, n_col) break def _update_obstacles(self): """Randomly toggle a few obstacles.""" - for r in range(self.rows): - for c in range(self.cols): - if (r, c) in [self.solver_pos, self.target_pos]: + for row in range(self.rows): + for col in range(self.cols): + if (row, col) in [self.solver_pos, self.target_pos]: continue if random.random() < self.obstacle_change_prob: - self.maze[r, c] = 1 - self.maze[r, c] + self.maze[row, col] = 1 - self.maze[row, col] def _update_frame(self, frame): """Main animation loop.""" @@ -121,8 +131,8 @@ def _update_frame(self, frame): # Visited overlay self.visited_overlay.fill(0) visited_color = mcolors.to_rgba('#0077b6', alpha=0.3) - for r, c in self.visited_nodes: - self.visited_overlay[r, c] = visited_color + for row, col in self.visited_nodes: + self.visited_overlay[row, col] = visited_color self.visited_plot.set_data(self.visited_overlay) # Path line diff --git a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst index 4d3bdf19d3..35142e7a2f 100644 --- a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst +++ b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst @@ -10,7 +10,7 @@ Overview This example demonstrates a **dynamic maze-solving algorithm** based on the **Breadth-First Search (BFS)** strategy. The visualizer dynamically updates a maze -in real-time while the solver attempts to reach a moving target. +in real time while the solver attempts to reach a moving target. Unlike static pathfinding examples, this version introduces: @@ -22,6 +22,13 @@ This simulation provides intuition for dynamic pathfinding problems such as robot navigation in unpredictable environments. + +A sample animation frame: + +.. image:: https://raw.githubusercontent.com/AtsushiSakai/PythonRoboticsGifs/master/PathPlanning/dynamic_maze_solver/animation.gif + + + Algorithmic Background ---------------------- @@ -107,14 +114,6 @@ Elements include: - **Target** - magenta star - **Breadcrumbs** - trail of previously visited solver positions -A sample animation frame: - -.. image:: https://github.com/AtsushiSakai/PythonRoboticsGifs/raw/master/PathPlanning/dynamic_maze_solver/animation.gif - :alt: Maze BFS dynamic visualizer frame - :align: center - :scale: 80 % - - Mathematical Insights --------------------- @@ -141,6 +140,9 @@ Code Link ++++++++ .. automodule:: PathPlanning.BreadthFirstSearch.dynamic_maze_solver + :members: + :undoc-members: + :show-inheritance: References From 90d9df996c599a58ca769e8ea48a8c5efdc5a76a Mon Sep 17 00:00:00 2001 From: Ujjansh Sundram Date: Wed, 22 Oct 2025 17:13:08 +0530 Subject: [PATCH 08/25] Update Dynamic_maze_Solver.rst --- .../Dynamic_maze_Solver.rst | 128 ++---------------- 1 file changed, 8 insertions(+), 120 deletions(-) diff --git a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst index 35142e7a2f..4a3647b1d8 100644 --- a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst +++ b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst @@ -8,149 +8,37 @@ Dynamic Maze Solver using Breadth-First Search (BFS) Overview -------- -This example demonstrates a **dynamic maze-solving algorithm** based on the -**Breadth-First Search (BFS)** strategy. The visualizer dynamically updates a maze -in real time while the solver attempts to reach a moving target. - -Unlike static pathfinding examples, this version introduces: - -- **A moving target** that relocates periodically. -- **Randomly evolving obstacles** that can appear or disappear. -- **Animated BFS exploration**, showing visited cells, computed paths, and breadcrumbs. - -This simulation provides intuition for dynamic pathfinding problems such as -robot navigation in unpredictable environments. - - +This example demonstrates a **dynamic maze-solving algorithm** based on the **Breadth-First Search (BFS)** strategy. +The visualizer dynamically updates a maze in real time while the solver attempts to reach a moving target. A sample animation frame: -.. image:: https://raw.githubusercontent.com/AtsushiSakai/PythonRoboticsGifs/master/PathPlanning/dynamic_maze_solver/animation.gif - - +.. image:: https://github.com/AtsushiSakai/PythonRoboticsGifs/raw/master/PathPlanning/dynamic_maze_solver/animation.gif Algorithmic Background ---------------------- ### Breadth-First Search (BFS) -The BFS algorithm is a graph traversal method that explores nodes in layers, -guaranteeing the shortest path in an unweighted grid. - -Let the maze be represented as a grid: +The BFS algorithm is a graph traversal method that explores nodes in layers, guaranteeing the shortest path in an unweighted grid. .. math:: M = \{ (i, j) \mid 0 \leq i < R, 0 \leq j < C \} -where each cell is either *free (0)* or *obstacle (1)*. - -The BFS frontier expands as: - -.. math:: - - Q = [(s, [s])], \qquad s \in M - -where each element of \(Q\) is a pair \((v, P)\) with a current node \(v\) and -its path history \(P\). - -The BFS expansion step (pseudocode): - -.. math:: - - \begin{aligned} - (r,c),\;P &= Q.pop(0), \\ - ext{for each } (r',c') \in N(r,c):\quad &\text{if } 0\le r'`_ +- **Algorithm:** `Breadth-First Search (BFS) `_ - **Visualization:** Matplotlib animation -- **Maze Solver:**:-``__ - - - +- **Maze Solver:** `AI Maze BFS Example `_ From 66d36c6f569ede1b1a589172554abd8bf692fccc Mon Sep 17 00:00:00 2001 From: Ujjansh Sundram Date: Wed, 22 Oct 2025 17:21:54 +0530 Subject: [PATCH 09/25] Update Dynamic_maze_Solver.rst --- .../dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst index 4a3647b1d8..3604f0241e 100644 --- a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst +++ b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst @@ -32,9 +32,7 @@ Code Link +++++++++ .. automodule:: PathPlanning.BreadthFirstSearch.dynamic_maze_solver - :members: - :undoc-members: - :show-inheritance: + References ---------- From 76f96e347702bb4c48b6eccdb64f9b6a20a66608 Mon Sep 17 00:00:00 2001 From: Ujjansh Sundram Date: Thu, 23 Oct 2025 19:50:29 +0530 Subject: [PATCH 10/25] update the image --- .../dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst index 3604f0241e..e4570c03fa 100644 --- a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst +++ b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst @@ -13,7 +13,7 @@ The visualizer dynamically updates a maze in real time while the solver attempts A sample animation frame: -.. image:: https://github.com/AtsushiSakai/PythonRoboticsGifs/raw/master/PathPlanning/dynamic_maze_solver/animation.gif +.. image:: https://github.com/AtsushiSakai/PythonRoboticsGifs/raw/master/PathPlanning/Breadth-first_search/dynamic_maze_solver/animation.gif Algorithmic Background ---------------------- From 02053bd86b9fad6e3f81a7f267125a6e3a432055 Mon Sep 17 00:00:00 2001 From: Ujjansh Sundram Date: Fri, 24 Oct 2025 10:42:01 +0530 Subject: [PATCH 11/25] Updated files --- .../dynamic_maze_solver.py | 0 .../dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst | 2 +- tests/test_dynamic_maze_solver.py | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename PathPlanning/{BreadthFirstSearch => Dynamic_maze_Solver}/dynamic_maze_solver.py (100%) diff --git a/PathPlanning/BreadthFirstSearch/dynamic_maze_solver.py b/PathPlanning/Dynamic_maze_Solver/dynamic_maze_solver.py similarity index 100% rename from PathPlanning/BreadthFirstSearch/dynamic_maze_solver.py rename to PathPlanning/Dynamic_maze_Solver/dynamic_maze_solver.py diff --git a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst index e4570c03fa..acff4146a5 100644 --- a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst +++ b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst @@ -13,7 +13,7 @@ The visualizer dynamically updates a maze in real time while the solver attempts A sample animation frame: -.. image:: https://github.com/AtsushiSakai/PythonRoboticsGifs/raw/master/PathPlanning/Breadth-first_search/dynamic_maze_solver/animation.gif +.. image:: https://github.com/AtsushiSakai/PythonRoboticsGifs/raw/master/PathPlanning/Dynamic_maze_solver/animation.gif Algorithmic Background ---------------------- diff --git a/tests/test_dynamic_maze_solver.py b/tests/test_dynamic_maze_solver.py index bfb3d73c93..e138a6785e 100644 --- a/tests/test_dynamic_maze_solver.py +++ b/tests/test_dynamic_maze_solver.py @@ -1,5 +1,5 @@ import conftest -from PathPlanning.BreadthFirstSearch.dynamic_maze_solver import MazeVisualizer +from PathPlanning.Dynamic_maze_Solver.dynamic_maze_solver import MazeVisualizer def test_bfs_finds_path(): From acee7b6aba747fe9d15932e3cb3564acd43c31bc Mon Sep 17 00:00:00 2001 From: Ujjansh Sundram Date: Fri, 24 Oct 2025 10:46:32 +0530 Subject: [PATCH 12/25] updated link --- .../dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst index acff4146a5..bebf07a7cf 100644 --- a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst +++ b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst @@ -13,7 +13,7 @@ The visualizer dynamically updates a maze in real time while the solver attempts A sample animation frame: -.. image:: https://github.com/AtsushiSakai/PythonRoboticsGifs/raw/master/PathPlanning/Dynamic_maze_solver/animation.gif +.. image:: https://github.com/AtsushiSakai/PythonRoboticsGifs/raw/master/PathPlanning/Dynamic_maze_Solver/animation.gif Algorithmic Background ---------------------- From 63303e55f736ddce4862d7dc979a639a894fd55e Mon Sep 17 00:00:00 2001 From: Ujjansh Sundram Date: Fri, 24 Oct 2025 11:08:06 +0530 Subject: [PATCH 13/25] update file name --- .../dynamic_maze_solver.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename PathPlanning/{Dynamic_maze_Solver => DynamicMazeSolver}/dynamic_maze_solver.py (100%) diff --git a/PathPlanning/Dynamic_maze_Solver/dynamic_maze_solver.py b/PathPlanning/DynamicMazeSolver/dynamic_maze_solver.py similarity index 100% rename from PathPlanning/Dynamic_maze_Solver/dynamic_maze_solver.py rename to PathPlanning/DynamicMazeSolver/dynamic_maze_solver.py From 71e78ae73ad38431e36544600b32e6436c090304 Mon Sep 17 00:00:00 2001 From: Ujjansh Sundram Date: Fri, 24 Oct 2025 13:04:44 +0530 Subject: [PATCH 14/25] updared typo --- .../dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst index bebf07a7cf..f47c9c9802 100644 --- a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst +++ b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst @@ -13,7 +13,7 @@ The visualizer dynamically updates a maze in real time while the solver attempts A sample animation frame: -.. image:: https://github.com/AtsushiSakai/PythonRoboticsGifs/raw/master/PathPlanning/Dynamic_maze_Solver/animation.gif +.. image:: https://github.com/AtsushiSakai/PythonRoboticsGifs/raw/master/PathPlanning/DynamicMazeSolver/animation.gif Algorithmic Background ---------------------- From ce51ed32048acf6c211486d6144683665ce9c29a Mon Sep 17 00:00:00 2001 From: Ujjansh Sundram Date: Fri, 24 Oct 2025 13:26:10 +0530 Subject: [PATCH 15/25] updated the test file --- tests/test_dynamic_maze_solver.py | 43 +++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/tests/test_dynamic_maze_solver.py b/tests/test_dynamic_maze_solver.py index e138a6785e..d6e4154c2e 100644 --- a/tests/test_dynamic_maze_solver.py +++ b/tests/test_dynamic_maze_solver.py @@ -1,5 +1,5 @@ import conftest -from PathPlanning.Dynamic_maze_Solver.dynamic_maze_solver import MazeVisualizer +from PathPlanning.DynamicMazeSolver import dynamic_maze_solver as m def test_bfs_finds_path(): @@ -13,7 +13,8 @@ def test_bfs_finds_path(): start = (0, 0) target = (2, 2) - viz = MazeVisualizer(maze, start, target) + # module `dynamic_maze_solver` exposes `MazeVisualizer` class + viz = m.MazeVisualizer(maze, start, target) path, visited = viz._bfs() @@ -22,5 +23,43 @@ def test_bfs_finds_path(): assert path[-1] == target +def test_bfs_unreachable_target(): + # target is enclosed by walls + maze = [ + [0, 1, 0], + [1, 1, 1], + [0, 1, 0] + ] + + start = (0, 0) + target = (2, 2) + + viz = m.MazeVisualizer(maze, start, target) + + path, visited = viz._bfs() + + assert path is None + assert target not in visited + + +def test_bfs_start_equals_target(): + # trivial case where start == target + maze = [ + [0, 0, 0], + [0, 0, 0], + [0, 0, 0] + ] + + start = (1, 1) + target = start + + viz = m.MazeVisualizer(maze, start, target) + + path, visited = viz._bfs() + + assert path is not None + assert path == [start] + + if __name__ == '__main__': conftest.run_this_test(__file__) From 09c0508d70e3f0c97fec6ccd46b5da193460ff9c Mon Sep 17 00:00:00 2001 From: Ujjansh Sundram Date: Sat, 25 Oct 2025 15:08:16 +0530 Subject: [PATCH 16/25] update the code link --- .../dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst index f47c9c9802..62386c656f 100644 --- a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst +++ b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst @@ -18,20 +18,21 @@ A sample animation frame: Algorithmic Background ---------------------- -### Breadth-First Search (BFS) +Breadth-First Search (BFS) +-------------------------- The BFS algorithm is a graph traversal method that explores nodes in layers, guaranteeing the shortest path in an unweighted grid. .. math:: - M = \{ (i, j) \mid 0 \leq i < R, 0 \leq j < C \} + M = \\{ (i, j) \mid 0 \leq i < R, 0 \leq j < C \\} -... +where R and C denote the number of rows and columns in the grid. Code Link +++++++++ -.. automodule:: PathPlanning.BreadthFirstSearch.dynamic_maze_solver +.. automodule:: PathPlanning.DynamicMazeSolver.dynamic_maze_solver References From 0210a0ec3516f7a42e36759802d58c3b97d35cca Mon Sep 17 00:00:00 2001 From: Ujjansh Sundram Date: Sat, 25 Oct 2025 15:42:18 +0530 Subject: [PATCH 17/25] updated the pathplanning file --- docs/modules/5_path_planning/path_planning_main.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/modules/5_path_planning/path_planning_main.rst b/docs/modules/5_path_planning/path_planning_main.rst index 0c84a19c22..a938be650e 100644 --- a/docs/modules/5_path_planning/path_planning_main.rst +++ b/docs/modules/5_path_planning/path_planning_main.rst @@ -12,6 +12,7 @@ Path planning is the ability of a robot to search feasible and efficient path to dynamic_window_approach/dynamic_window_approach bugplanner/bugplanner grid_base_search/grid_base_search + dynamic_bfs_maze_Solver/Dynamic_maze_Solver time_based_grid_search/time_based_grid_search model_predictive_trajectory_generator/model_predictive_trajectory_generator state_lattice_planner/state_lattice_planner From e4cb7d9dc14cf14dfd5eeb66c003fea55d93c158 Mon Sep 17 00:00:00 2001 From: Ujjansh Sundram Date: Sat, 25 Oct 2025 15:54:00 +0530 Subject: [PATCH 18/25] update the .rst files --- .../dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst | 4 ++-- docs/modules/5_path_planning/path_planning_main.rst | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst index 62386c656f..de877cf9ff 100644 --- a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst +++ b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst @@ -25,12 +25,12 @@ The BFS algorithm is a graph traversal method that explores nodes in layers, gua .. math:: - M = \\{ (i, j) \mid 0 \leq i < R, 0 \leq j < C \\} + M = \\\{ (i, j) \mid 0 \leq i < R, 0 \leq j < C \\\} where R and C denote the number of rows and columns in the grid. Code Link -+++++++++ +++++++++ .. automodule:: PathPlanning.DynamicMazeSolver.dynamic_maze_solver diff --git a/docs/modules/5_path_planning/path_planning_main.rst b/docs/modules/5_path_planning/path_planning_main.rst index a938be650e..c302d1e993 100644 --- a/docs/modules/5_path_planning/path_planning_main.rst +++ b/docs/modules/5_path_planning/path_planning_main.rst @@ -12,7 +12,7 @@ Path planning is the ability of a robot to search feasible and efficient path to dynamic_window_approach/dynamic_window_approach bugplanner/bugplanner grid_base_search/grid_base_search - dynamic_bfs_maze_Solver/Dynamic_maze_Solver + dynamic_bfs_maze_solver/dynamic_maze_solver time_based_grid_search/time_based_grid_search model_predictive_trajectory_generator/model_predictive_trajectory_generator state_lattice_planner/state_lattice_planner From e228183f88c8bee013cf0a8665f73cc9e540d030 Mon Sep 17 00:00:00 2001 From: Ujjansh Sundram Date: Sat, 25 Oct 2025 16:03:24 +0530 Subject: [PATCH 19/25] update .rst files --- .../dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst | 2 +- .../dynamic_bfs_maze_Solver/dynamic_maze_solver_index.rst | 6 ++++++ docs/modules/5_path_planning/path_planning_main.rst | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 docs/modules/5_path_planning/dynamic_bfs_maze_Solver/dynamic_maze_solver_index.rst diff --git a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst index de877cf9ff..7106df53b9 100644 --- a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst +++ b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst @@ -25,7 +25,7 @@ The BFS algorithm is a graph traversal method that explores nodes in layers, gua .. math:: - M = \\\{ (i, j) \mid 0 \leq i < R, 0 \leq j < C \\\} + M = \{ (i, j) \mid 0 \leq i < R, 0 \leq j < C \} where R and C denote the number of rows and columns in the grid. diff --git a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/dynamic_maze_solver_index.rst b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/dynamic_maze_solver_index.rst new file mode 100644 index 0000000000..dc8e27a5fb --- /dev/null +++ b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/dynamic_maze_solver_index.rst @@ -0,0 +1,6 @@ +Dynamic Maze Solver (index) +=========================== + +This is the documentation index page for the Dynamic Maze Solver example. It mirrors the original `Dynamic_maze_Solver.rst` content but uses a distinct filename to avoid case-only renames on case-insensitive filesystems. + +.. include:: dynamic_maze_solver.rst diff --git a/docs/modules/5_path_planning/path_planning_main.rst b/docs/modules/5_path_planning/path_planning_main.rst index c302d1e993..41233fbbae 100644 --- a/docs/modules/5_path_planning/path_planning_main.rst +++ b/docs/modules/5_path_planning/path_planning_main.rst @@ -12,7 +12,7 @@ Path planning is the ability of a robot to search feasible and efficient path to dynamic_window_approach/dynamic_window_approach bugplanner/bugplanner grid_base_search/grid_base_search - dynamic_bfs_maze_solver/dynamic_maze_solver + dynamic_bfs_maze_solver/dynamic_maze_solver_index time_based_grid_search/time_based_grid_search model_predictive_trajectory_generator/model_predictive_trajectory_generator state_lattice_planner/state_lattice_planner From 4975e29bce849c07a92a1757dec1551e1c59d4d7 Mon Sep 17 00:00:00 2001 From: Ujjansh Sundram Date: Sun, 26 Oct 2025 01:03:25 +0530 Subject: [PATCH 20/25] update the rst files --- .../dynamic_bfs_maze_Solver/dynamic_maze_solver_index.rst | 6 ------ .../dynamic_bfs_maze_solver_main.rst} | 0 docs/modules/5_path_planning/path_planning_main.rst | 2 +- 3 files changed, 1 insertion(+), 7 deletions(-) delete mode 100644 docs/modules/5_path_planning/dynamic_bfs_maze_Solver/dynamic_maze_solver_index.rst rename docs/modules/5_path_planning/{dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst => dynamic_bfs_maze_solver/dynamic_bfs_maze_solver_main.rst} (100%) diff --git a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/dynamic_maze_solver_index.rst b/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/dynamic_maze_solver_index.rst deleted file mode 100644 index dc8e27a5fb..0000000000 --- a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/dynamic_maze_solver_index.rst +++ /dev/null @@ -1,6 +0,0 @@ -Dynamic Maze Solver (index) -=========================== - -This is the documentation index page for the Dynamic Maze Solver example. It mirrors the original `Dynamic_maze_Solver.rst` content but uses a distinct filename to avoid case-only renames on case-insensitive filesystems. - -.. include:: dynamic_maze_solver.rst diff --git a/docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst b/docs/modules/5_path_planning/dynamic_bfs_maze_solver/dynamic_bfs_maze_solver_main.rst similarity index 100% rename from docs/modules/5_path_planning/dynamic_bfs_maze_Solver/Dynamic_maze_Solver.rst rename to docs/modules/5_path_planning/dynamic_bfs_maze_solver/dynamic_bfs_maze_solver_main.rst diff --git a/docs/modules/5_path_planning/path_planning_main.rst b/docs/modules/5_path_planning/path_planning_main.rst index 41233fbbae..26f386d15e 100644 --- a/docs/modules/5_path_planning/path_planning_main.rst +++ b/docs/modules/5_path_planning/path_planning_main.rst @@ -12,7 +12,7 @@ Path planning is the ability of a robot to search feasible and efficient path to dynamic_window_approach/dynamic_window_approach bugplanner/bugplanner grid_base_search/grid_base_search - dynamic_bfs_maze_solver/dynamic_maze_solver_index + dynamic_bfs_maze_solver/dynamic_bfs_maze_solver time_based_grid_search/time_based_grid_search model_predictive_trajectory_generator/model_predictive_trajectory_generator state_lattice_planner/state_lattice_planner From 3cc3d22033b85f1e476442810fc6de12d59d044f Mon Sep 17 00:00:00 2001 From: Ujjansh Sundram Date: Sun, 26 Oct 2025 01:06:47 +0530 Subject: [PATCH 21/25] fix error CI --- .../dynamic_bfs_maze_solver/dynamic_bfs_maze_solver_main.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/modules/5_path_planning/dynamic_bfs_maze_solver/dynamic_bfs_maze_solver_main.rst b/docs/modules/5_path_planning/dynamic_bfs_maze_solver/dynamic_bfs_maze_solver_main.rst index 7106df53b9..fa6de015dc 100644 --- a/docs/modules/5_path_planning/dynamic_bfs_maze_solver/dynamic_bfs_maze_solver_main.rst +++ b/docs/modules/5_path_planning/dynamic_bfs_maze_solver/dynamic_bfs_maze_solver_main.rst @@ -30,7 +30,7 @@ The BFS algorithm is a graph traversal method that explores nodes in layers, gua where R and C denote the number of rows and columns in the grid. Code Link -++++++++ ++++++++++ .. automodule:: PathPlanning.DynamicMazeSolver.dynamic_maze_solver From 89192f9ee6b09ccd93e880d2c235b59a5e084ab8 Mon Sep 17 00:00:00 2001 From: Ujjansh Sundram Date: Sun, 26 Oct 2025 01:34:03 +0530 Subject: [PATCH 22/25] fix the rendering status --- PathPlanning/DynamicMazeSolver/__init__.py | 5 +++++ .../dynamic_bfs_maze_solver/dynamic_bfs_maze_solver_main.rst | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 PathPlanning/DynamicMazeSolver/__init__.py diff --git a/PathPlanning/DynamicMazeSolver/__init__.py b/PathPlanning/DynamicMazeSolver/__init__.py new file mode 100644 index 0000000000..cf9fecea57 --- /dev/null +++ b/PathPlanning/DynamicMazeSolver/__init__.py @@ -0,0 +1,5 @@ +"""Dynamic Maze Solver module.""" + +from .dynamic_maze_solver import MazeVisualizer + +__all__ = ['MazeVisualizer'] diff --git a/docs/modules/5_path_planning/dynamic_bfs_maze_solver/dynamic_bfs_maze_solver_main.rst b/docs/modules/5_path_planning/dynamic_bfs_maze_solver/dynamic_bfs_maze_solver_main.rst index fa6de015dc..2a4e1250e6 100644 --- a/docs/modules/5_path_planning/dynamic_bfs_maze_solver/dynamic_bfs_maze_solver_main.rst +++ b/docs/modules/5_path_planning/dynamic_bfs_maze_solver/dynamic_bfs_maze_solver_main.rst @@ -32,7 +32,10 @@ where R and C denote the number of rows and columns in the grid. Code Link +++++++++ -.. automodule:: PathPlanning.DynamicMazeSolver.dynamic_maze_solver +.. autoclass:: PathPlanning.DynamicMazeSolver.dynamic_maze_solver.MazeVisualizer + :members: + :undoc-members: + :show-inheritance: References From 5e765e495a3b0e22f0e838e3811107c9b28d3a49 Mon Sep 17 00:00:00 2001 From: Ujjansh Sundram Date: Sun, 26 Oct 2025 01:43:23 +0530 Subject: [PATCH 23/25] fix gif rendering issues --- .../dynamic_bfs_maze_solver_main.rst | 72 ++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/docs/modules/5_path_planning/dynamic_bfs_maze_solver/dynamic_bfs_maze_solver_main.rst b/docs/modules/5_path_planning/dynamic_bfs_maze_solver/dynamic_bfs_maze_solver_main.rst index 2a4e1250e6..131b70bb9c 100644 --- a/docs/modules/5_path_planning/dynamic_bfs_maze_solver/dynamic_bfs_maze_solver_main.rst +++ b/docs/modules/5_path_planning/dynamic_bfs_maze_solver/dynamic_bfs_maze_solver_main.rst @@ -11,9 +11,33 @@ Overview This example demonstrates a **dynamic maze-solving algorithm** based on the **Breadth-First Search (BFS)** strategy. The visualizer dynamically updates a maze in real time while the solver attempts to reach a moving target. -A sample animation frame: +Features +~~~~~~~~ + +- **Dynamic Maze Solving**: Real-time BFS pathfinding on a grid +- **Moving Target**: The target position changes dynamically during the search +- **Evolving Obstacles**: Obstacles can appear/disappear randomly during execution +- **Visual Feedback**: + + - Black dots represent obstacles + - Solver position is shown with live updates + - Path visualization shows the solution trajectory + - Breadcrumb trail displays the solver's movement history + +Sample Animation +~~~~~~~~~~~~~~~~ + +A sample animation frame from the dynamic maze solver: .. image:: https://github.com/AtsushiSakai/PythonRoboticsGifs/raw/master/PathPlanning/DynamicMazeSolver/animation.gif + :width: 600 + :align: center + +The visualization shows: + - **Grid Layout**: The maze environment with obstacles (black points) + - **Target**: Red/green markers indicating the goal position + - **Path**: The solution path traced by the BFS algorithm + - **Real-time Updates**: Continuous animation showing the solver in action Algorithmic Background ---------------------- @@ -29,6 +53,52 @@ The BFS algorithm is a graph traversal method that explores nodes in layers, gua where R and C denote the number of rows and columns in the grid. +Usage Example +~~~~~~~~~~~~~ + +To run the dynamic maze solver: + +.. code-block:: python + + from PathPlanning.DynamicMazeSolver.dynamic_maze_solver import MazeVisualizer + + # Define the maze (0 = free space, 1 = obstacle) + initial_maze = [ + [0, 1, 0, 0, 0, 0, 0, 0, 1, 0], + [0, 1, 0, 1, 1, 0, 1, 0, 1, 0], + [0, 0, 0, 1, 0, 0, 1, 0, 0, 0], + [0, 1, 0, 1, 0, 1, 1, 1, 1, 0], + [0, 1, 0, 0, 0, 0, 0, 0, 1, 0], + [0, 1, 1, 1, 1, 1, 1, 0, 1, 0], + [0, 0, 0, 0, 0, 0, 1, 0, 0, 0], + [1, 1, 1, 1, 0, 1, 1, 1, 1, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + ] + + # Set start and end points + start_point = (0, 0) + end_point = (8, 9) + + # Create visualizer and run + visualizer = MazeVisualizer(initial_maze, start_point, end_point) + visualizer.run() + +Expected Output +~~~~~~~~~~~~~~~ + +When you run the solver, you will see an interactive matplotlib window displaying: + +- **Grid with Obstacles**: Black points representing walls and obstacles +- **Start Position**: Marked at the initial coordinates +- **Target Position**: The goal location (changes dynamically) +- **Solver Path**: The trajectory computed by BFS algorithm +- **Animation**: Real-time visualization of the pathfinding process +- **Status Bar**: Shows frame count and current path length + +The animation continues until either: + - The solver reaches the target position (success) + - The maximum number of frames is reached (500 frames by default) + Code Link +++++++++ From 559a404c65f13b5cc13f25609c47aee2ceab3417 Mon Sep 17 00:00:00 2001 From: Ujjansh Sundram Date: Sun, 26 Oct 2025 14:52:00 +0530 Subject: [PATCH 24/25] update file path --- .../dynamic_bfs_maze_solver_main.rst | 116 ------------------ .../grid_base_search_main.rst | 30 +++++ .../5_path_planning/path_planning_main.rst | 1 - 3 files changed, 30 insertions(+), 117 deletions(-) delete mode 100644 docs/modules/5_path_planning/dynamic_bfs_maze_solver/dynamic_bfs_maze_solver_main.rst diff --git a/docs/modules/5_path_planning/dynamic_bfs_maze_solver/dynamic_bfs_maze_solver_main.rst b/docs/modules/5_path_planning/dynamic_bfs_maze_solver/dynamic_bfs_maze_solver_main.rst deleted file mode 100644 index 131b70bb9c..0000000000 --- a/docs/modules/5_path_planning/dynamic_bfs_maze_solver/dynamic_bfs_maze_solver_main.rst +++ /dev/null @@ -1,116 +0,0 @@ -Dynamic Maze Solver using Breadth-First Search (BFS) -==================================================== - -.. contents:: Table of Contents - :local: - :depth: 2 - -Overview --------- - -This example demonstrates a **dynamic maze-solving algorithm** based on the **Breadth-First Search (BFS)** strategy. -The visualizer dynamically updates a maze in real time while the solver attempts to reach a moving target. - -Features -~~~~~~~~ - -- **Dynamic Maze Solving**: Real-time BFS pathfinding on a grid -- **Moving Target**: The target position changes dynamically during the search -- **Evolving Obstacles**: Obstacles can appear/disappear randomly during execution -- **Visual Feedback**: - - - Black dots represent obstacles - - Solver position is shown with live updates - - Path visualization shows the solution trajectory - - Breadcrumb trail displays the solver's movement history - -Sample Animation -~~~~~~~~~~~~~~~~ - -A sample animation frame from the dynamic maze solver: - -.. image:: https://github.com/AtsushiSakai/PythonRoboticsGifs/raw/master/PathPlanning/DynamicMazeSolver/animation.gif - :width: 600 - :align: center - -The visualization shows: - - **Grid Layout**: The maze environment with obstacles (black points) - - **Target**: Red/green markers indicating the goal position - - **Path**: The solution path traced by the BFS algorithm - - **Real-time Updates**: Continuous animation showing the solver in action - -Algorithmic Background ----------------------- - -Breadth-First Search (BFS) --------------------------- - -The BFS algorithm is a graph traversal method that explores nodes in layers, guaranteeing the shortest path in an unweighted grid. - -.. math:: - - M = \{ (i, j) \mid 0 \leq i < R, 0 \leq j < C \} - -where R and C denote the number of rows and columns in the grid. - -Usage Example -~~~~~~~~~~~~~ - -To run the dynamic maze solver: - -.. code-block:: python - - from PathPlanning.DynamicMazeSolver.dynamic_maze_solver import MazeVisualizer - - # Define the maze (0 = free space, 1 = obstacle) - initial_maze = [ - [0, 1, 0, 0, 0, 0, 0, 0, 1, 0], - [0, 1, 0, 1, 1, 0, 1, 0, 1, 0], - [0, 0, 0, 1, 0, 0, 1, 0, 0, 0], - [0, 1, 0, 1, 0, 1, 1, 1, 1, 0], - [0, 1, 0, 0, 0, 0, 0, 0, 1, 0], - [0, 1, 1, 1, 1, 1, 1, 0, 1, 0], - [0, 0, 0, 0, 0, 0, 1, 0, 0, 0], - [1, 1, 1, 1, 0, 1, 1, 1, 1, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - ] - - # Set start and end points - start_point = (0, 0) - end_point = (8, 9) - - # Create visualizer and run - visualizer = MazeVisualizer(initial_maze, start_point, end_point) - visualizer.run() - -Expected Output -~~~~~~~~~~~~~~~ - -When you run the solver, you will see an interactive matplotlib window displaying: - -- **Grid with Obstacles**: Black points representing walls and obstacles -- **Start Position**: Marked at the initial coordinates -- **Target Position**: The goal location (changes dynamically) -- **Solver Path**: The trajectory computed by BFS algorithm -- **Animation**: Real-time visualization of the pathfinding process -- **Status Bar**: Shows frame count and current path length - -The animation continues until either: - - The solver reaches the target position (success) - - The maximum number of frames is reached (500 frames by default) - -Code Link -+++++++++ - -.. autoclass:: PathPlanning.DynamicMazeSolver.dynamic_maze_solver.MazeVisualizer - :members: - :undoc-members: - :show-inheritance: - - -References ----------- - -- **Algorithm:** `Breadth-First Search (BFS) `_ -- **Visualization:** Matplotlib animation -- **Maze Solver:** `AI Maze BFS Example `_ diff --git a/docs/modules/5_path_planning/grid_base_search/grid_base_search_main.rst b/docs/modules/5_path_planning/grid_base_search/grid_base_search_main.rst index c4aa6882aa..d5d6ae1bd8 100644 --- a/docs/modules/5_path_planning/grid_base_search/grid_base_search_main.rst +++ b/docs/modules/5_path_planning/grid_base_search/grid_base_search_main.rst @@ -16,6 +16,36 @@ Code Link .. autofunction:: PathPlanning.BreadthFirstSearch.breadth_first_search.BreadthFirstSearchPlanner +Dynamic Maze Solver using Breadth-First Search (BFS) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This is a dynamic maze solver using Breadth-First Search algorithm with real-time visualization. +The visualizer dynamically updates a maze in real time while the solver attempts to reach a moving target. + +Features: + +- **Dynamic Maze Solving**: Real-time BFS pathfinding on a grid +- **Moving Target**: The target position changes dynamically during the search +- **Evolving Obstacles**: Obstacles can appear/disappear randomly during execution +- **Visual Feedback**: Live animation showing the pathfinding process + +.. image:: https://github.com/AtsushiSakai/PythonRoboticsGifs/raw/master/PathPlanning/DynamicMazeSolver/animation.gif + +In the animation, the visualizer displays: + - Black points representing obstacles + - Solver position with live updates + - Path visualization showing the solution trajectory + - Breadcrumb trail displaying the solver's movement history + +Code Link ++++++++++++++ + +.. autoclass:: PathPlanning.DynamicMazeSolver.dynamic_maze_solver.MazeVisualizer + :members: + :undoc-members: + :show-inheritance: + + Depth First Search ~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/modules/5_path_planning/path_planning_main.rst b/docs/modules/5_path_planning/path_planning_main.rst index 26f386d15e..0c84a19c22 100644 --- a/docs/modules/5_path_planning/path_planning_main.rst +++ b/docs/modules/5_path_planning/path_planning_main.rst @@ -12,7 +12,6 @@ Path planning is the ability of a robot to search feasible and efficient path to dynamic_window_approach/dynamic_window_approach bugplanner/bugplanner grid_base_search/grid_base_search - dynamic_bfs_maze_solver/dynamic_bfs_maze_solver time_based_grid_search/time_based_grid_search model_predictive_trajectory_generator/model_predictive_trajectory_generator state_lattice_planner/state_lattice_planner From ccfa6f33e2cade42c4e90b703ad88c0247c41c36 Mon Sep 17 00:00:00 2001 From: Ujjansh Sundram Date: Mon, 27 Oct 2025 15:46:19 +0530 Subject: [PATCH 25/25] updated the reference point --- .../grid_base_search/grid_base_search_main.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/modules/5_path_planning/grid_base_search/grid_base_search_main.rst b/docs/modules/5_path_planning/grid_base_search/grid_base_search_main.rst index d5d6ae1bd8..078ac64122 100644 --- a/docs/modules/5_path_planning/grid_base_search/grid_base_search_main.rst +++ b/docs/modules/5_path_planning/grid_base_search/grid_base_search_main.rst @@ -45,6 +45,13 @@ Code Link :undoc-members: :show-inheritance: +References +---------- + +- **Algorithm:** `Breadth-First Search (BFS) `_ +- **Visualization:** Matplotlib animation +- **Maze Solver:** `AI Maze BFS Example `_ + Depth First Search ~~~~~~~~~~~~~~~~~~~~