From f04d3627940328a364b0199b713ef03719d64ac6 Mon Sep 17 00:00:00 2001 From: David Gasinski Date: Mon, 18 Aug 2025 14:55:43 +0100 Subject: [PATCH 1/3] added function to join threads during cleanup, added typing and made args optional --- srunner/autoagents/autoware_agent.py | 8 ++--- srunner/tools/ROS2_launch.py | 47 +++++++++++++++------------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/srunner/autoagents/autoware_agent.py b/srunner/autoagents/autoware_agent.py index accb446..8b366a9 100644 --- a/srunner/autoagents/autoware_agent.py +++ b/srunner/autoagents/autoware_agent.py @@ -13,6 +13,7 @@ from std_msgs.msg import Empty + import threading import rclpy import time @@ -60,7 +61,6 @@ def setup(self, config: EnvironmentConfig | None = None) -> None: # check the bridge is ready # publish sensor information to the bridge # wait for it to return the correct message - ego_config_msg = EgoConfig() ego_config_msg.ego_name = config.ego_name ego_config_msg.ego_model = config.ego_model @@ -148,12 +148,12 @@ def run_step(self) -> None: waypoints.append( self._convert_to_waypoint(waypoint).autoware_from_world_coords() ) - + # autoware cannot handle many waypoints, becomes unreliable n_waypoints = len(waypoints) segment_size = int(n_waypoints / 3) - - #self.route_node.request_route(goal_pose, waypoints[0::segment_size]) + + # self.route_node.request_route(goal_pose, waypoints[0::segment_size]) self.route_node.publish_route(goal_pose, waypoints[0::segment_size]) self.sent_route = True diff --git a/srunner/tools/ROS2_launch.py b/srunner/tools/ROS2_launch.py index 695a437..44fba95 100644 --- a/srunner/tools/ROS2_launch.py +++ b/srunner/tools/ROS2_launch.py @@ -1,12 +1,15 @@ import subprocess import threading + class ROS2Launch(object): threads = dict() stop_event = threading.Event() - - @classmethod - def launch_file(self, package_name: str, launch_file: str, args: dict) -> None: + + @staticmethod + def launch_file( + self, package_name: str, launch_file: str, args: dict | None = None + ) -> None: """will launch the file specified from the package specified Args: @@ -15,14 +18,13 @@ def launch_file(self, package_name: str, launch_file: str, args: dict) -> None: args (dict): dictionary of arguments to pass to launch file """ command = self._construct_command(package_name, launch_file, args) - thread = threading.Thread(target=self._run_command, args=(command, self.stop_event)) - self.threads[self.package_name] = { - "thread": thread, - "stop": False - } + thread = threading.Thread( + target=self._run_command, args=(command, self.stop_event) + ) + self.threads[self.package_name] = {"thread": thread, "stop": False} thread.start() - - @classmethod + + @staticmethod def cleanup(self, package_name: str) -> None: """provide package name to stop running @@ -31,24 +33,27 @@ def cleanup(self, package_name: str) -> None: """ if package_name in self.threads: thread = self.threads[package_name] - thread['stop'] = True - + thread["stop"] = True + thread["thread"].join() + def _run_command(self, command: list[str], package_name) -> None: process = subprocess.Popen(command, check=True) - + if package_name in self.threads: - while(not self.threads[package_name]['stop']): + while not self.threads[package_name]["stop"]: if process.poll() is not None: break - + if process.poll() is None: process.kill() - - def _construct_command(self, package_name, launch_file, args) -> list[str]: + + def _construct_command( + self, package_name: str, launch_file: str, args: dict | None = None + ) -> list[str]: command = [] command.append("ros2 launch").append(package_name).append(launch_file) - for key, value in args.dict(): - command.append(f"{key}:={value}") + + if args is not None: + for key, value in args.dict(): + command.append(f"{key}:={value}") return command - - \ No newline at end of file From 66706a5708471f810aecbed796630fa4fe25d3a1 Mon Sep 17 00:00:00 2001 From: David Gasinski Date: Mon, 18 Aug 2025 14:57:45 +0100 Subject: [PATCH 2/3] converted class to static --- srunner/autoagents/autoware_agent.py | 7 +++++++ srunner/tools/ROS2_launch.py | 24 +++++++++++++----------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/srunner/autoagents/autoware_agent.py b/srunner/autoagents/autoware_agent.py index 8b366a9..0f0cbe6 100644 --- a/srunner/autoagents/autoware_agent.py +++ b/srunner/autoagents/autoware_agent.py @@ -13,6 +13,8 @@ from std_msgs.msg import Empty +from srunner.tools import ROS2_launch + import threading import rclpy @@ -58,6 +60,11 @@ def setup(self, config: EnvironmentConfig | None = None) -> None: self.sent_route = False + # launch the bridge + ROS2_launch.ROS2Launch.launch_file( + "autoware_carla_interface", "autoware_carla_interface.launch" + ) + # check the bridge is ready # publish sensor information to the bridge # wait for it to return the correct message diff --git a/srunner/tools/ROS2_launch.py b/srunner/tools/ROS2_launch.py index 44fba95..30c6e9e 100644 --- a/srunner/tools/ROS2_launch.py +++ b/srunner/tools/ROS2_launch.py @@ -8,7 +8,7 @@ class ROS2Launch(object): @staticmethod def launch_file( - self, package_name: str, launch_file: str, args: dict | None = None + package_name: str, launch_file: str, args: dict | None = None ) -> None: """will launch the file specified from the package specified @@ -17,38 +17,40 @@ def launch_file( launch_file (str): launch file name args (dict): dictionary of arguments to pass to launch file """ - command = self._construct_command(package_name, launch_file, args) + command = ROS2Launch._construct_command(package_name, launch_file, args) thread = threading.Thread( - target=self._run_command, args=(command, self.stop_event) + target=ROS2Launch._run_command, args=(command, ROS2Launch.stop_event) ) - self.threads[self.package_name] = {"thread": thread, "stop": False} + ROS2Launch.threads[package_name] = {"thread": thread, "stop": False} thread.start() @staticmethod - def cleanup(self, package_name: str) -> None: + def cleanup(package_name: str) -> None: """provide package name to stop running Args: package_name (str): name of the ROS2 package to kill """ - if package_name in self.threads: - thread = self.threads[package_name] + if package_name in ROS2Launch.threads: + thread = ROS2Launch.threads[package_name] thread["stop"] = True thread["thread"].join() - def _run_command(self, command: list[str], package_name) -> None: + @staticmethod + def _run_command(command: list[str], package_name) -> None: process = subprocess.Popen(command, check=True) - if package_name in self.threads: - while not self.threads[package_name]["stop"]: + if package_name in ROS2Launch.threads: + while not ROS2Launch.threads[package_name]["stop"]: if process.poll() is not None: break if process.poll() is None: process.kill() + @staticmethod def _construct_command( - self, package_name: str, launch_file: str, args: dict | None = None + package_name: str, launch_file: str, args: dict | None = None ) -> list[str]: command = [] command.append("ros2 launch").append(package_name).append(launch_file) From b2581729bab292d8777d2ded4b02a6b0803c1af9 Mon Sep 17 00:00:00 2001 From: Gwilym-Rutherford Date: Mon, 18 Aug 2025 15:48:31 +0100 Subject: [PATCH 3/3] Fix _run_command function --- srunner/tools/ROS2_launch.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/srunner/tools/ROS2_launch.py b/srunner/tools/ROS2_launch.py index 30c6e9e..7845dc6 100644 --- a/srunner/tools/ROS2_launch.py +++ b/srunner/tools/ROS2_launch.py @@ -38,7 +38,17 @@ def cleanup(package_name: str) -> None: @staticmethod def _run_command(command: list[str], package_name) -> None: - process = subprocess.Popen(command, check=True) + command = ( + f"/bin/bash && source /opt/ros/humble/setup.bash && {' '.join(command)}" + ) + + process = subprocess.Popen( + command, + shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + ) if package_name in ROS2Launch.threads: while not ROS2Launch.threads[package_name]["stop"]: