From f36491139d912d6ba4f4ace526eb1918bd5687fb Mon Sep 17 00:00:00 2001 From: David Gasinski Date: Tue, 9 Sep 2025 17:34:33 +0100 Subject: [PATCH 1/3] added code to modify folder permissions to allow a docker copy --- aw_scenario_runner.py | 2 +- srunner/tools/CARLA_manager.py | 24 +++++++++++++++++++++++- srunner/tools/results_manager.py | 4 ++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/aw_scenario_runner.py b/aw_scenario_runner.py index 35334d8..209db06 100644 --- a/aw_scenario_runner.py +++ b/aw_scenario_runner.py @@ -348,7 +348,7 @@ def run(self) -> None: if self.host_volume is not None: CARLAManager.fetch_file( "/home/carla/recording.log", - f"{self.host_volume}/{self.results_manager.last_scenario_host}/recording.log", + f"{self.host_volume}/{self.results_manager.last_scenario_host}", ) logger.info("Calculating driving score...") diff --git a/srunner/tools/CARLA_manager.py b/srunner/tools/CARLA_manager.py index 4b88d95..3c4e1d5 100644 --- a/srunner/tools/CARLA_manager.py +++ b/srunner/tools/CARLA_manager.py @@ -57,12 +57,34 @@ def stop_carla(): logger.info(f"Kill stdout: {result.stdout.strip()}") CARLAManager.container_id = None + @staticmethod + def update_permission(path: str) -> None: + """Updates the permissions of a folder to allow non-root users to copy + + Args: + path (str): file to modify + """ + env = os.environ.copy() + result = subprocess.run( + f"chmod -R 777 {path}", + shell=True, + text=True, + capture_output=True, + env=env, + ) + + if not result.returncode == 0: + logger.error(f"Failed to update permissions for {path}") + else: + logger.info(f"Successfully changed {path} ownership") + @staticmethod def fetch_file(path: str, dest: str): if CARLAManager.container_id is not None: env = os.environ.copy() + # ensure everyone has permission to copy to dest result = subprocess.run( - f"docker cp {CARLAManager.container_id}:{path} {dest}", + f"chmod -R 777 {dest} && docker cp {CARLAManager.container_id}:{path} {dest}", shell=True, text=True, capture_output=True, diff --git a/srunner/tools/results_manager.py b/srunner/tools/results_manager.py index c6d5633..24f3ece 100644 --- a/srunner/tools/results_manager.py +++ b/srunner/tools/results_manager.py @@ -3,6 +3,7 @@ import json from srunner.scenario_decoder.json_to_xml_files import XMLToFiles +from srunner.tools.CARLA_manager import CARLAManager class ScenarioDefinitionManager(object): @@ -65,6 +66,9 @@ def _create_scenario_folder(self, iteration: str, results_folder: str): os.path.split(results_folder)[1], iteration ) # relative path on host + # update permissions + CARLAManager.update_permission(self.last_scenario) + return full_path def parse_json( From 3ce34e99daf201096fbc54b821f0f27a672e8308 Mon Sep 17 00:00:00 2001 From: David Gasinski Date: Tue, 9 Sep 2025 18:15:30 +0100 Subject: [PATCH 2/3] fixed issue with MetricsCollector thread hanging --- aw_scenario_runner.py | 10 ++++------ srunner/tools/metrics_collector.py | 25 +++++++++++++++++-------- srunner/tools/results_manager.py | 4 ---- srunner/tools/test_buffer.txt | 1 + 4 files changed, 22 insertions(+), 18 deletions(-) create mode 100644 srunner/tools/test_buffer.txt diff --git a/aw_scenario_runner.py b/aw_scenario_runner.py index 209db06..41c577a 100644 --- a/aw_scenario_runner.py +++ b/aw_scenario_runner.py @@ -68,7 +68,6 @@ class AWScenarioRunner(object): definition_manager = None aw_agent = None - host_volume = os.environ["SR_HOST_VOLUME"] def __init__(self, config: dict) -> None: """ @@ -345,11 +344,10 @@ def run(self) -> None: scenario_process.kill() # copy over the recording from CARLA container if env variable is setup - if self.host_volume is not None: - CARLAManager.fetch_file( - "/home/carla/recording.log", - f"{self.host_volume}/{self.results_manager.last_scenario_host}", - ) + CARLAManager.fetch_file( + "/home/carla/recording.log", + self.results_manager.last_scenario, + ) logger.info("Calculating driving score...") driving_score = self._calculate_driving_score(result["criteria"]) diff --git a/srunner/tools/metrics_collector.py b/srunner/tools/metrics_collector.py index 49c6977..a5fff7f 100644 --- a/srunner/tools/metrics_collector.py +++ b/srunner/tools/metrics_collector.py @@ -1,4 +1,4 @@ -from queue import Queue +from queue import Queue, Empty from typing import Any import threading @@ -44,7 +44,6 @@ def reset(cls) -> None: cls.state = {} cls._file_target = "" cls._thread = None - cls._running = False @classmethod def update_key(cls, key: str, value: Any) -> None: @@ -91,15 +90,21 @@ def stop_thread(cls) -> None: @classmethod def _thread_target(cls) -> None: - with open(cls._file_target, "w") as f: # open the file for reading - f.write("[") # first character of json array - while cls._running: + f = open(cls._file_target, "w") + + f.write("[") + while cls._running: + try: state = cls.state_queue.get( - block=True - ) # block thread until there is an object in queue + block=True, timeout=0.05 + ) # can't block thread as it will never finish serialized_json = json.dumps(state) f.write(serialized_json + ",") - f.write("]") # last json character + except Empty: + pass + + f.write("]") # last json character + f.close() if __name__ == "__main__": @@ -107,6 +112,7 @@ def _thread_target(cls) -> None: target = "test_buffer.txt" state = {"timestamp": time.perf_counter(), "value": 0} + start = time.perf_counter() MetricsCollector.init_state(state, target, include=False) @@ -118,4 +124,7 @@ def _thread_target(cls) -> None: MetricsCollector.update_key("value", i) MetricsCollector.save_state() + print(f"Took {time.perf_counter() - start} to push.") + MetricsCollector.stop_thread() + print(f"Took {time.perf_counter() - start} to join.") diff --git a/srunner/tools/results_manager.py b/srunner/tools/results_manager.py index 24f3ece..7066b9a 100644 --- a/srunner/tools/results_manager.py +++ b/srunner/tools/results_manager.py @@ -62,13 +62,9 @@ def _create_scenario_folder(self, iteration: str, results_folder: str): os.makedirs(full_path, exist_ok=True) # exist_ok=True, no need to error handle self.last_scenario = full_path - self.last_scenario_host = os.path.join( - os.path.split(results_folder)[1], iteration - ) # relative path on host # update permissions CARLAManager.update_permission(self.last_scenario) - return full_path def parse_json( diff --git a/srunner/tools/test_buffer.txt b/srunner/tools/test_buffer.txt new file mode 100644 index 0000000..8c395cb --- /dev/null +++ b/srunner/tools/test_buffer.txt @@ -0,0 +1 @@ +[{"timestamp": 4567.247525948, "value": 1},{"timestamp": 4568.253647252, "value": 2},{"timestamp": 4569.259156654, "value": 3},{"timestamp": 4570.26535354, "value": 4},{"timestamp": 4571.271072756, "value": 5},{"timestamp": 4572.277276641, "value": 6},{"timestamp": 4573.28347915, "value": 7},{"timestamp": 4574.289774352, "value": 8},{"timestamp": 4575.29519866, "value": 9},] From b9ff83fc5062b83c38b596cabfdb7a5971a1036d Mon Sep 17 00:00:00 2001 From: David Gasinski Date: Tue, 9 Sep 2025 18:15:48 +0100 Subject: [PATCH 3/3] removed test_buffer file --- srunner/tools/test_buffer.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 srunner/tools/test_buffer.txt diff --git a/srunner/tools/test_buffer.txt b/srunner/tools/test_buffer.txt deleted file mode 100644 index 8c395cb..0000000 --- a/srunner/tools/test_buffer.txt +++ /dev/null @@ -1 +0,0 @@ -[{"timestamp": 4567.247525948, "value": 1},{"timestamp": 4568.253647252, "value": 2},{"timestamp": 4569.259156654, "value": 3},{"timestamp": 4570.26535354, "value": 4},{"timestamp": 4571.271072756, "value": 5},{"timestamp": 4572.277276641, "value": 6},{"timestamp": 4573.28347915, "value": 7},{"timestamp": 4574.289774352, "value": 8},{"timestamp": 4575.29519866, "value": 9},]