From 25a6f68ea72c11f0ae684e9a706906e91a0c56b4 Mon Sep 17 00:00:00 2001 From: Shisato Yano Date: Sun, 25 Oct 2026 22:27:46 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Skip=20the=20search=20GIF?= =?UTF-8?q?=20in=20path=20planning=20smoke=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 7 path planning simulations always passed gif_name to the planner, so every test run encoded multi-MB search GIFs and overwrote the committed demo GIFs. Pass gif_name only when show_plot is true, like aco/elastic_bands, and make the planners return early when gif_name is None. Before this, None made 6 planners call plt.show() and made informed RRT* fail with Path(None). path.json still changes after tests because RRT planners are unseeded; that is handled in #90. Closes #87 Co-Authored-By: Claude Opus 5.5 --- .../plan/astar/astar_path_planner.py | 18 ++++---- .../astar_bidirectional_path_planner.py | 18 ++++---- .../plan/dijkstra/dijkstra_path_planner.py | 42 +++++++++---------- .../informed_rrt_star_path_planner.py | 2 +- src/components/plan/rrt/rrt_path_planner.py | 18 ++++---- .../plan/rrt_star/rrt_star_path_planner.py | 18 ++++---- .../rrt_star_bidirectional_path_planner.py | 18 ++++---- .../astar_bidirectional_path_planning.py | 2 +- .../astar_path_planning.py | 2 +- .../dijkstra_path_planning.py | 2 +- .../informed_rrt_star_path_planning.py | 2 +- .../rrt_path_planning/rrt_path_planning.py | 2 +- .../rrt_star_bidirectional_path_planning.py | 2 +- .../rrt_star_path_planning.py | 2 +- 14 files changed, 74 insertions(+), 74 deletions(-) diff --git a/src/components/plan/astar/astar_path_planner.py b/src/components/plan/astar/astar_path_planner.py index 4094a864..dbc8a5f5 100644 --- a/src/components/plan/astar/astar_path_planner.py +++ b/src/components/plan/astar/astar_path_planner.py @@ -203,6 +203,9 @@ def save_path(self, path, filename): def visualize_search(self, gif_name=None): + if gif_name is None: + return + print(f"Exploring {len(self.explored_nodes)} nodes.") if not self.explored_nodes: print("Error: No explored nodes. Ensure search() is executed before visualize_search().") @@ -225,15 +228,12 @@ def visualize_search(self, gif_name=None): repeat=False, ) - if gif_name is not None: - try: - print("Saving animation...") - self.anime.save(gif_name, writer="pillow") - print("Animation saved successfully.") - except Exception as e: - print(f"Error saving animation: {e}") - else: - plt.show() + try: + print("Saving animation...") + self.anime.save(gif_name, writer="pillow") + print("Animation saved successfully.") + except Exception as e: + print(f"Error saving animation: {e}") # clear existing plot and close existing figure plt.clf() diff --git a/src/components/plan/astar_bidirectional/astar_bidirectional_path_planner.py b/src/components/plan/astar_bidirectional/astar_bidirectional_path_planner.py index 4d0d83d7..f5db3851 100644 --- a/src/components/plan/astar_bidirectional/astar_bidirectional_path_planner.py +++ b/src/components/plan/astar_bidirectional/astar_bidirectional_path_planner.py @@ -357,6 +357,9 @@ def save_path(self, path, filename): json.dump(path, f) def visualize_search(self, gif_name=None): + if gif_name is None: + return + print(f"Exploring {len(self.explored_nodes)} nodes.") if not self.explored_nodes: print("Error: No explored nodes. Ensure search() is executed before visualize_search().") @@ -377,15 +380,12 @@ def visualize_search(self, gif_name=None): repeat=False, ) - if gif_name is not None: - try: - print("Saving animation...") - self.anime.save(gif_name, writer="pillow") - print("Animation saved successfully.") - except Exception as e: - print(f"Error saving animation: {e}") - else: - plt.show() + try: + print("Saving animation...") + self.anime.save(gif_name, writer="pillow") + print("Animation saved successfully.") + except Exception as e: + print(f"Error saving animation: {e}") # clear existing plot and close existing figure plt.clf() diff --git a/src/components/plan/dijkstra/dijkstra_path_planner.py b/src/components/plan/dijkstra/dijkstra_path_planner.py index 99151d66..9222aec9 100644 --- a/src/components/plan/dijkstra/dijkstra_path_planner.py +++ b/src/components/plan/dijkstra/dijkstra_path_planner.py @@ -197,6 +197,9 @@ def save_path(self, path, filename): def visualize_search(self, gif_name=None): + if gif_name is None: + return + print(f"Exploring {len(self.explored_nodes)} nodes.") if not self.explored_nodes: print("Error: No explored nodes. Ensure search() is executed before visualize_search().") @@ -226,28 +229,25 @@ def visualize_search(self, gif_name=None): repeat=False, ) - if gif_name is not None: + try: + print("Saving animation...") + # Use FFmpeg writer if available for better memory efficiency try: - print("Saving animation...") - # Use FFmpeg writer if available for better memory efficiency - try: - self.anime.save(gif_name, writer="pillow", fps=20, - savefig_kwargs={'bbox_inches': 'tight', 'dpi': 100}) - except Exception: - # Fallback to pillow with reduced quality - self.anime.save(gif_name, writer="pillow") - print("Animation saved successfully.") - except Exception as e: - print(f"Error saving animation: {e}") - # Try saving as MP4 instead if GIF fails - try: - mp4_name = gif_name.replace('.gif', '.mp4') - self.anime.save(mp4_name, writer="ffmpeg", fps=20) - print(f"Saved as MP4 instead: {mp4_name}") - except Exception as e2: - print(f"Both GIF and MP4 saving failed: {e2}") - else: - plt.show() + self.anime.save(gif_name, writer="pillow", fps=20, + savefig_kwargs={'bbox_inches': 'tight', 'dpi': 100}) + except Exception: + # Fallback to pillow with reduced quality + self.anime.save(gif_name, writer="pillow") + print("Animation saved successfully.") + except Exception as e: + print(f"Error saving animation: {e}") + # Try saving as MP4 instead if GIF fails + try: + mp4_name = gif_name.replace('.gif', '.mp4') + self.anime.save(mp4_name, writer="ffmpeg", fps=20) + print(f"Saved as MP4 instead: {mp4_name}") + except Exception as e2: + print(f"Both GIF and MP4 saving failed: {e2}") # clear existing plot and close existing figure plt.clf() diff --git a/src/components/plan/informed_rrt_star/informed_rrt_star_path_planner.py b/src/components/plan/informed_rrt_star/informed_rrt_star_path_planner.py index 09122724..d8d9e788 100644 --- a/src/components/plan/informed_rrt_star/informed_rrt_star_path_planner.py +++ b/src/components/plan/informed_rrt_star/informed_rrt_star_path_planner.py @@ -320,7 +320,7 @@ def save_path(self, path): json.dump(path, f) def visualize_search(self, gif_name, frame_skip=3): - if not self.tree_edges: + if gif_name is None or not self.tree_edges: return Path(gif_name).parent.mkdir(parents=True, exist_ok=True) diff --git a/src/components/plan/rrt/rrt_path_planner.py b/src/components/plan/rrt/rrt_path_planner.py index e96ddb27..666c139f 100644 --- a/src/components/plan/rrt/rrt_path_planner.py +++ b/src/components/plan/rrt/rrt_path_planner.py @@ -286,6 +286,9 @@ def save_path(self, path, filename): def visualize_search(self, gif_name=None): + if gif_name is None: + return + print(f"Exploring {len(self.explored_nodes)} nodes.") if not self.explored_nodes: print("Error: No explored nodes. Ensure search() is executed before visualize_search().") @@ -308,15 +311,12 @@ def visualize_search(self, gif_name=None): repeat=False, ) - if gif_name is not None: - try: - print("Saving animation...") - self.anime.save(gif_name, writer="pillow") - print("Animation saved successfully.") - except Exception as e: - print(f"Error saving animation: {e}") - else: - plt.show() + try: + print("Saving animation...") + self.anime.save(gif_name, writer="pillow") + print("Animation saved successfully.") + except Exception as e: + print(f"Error saving animation: {e}") # clear existing plot and close existing figure plt.clf() diff --git a/src/components/plan/rrt_star/rrt_star_path_planner.py b/src/components/plan/rrt_star/rrt_star_path_planner.py index 74feb733..0882ca9b 100644 --- a/src/components/plan/rrt_star/rrt_star_path_planner.py +++ b/src/components/plan/rrt_star/rrt_star_path_planner.py @@ -397,6 +397,9 @@ def save_path(self, path, filename): json.dump(path, f) def visualize_search(self, gif_name=None): + if gif_name is None: + return + print(f"Exploring {len(self.explored_nodes)} nodes.") if not self.explored_nodes: print("Error: No explored nodes. Ensure search() is executed before visualize_search().") @@ -417,15 +420,12 @@ def visualize_search(self, gif_name=None): repeat=False, ) - if gif_name is not None: - try: - print("Saving animation...") - self.anime.save(gif_name, writer="pillow") - print("Animation saved successfully.") - except Exception as e: - print(f"Error saving animation: {e}") - else: - plt.show() + try: + print("Saving animation...") + self.anime.save(gif_name, writer="pillow") + print("Animation saved successfully.") + except Exception as e: + print(f"Error saving animation: {e}") plt.clf() plt.close() diff --git a/src/components/plan/rrt_star_bidirectional/rrt_star_bidirectional_path_planner.py b/src/components/plan/rrt_star_bidirectional/rrt_star_bidirectional_path_planner.py index 24730941..ebd5a1ed 100644 --- a/src/components/plan/rrt_star_bidirectional/rrt_star_bidirectional_path_planner.py +++ b/src/components/plan/rrt_star_bidirectional/rrt_star_bidirectional_path_planner.py @@ -379,6 +379,9 @@ def save_path(self, path, filename): json.dump(path, f) def visualize_search(self, gif_name=None): + if gif_name is None: + return + print(f"Exploring {len(self.explored_nodes)} nodes.") if not self.explored_nodes: print("Error: No explored nodes. Ensure search() is executed before visualize_search().") @@ -399,15 +402,12 @@ def visualize_search(self, gif_name=None): repeat=False, ) - if gif_name is not None: - try: - print("Saving animation...") - self.anime.save(gif_name, writer="pillow") - print("Animation saved successfully.") - except Exception as e: - print(f"Error saving animation: {e}") - else: - plt.show() + try: + print("Saving animation...") + self.anime.save(gif_name, writer="pillow") + print("Animation saved successfully.") + except Exception as e: + print(f"Error saving animation: {e}") plt.clf() plt.close() diff --git a/src/simulations/path_planning/astar_bidirectional_path_planning/astar_bidirectional_path_planning.py b/src/simulations/path_planning/astar_bidirectional_path_planning/astar_bidirectional_path_planning.py index 8344b4d7..41b94fcf 100644 --- a/src/simulations/path_planning/astar_bidirectional_path_planning/astar_bidirectional_path_planning.py +++ b/src/simulations/path_planning/astar_bidirectional_path_planning/astar_bidirectional_path_planning.py @@ -112,7 +112,7 @@ def main(): x_lim=x_lim, y_lim=y_lim, path_filename=path_filename, - gif_name=search_gif_path, + gif_name=search_gif_path if show_plot else None, ) # Load sparse path from json file diff --git a/src/simulations/path_planning/astar_path_planning/astar_path_planning.py b/src/simulations/path_planning/astar_path_planning/astar_path_planning.py index 52c34560..573b48a9 100644 --- a/src/simulations/path_planning/astar_path_planning/astar_path_planning.py +++ b/src/simulations/path_planning/astar_path_planning/astar_path_planning.py @@ -77,7 +77,7 @@ def main(): occ_grid.save_map() # Easy Goal = (50,22) # Hard Goal = (50,-10) - planner = AStarPathPlanner((0, 0), (50, -10), map_path, weight=5.0, x_lim=x_lim, y_lim=y_lim, path_filename=path_filename, gif_name=search_gif_path) + planner = AStarPathPlanner((0, 0), (50, -10), map_path, weight=5.0, x_lim=x_lim, y_lim=y_lim, path_filename=path_filename, gif_name=search_gif_path if show_plot else None) # Load sparse path from json file with open(path_filename, 'r') as f: diff --git a/src/simulations/path_planning/dijkstra_path_planning/dijkstra_path_planning.py b/src/simulations/path_planning/dijkstra_path_planning/dijkstra_path_planning.py index f80d1ae2..0988e996 100644 --- a/src/simulations/path_planning/dijkstra_path_planning/dijkstra_path_planning.py +++ b/src/simulations/path_planning/dijkstra_path_planning/dijkstra_path_planning.py @@ -77,7 +77,7 @@ def main(): occ_grid.save_map() # Easy Goal = (50,22) # Hard Goal = (50,-10) - planner = DijkstraPathPlanner((0, 0), (50, -10), map_path, x_lim=x_lim, y_lim=y_lim, path_filename=path_filename, gif_name=search_gif_path) + planner = DijkstraPathPlanner((0, 0), (50, -10), map_path, x_lim=x_lim, y_lim=y_lim, path_filename=path_filename, gif_name=search_gif_path if show_plot else None) # Load sparse path from json file with open(path_filename, 'r') as f: diff --git a/src/simulations/path_planning/informed_rrt_star_path_planning/informed_rrt_star_path_planning.py b/src/simulations/path_planning/informed_rrt_star_path_planning/informed_rrt_star_path_planning.py index 5019a606..8de18b20 100644 --- a/src/simulations/path_planning/informed_rrt_star_path_planning/informed_rrt_star_path_planning.py +++ b/src/simulations/path_planning/informed_rrt_star_path_planning/informed_rrt_star_path_planning.py @@ -71,7 +71,7 @@ def main(): occ_grid.add_object(obst_list) occ_grid.save_map() - planner = InformedRrtStarPathPlanner((10, 0), (30, 0), map_path, x_lim=x_lim, y_lim=y_lim, path_filename=path_filename, gif_name=search_gif_path, + planner = InformedRrtStarPathPlanner((10, 0), (30, 0), map_path, x_lim=x_lim, y_lim=y_lim, path_filename=path_filename, gif_name=search_gif_path if show_plot else None, max_iterations=1200,step_size=1.5,goal_sample_rate=0.05, visualize_live=False) # Load sparse path from json file diff --git a/src/simulations/path_planning/rrt_path_planning/rrt_path_planning.py b/src/simulations/path_planning/rrt_path_planning/rrt_path_planning.py index 8ddc1b13..8ab1d6c4 100644 --- a/src/simulations/path_planning/rrt_path_planning/rrt_path_planning.py +++ b/src/simulations/path_planning/rrt_path_planning/rrt_path_planning.py @@ -77,7 +77,7 @@ def main(): occ_grid.save_map() # Easy Goal = (50,22) # Hard Goal = (50,-10) - planner = RrtPathPlanner((0, 0), (50, -10), map_path, x_lim=x_lim, y_lim=y_lim, path_filename=path_filename, gif_name=search_gif_path, + planner = RrtPathPlanner((0, 0), (50, -10), map_path, x_lim=x_lim, y_lim=y_lim, path_filename=path_filename, gif_name=search_gif_path if show_plot else None, max_iterations=5000,step_size=0.5,goal_sample_rate=0.05) # Load sparse path from json file diff --git a/src/simulations/path_planning/rrt_star_bidirectional_path_planning/rrt_star_bidirectional_path_planning.py b/src/simulations/path_planning/rrt_star_bidirectional_path_planning/rrt_star_bidirectional_path_planning.py index 2b2403b7..f1f79691 100644 --- a/src/simulations/path_planning/rrt_star_bidirectional_path_planning/rrt_star_bidirectional_path_planning.py +++ b/src/simulations/path_planning/rrt_star_bidirectional_path_planning/rrt_star_bidirectional_path_planning.py @@ -77,7 +77,7 @@ def main(): occ_grid.save_map() # Easy Goal = (50,22) # Hard Goal = (50,-10) - planner = RrtStarBidirectionalPathPlanner((0, 0), (50, -10), map_path, x_lim=x_lim, y_lim=y_lim, path_filename=path_filename, gif_name=search_gif_path, + planner = RrtStarBidirectionalPathPlanner((0, 0), (50, -10), map_path, x_lim=x_lim, y_lim=y_lim, path_filename=path_filename, gif_name=search_gif_path if show_plot else None, max_iterations=5000, step_size=0.5, goal_sample_rate=0.05) # Load sparse path from json file diff --git a/src/simulations/path_planning/rrt_star_path_planning/rrt_star_path_planning.py b/src/simulations/path_planning/rrt_star_path_planning/rrt_star_path_planning.py index 1391a53e..9197e2d4 100644 --- a/src/simulations/path_planning/rrt_star_path_planning/rrt_star_path_planning.py +++ b/src/simulations/path_planning/rrt_star_path_planning/rrt_star_path_planning.py @@ -77,7 +77,7 @@ def main(): occ_grid.save_map() # Easy Goal = (50,22) # Hard Goal = (50,-10) - planner = RrtStarPathPlanner((0, 0), (50, -10), map_path, x_lim=x_lim, y_lim=y_lim, path_filename=path_filename, gif_name=search_gif_path, + planner = RrtStarPathPlanner((0, 0), (50, -10), map_path, x_lim=x_lim, y_lim=y_lim, path_filename=path_filename, gif_name=search_gif_path if show_plot else None, max_iterations=5000, step_size=0.5, goal_sample_rate=0.05) # Load sparse path from json file