diff --git a/.gitignore b/.gitignore index 7e7baef..6119e70 100644 --- a/.gitignore +++ b/.gitignore @@ -172,3 +172,4 @@ cython_debug/ # ADF agent.log* +precompute diff --git a/adf_core_python/cli/template/src/team_name/module/complex/sample_road_detector.py b/adf_core_python/cli/template/src/team_name/module/complex/sample_road_detector.py index 3dd95d8..2f554db 100644 --- a/adf_core_python/cli/template/src/team_name/module/complex/sample_road_detector.py +++ b/adf_core_python/cli/template/src/team_name/module/complex/sample_road_detector.py @@ -9,7 +9,7 @@ from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo -from adf_core_python.core.agent.info.scenario_info import Mode, ScenarioInfo +from adf_core_python.core.agent.info.scenario_info import ScenarioInfo from adf_core_python.core.agent.info.world_info import WorldInfo from adf_core_python.core.agent.module.module_manager import ModuleManager from adf_core_python.core.agent.precompute.precompute_data import PrecomputeData @@ -31,15 +31,14 @@ def __init__( super().__init__( agent_info, world_info, scenario_info, module_manager, develop_data ) - match scenario_info.get_mode(): - case Mode.NON_PRECOMPUTE: - self._path_planning: PathPlanning = cast( - PathPlanning, - module_manager.get_module( - "SampleRoadDetector.PathPlanning", - "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", - ), - ) + + self._path_planning: PathPlanning = cast( + PathPlanning, + module_manager.get_module( + "SampleRoadDetector.PathPlanning", + "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", + ), + ) self.register_sub_module(self._path_planning) self._result = None diff --git a/adf_core_python/core/agent/agent.py b/adf_core_python/core/agent/agent.py index 55506e1..bdf45c6 100644 --- a/adf_core_python/core/agent/agent.py +++ b/adf_core_python/core/agent/agent.py @@ -112,12 +112,15 @@ def __init__( self.is_precompute = is_precompute if is_precompute: - # PrecomputeData.remove_date(data_storage_name) - self.mode = Mode.PRECOMPUTATION + self._mode = Mode.PRECOMPUTATION + + try: + self._precompute_data = PrecomputeData(data_storage_name) + except Exception as _: + pass self._module_config = module_config self._develop_data = develop_data - self._precompute_data = PrecomputeData(data_storage_name) self._message_manager: MessageManager = MessageManager() self._communication_module: CommunicationModule = StandardCommunicationModule() @@ -131,11 +134,10 @@ def post_connect(self) -> None: if self.is_precompute: self._mode = Mode.PRECOMPUTATION else: - # if self._precompute_data.is_ready(): - # self._mode = Mode.PRECOMPUTED - # else: - # self._mode = Mode.NON_PRECOMPUTE - self._mode = Mode.NON_PRECOMPUTE + if self._precompute_data.is_available(): + self._mode = Mode.PRECOMPUTED + else: + self._mode = Mode.NON_PRECOMPUTE self.config.set_value(ConfigKey.KEY_DEBUG_FLAG, self.is_debug) self.config.set_value( @@ -210,10 +212,6 @@ def update_step_info( def think(self) -> None: pass - @abstractmethod - def precompute(self) -> None: - pass - @abstractmethod def get_requested_entities(self) -> list[EntityURN]: pass @@ -266,12 +264,12 @@ def handle_connect_ok(self, msg: Any) -> None: self.send_acknowledge(msg.request_id) self.post_connect() self.logger.info( - f"Connected to kernel: {self.__class__.__qualname__} (request_id: {msg.request_id})", + f"Connected to kernel: {self.__class__.__qualname__} (request_id: {msg.request_id}, agent_id: {self.agent_id}, mode: {self._mode})", request_id=msg.request_id, ) - if self.precompute_flag: - print("self.precompute_flag: ", self.precompute_flag) - self.precompute() + if self.is_precompute: + self.logger.info("Precompute finished") + exit(0) self.finish_post_connect_event.set() diff --git a/adf_core_python/core/agent/office/office.py b/adf_core_python/core/agent/office/office.py index 09e97bd..98911f8 100644 --- a/adf_core_python/core/agent/office/office.py +++ b/adf_core_python/core/agent/office/office.py @@ -82,9 +82,25 @@ def post_connect(self) -> None: match self._scenario_info.get_mode(): case Mode.PRECOMPUTATION: - pass + self._tactics_center.precompute( + self._agent_info, + self._world_info, + self._scenario_info, + self._module_manager, + self._precompute_data, + self._message_manager, + self._develop_data, + ) case Mode.PRECOMPUTED: - pass + self._tactics_center.resume( + self._agent_info, + self._world_info, + self._scenario_info, + self._module_manager, + self._precompute_data, + self._message_manager, + self._develop_data, + ) case Mode.NON_PRECOMPUTE: self._tactics_center.prepare( self._agent_info, diff --git a/adf_core_python/core/agent/office/office_fire.py b/adf_core_python/core/agent/office/office_fire.py index dcab2bd..16b93cd 100644 --- a/adf_core_python/core/agent/office/office_fire.py +++ b/adf_core_python/core/agent/office/office_fire.py @@ -31,8 +31,5 @@ def __init__( finish_post_connect_event, ) - def precompute(self) -> None: - pass - def get_requested_entities(self) -> list[EntityURN]: return [EntityURN.FIRE_STATION] diff --git a/adf_core_python/core/agent/office/office_police.py b/adf_core_python/core/agent/office/office_police.py index b4c9fc4..4b2ca8b 100644 --- a/adf_core_python/core/agent/office/office_police.py +++ b/adf_core_python/core/agent/office/office_police.py @@ -31,8 +31,5 @@ def __init__( finish_post_connect_event, ) - def precompute(self) -> None: - pass - def get_requested_entities(self) -> list[EntityURN]: return [EntityURN.POLICE_OFFICE] diff --git a/adf_core_python/core/agent/platoon/platoon.py b/adf_core_python/core/agent/platoon/platoon.py index c5ff9f8..8a66099 100644 --- a/adf_core_python/core/agent/platoon/platoon.py +++ b/adf_core_python/core/agent/platoon/platoon.py @@ -83,9 +83,25 @@ def post_connect(self) -> None: match self._scenario_info.get_mode(): case Mode.PRECOMPUTATION: - pass + self._tactics_agent.precompute( + self._agent_info, + self._world_info, + self._scenario_info, + self._module_manager, + self._precompute_data, + self._message_manager, + self._develop_data, + ) case Mode.PRECOMPUTED: - pass + self._tactics_agent.resume( + self._agent_info, + self._world_info, + self._scenario_info, + self._module_manager, + self._precompute_data, + self._message_manager, + self._develop_data, + ) case Mode.NON_PRECOMPUTE: self._tactics_agent.prepare( self._agent_info, diff --git a/adf_core_python/core/agent/platoon/platoon_ambulance.py b/adf_core_python/core/agent/platoon/platoon_ambulance.py index 8a4d976..169d208 100644 --- a/adf_core_python/core/agent/platoon/platoon_ambulance.py +++ b/adf_core_python/core/agent/platoon/platoon_ambulance.py @@ -31,8 +31,5 @@ def __init__( finish_post_connect_event, ) - def precompute(self) -> None: - pass - def get_requested_entities(self) -> list[EntityURN]: return [EntityURN.AMBULANCE_TEAM] diff --git a/adf_core_python/core/agent/platoon/platoon_fire.py b/adf_core_python/core/agent/platoon/platoon_fire.py index 01d75ba..3071eef 100644 --- a/adf_core_python/core/agent/platoon/platoon_fire.py +++ b/adf_core_python/core/agent/platoon/platoon_fire.py @@ -31,8 +31,5 @@ def __init__( finish_post_connect_event, ) - def precompute(self) -> None: - pass - def get_requested_entities(self) -> list[EntityURN]: return [EntityURN.FIRE_BRIGADE] diff --git a/adf_core_python/core/agent/platoon/platoon_police.py b/adf_core_python/core/agent/platoon/platoon_police.py index 569159e..6df9440 100644 --- a/adf_core_python/core/agent/platoon/platoon_police.py +++ b/adf_core_python/core/agent/platoon/platoon_police.py @@ -31,8 +31,5 @@ def __init__( finish_post_connect_event, ) - def precompute(self) -> None: - pass - def get_requested_entities(self) -> list[EntityURN]: return [EntityURN.POLICE_FORCE] diff --git a/adf_core_python/core/agent/precompute/precompute_data.py b/adf_core_python/core/agent/precompute/precompute_data.py index ba5840f..41b2029 100644 --- a/adf_core_python/core/agent/precompute/precompute_data.py +++ b/adf_core_python/core/agent/precompute/precompute_data.py @@ -1,4 +1,75 @@ -# TODO: Implement the PrecomputeData class +import json +import os + +ENCODE = "utf-8" + + class PrecomputeData: - def __init__(self, file_path: str) -> None: - self._file_path = file_path + def __init__(self, dir_path: str) -> None: + """ + Initialize the PrecomputeData object. + + Parameters + ---------- + dir_path : str + The directory path to save the precompute data. + + Raises + ------ + Exception + """ + self._dir_path = dir_path + + def read_json_data(self, module_name: str) -> dict: + """ + Read the precompute data from the file. + + Returns + ------- + dict + The precompute data. + + Raises + ------ + Exception + """ + + with open(f"{self._dir_path}/{module_name}.json", "r", encoding=ENCODE) as file: + return json.load(file) + + def write_json_data(self, data: dict, module_name: str) -> None: + """ + Write the precompute data to the file. + + Parameters + ---------- + data : dict + The data to write. + + Raises + ------ + Exception + """ + if not os.path.exists(self._dir_path): + os.makedirs(self._dir_path) + + with open(f"{self._dir_path}/{module_name}.json", "w", encoding=ENCODE) as file: + json.dump(data, file, indent=4) + + def remove_precompute_data(self) -> None: + """ + Remove the precompute data file. + """ + if os.path.exists(self._dir_path): + os.remove(self._dir_path) + + def is_available(self) -> bool: + """ + Check if the precompute data is available. + + Returns + ------- + bool + True if the precompute data is available, False otherwise. + """ + return os.path.exists(self._dir_path) diff --git a/adf_core_python/core/component/tactics/tactics_center.py b/adf_core_python/core/component/tactics/tactics_center.py index ea95edf..2469cc6 100644 --- a/adf_core_python/core/component/tactics/tactics_center.py +++ b/adf_core_python/core/component/tactics/tactics_center.py @@ -46,6 +46,19 @@ def resume( ) -> None: raise NotImplementedError + @abstractmethod + def precompute( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + message_manager: MessageManager, + develop_data: DevelopData, + ) -> None: + raise NotImplementedError + @abstractmethod def prepare( self, diff --git a/adf_core_python/core/launcher/config_key.py b/adf_core_python/core/launcher/config_key.py index d32afb2..591876e 100644 --- a/adf_core_python/core/launcher/config_key.py +++ b/adf_core_python/core/launcher/config_key.py @@ -23,3 +23,4 @@ class ConfigKey: KEY_FIRE_STATION_COUNT: Final[str] = "adf.team.office.fire.count" KEY_POLICE_OFFICE_COUNT: Final[str] = "adf.team.office.police.count" # adf-core-python + KEY_PRECOMPUTE_DATA_DIR: Final[str] = "adf.agent.precompute.dir_name" diff --git a/adf_core_python/core/launcher/connect/connector_ambulance_center.py b/adf_core_python/core/launcher/connect/connector_ambulance_center.py index 33e736e..132a985 100644 --- a/adf_core_python/core/launcher/connect/connector_ambulance_center.py +++ b/adf_core_python/core/launcher/connect/connector_ambulance_center.py @@ -53,8 +53,10 @@ def connect( ), ) - request_id: int = component_launcher.generate_request_id() + precompute_data_dir: str = f"{config.get_value(ConfigKey.KEY_PRECOMPUTE_DATA_DIR, 'precompute')}/ambulance_center" + finish_post_connect_event = threading.Event() + request_id: int = component_launcher.generate_request_id() thread = threading.Thread( target=component_launcher.connect, args=( @@ -63,7 +65,7 @@ def connect( "ambulance_center", config.get_value(ConfigKey.KEY_PRECOMPUTE, False), config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), - "test", + precompute_data_dir, module_config, develop_data, finish_post_connect_event, diff --git a/adf_core_python/core/launcher/connect/connector_ambulance_team.py b/adf_core_python/core/launcher/connect/connector_ambulance_team.py index 44620e8..d2aa8c0 100644 --- a/adf_core_python/core/launcher/connect/connector_ambulance_team.py +++ b/adf_core_python/core/launcher/connect/connector_ambulance_team.py @@ -53,8 +53,10 @@ def connect( ), ) - request_id: int = component_launcher.generate_request_id() + precompute_data_dir: str = f"{config.get_value(ConfigKey.KEY_PRECOMPUTE_DATA_DIR, 'precompute')}/ambulance_team" + finish_post_connect_event = threading.Event() + request_id: int = component_launcher.generate_request_id() thread = threading.Thread( target=component_launcher.connect, args=( @@ -63,7 +65,7 @@ def connect( "ambulance_team", config.get_value(ConfigKey.KEY_PRECOMPUTE, False), config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), - "test", + precompute_data_dir, module_config, develop_data, finish_post_connect_event, diff --git a/adf_core_python/core/launcher/connect/connector_fire_brigade.py b/adf_core_python/core/launcher/connect/connector_fire_brigade.py index 2f5ecf5..747f503 100644 --- a/adf_core_python/core/launcher/connect/connector_fire_brigade.py +++ b/adf_core_python/core/launcher/connect/connector_fire_brigade.py @@ -51,6 +51,8 @@ def connect( ), ) + precompute_data_dir: str = f"{config.get_value(ConfigKey.KEY_PRECOMPUTE_DATA_DIR, 'precompute')}/fire_brigade" + request_id: int = component_launcher.generate_request_id() finish_post_connect_event = threading.Event() thread = threading.Thread( @@ -61,7 +63,7 @@ def connect( "fire_brigade", config.get_value(ConfigKey.KEY_PRECOMPUTE, False), config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), - "test", + precompute_data_dir, module_config, develop_data, finish_post_connect_event, diff --git a/adf_core_python/core/launcher/connect/connector_fire_station.py b/adf_core_python/core/launcher/connect/connector_fire_station.py index 7efec93..8f099ee 100644 --- a/adf_core_python/core/launcher/connect/connector_fire_station.py +++ b/adf_core_python/core/launcher/connect/connector_fire_station.py @@ -51,6 +51,8 @@ def connect( ), ) + precompute_data_dir: str = f"{config.get_value(ConfigKey.KEY_PRECOMPUTE_DATA_DIR, 'precompute')}/fire_station" + request_id: int = component_launcher.generate_request_id() finish_post_connect_event = threading.Event() thread = threading.Thread( @@ -61,7 +63,7 @@ def connect( "fire_station", config.get_value(ConfigKey.KEY_PRECOMPUTE, False), config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), - "test", + precompute_data_dir, module_config, develop_data, finish_post_connect_event, diff --git a/adf_core_python/core/launcher/connect/connector_police_force.py b/adf_core_python/core/launcher/connect/connector_police_force.py index bd29160..e17fe76 100644 --- a/adf_core_python/core/launcher/connect/connector_police_force.py +++ b/adf_core_python/core/launcher/connect/connector_police_force.py @@ -51,6 +51,8 @@ def connect( ), ) + precompute_data_dir: str = f"{config.get_value(ConfigKey.KEY_PRECOMPUTE_DATA_DIR, 'precompute')}/police_force" + request_id: int = component_launcher.generate_request_id() finish_post_connect_event = threading.Event() thread = threading.Thread( @@ -61,7 +63,7 @@ def connect( "police_force", config.get_value(ConfigKey.KEY_PRECOMPUTE, False), config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), - "test", + precompute_data_dir, module_config, develop_data, finish_post_connect_event, diff --git a/adf_core_python/core/launcher/connect/connector_police_office.py b/adf_core_python/core/launcher/connect/connector_police_office.py index 69fd76b..52c3aac 100644 --- a/adf_core_python/core/launcher/connect/connector_police_office.py +++ b/adf_core_python/core/launcher/connect/connector_police_office.py @@ -53,6 +53,8 @@ def connect( ), ) + precompute_data_dir: str = f"{config.get_value(ConfigKey.KEY_PRECOMPUTE_DATA_DIR, 'precompute')}/police_office" + request_id: int = component_launcher.generate_request_id() finish_post_connect_event = threading.Event() thread = threading.Thread( @@ -63,7 +65,7 @@ def connect( "police_office", config.get_value(ConfigKey.KEY_PRECOMPUTE, False), config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), - "test", + precompute_data_dir, module_config, develop_data, finish_post_connect_event, diff --git a/adf_core_python/implement/action/default_extend_action_clear.py b/adf_core_python/implement/action/default_extend_action_clear.py index 39aa859..d23c8d1 100644 --- a/adf_core_python/implement/action/default_extend_action_clear.py +++ b/adf_core_python/implement/action/default_extend_action_clear.py @@ -22,7 +22,7 @@ from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo -from adf_core_python.core.agent.info.scenario_info import Mode, ScenarioInfo +from adf_core_python.core.agent.info.scenario_info import ScenarioInfo from adf_core_python.core.agent.info.world_info import WorldInfo from adf_core_python.core.agent.module.module_manager import ModuleManager from adf_core_python.core.agent.precompute.precompute_data import PrecomputeData @@ -63,19 +63,13 @@ def __init__( self._old_clear_y = 0 self.count = 0 - match self.scenario_info.get_mode(): - case Mode.NON_PRECOMPUTE: - self._path_planning = cast( - PathPlanning, - self.module_manager.get_module( - "DefaultExtendActionClear.PathPlanning", - "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", - ), - ) - case Mode.PRECOMPUTATION: - pass - case Mode.PRECOMPUTED: - pass + self._path_planning = cast( + PathPlanning, + self.module_manager.get_module( + "DefaultExtendActionClear.PathPlanning", + "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", + ), + ) def precompute(self, precompute_data: PrecomputeData) -> ExtendAction: super().precompute(precompute_data) diff --git a/adf_core_python/implement/action/default_extend_action_move.py b/adf_core_python/implement/action/default_extend_action_move.py index 6614ffd..e4936a4 100644 --- a/adf_core_python/implement/action/default_extend_action_move.py +++ b/adf_core_python/implement/action/default_extend_action_move.py @@ -10,7 +10,7 @@ from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo -from adf_core_python.core.agent.info.scenario_info import Mode, ScenarioInfo +from adf_core_python.core.agent.info.scenario_info import ScenarioInfo from adf_core_python.core.agent.info.world_info import WorldInfo from adf_core_python.core.agent.module.module_manager import ModuleManager from adf_core_python.core.agent.precompute.precompute_data import PrecomputeData @@ -33,19 +33,13 @@ def __init__( self._target_entity_id: Optional[EntityID] = None self._threshold_to_rest: int = develop_data.get_value("threshold_to_rest", 100) - match self.scenario_info.get_mode(): - case Mode.NON_PRECOMPUTE: - self._path_planning: PathPlanning = cast( - PathPlanning, - self.module_manager.get_module( - "DefaultExtendActionMove.PathPlanning", - "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", - ), - ) - case Mode.PRECOMPUTATION: - pass - case Mode.PRECOMPUTED: - pass + self._path_planning: PathPlanning = cast( + PathPlanning, + self.module_manager.get_module( + "DefaultExtendActionMove.PathPlanning", + "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", + ), + ) def precompute(self, precompute_data: PrecomputeData) -> ExtendAction: super().precompute(precompute_data) diff --git a/adf_core_python/implement/action/default_extend_action_rescue.py b/adf_core_python/implement/action/default_extend_action_rescue.py index 640d088..e76e96a 100644 --- a/adf_core_python/implement/action/default_extend_action_rescue.py +++ b/adf_core_python/implement/action/default_extend_action_rescue.py @@ -13,7 +13,6 @@ from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo from adf_core_python.core.agent.info.scenario_info import ( - Mode, ScenarioInfo, ScenarioInfoKeys, ) @@ -42,19 +41,13 @@ def __init__( "adf_core_python.implement.action.DefaultExtendActionRescue.rest", 100 ) - match self.scenario_info.get_mode(): - case Mode.NON_PRECOMPUTE: - self._path_planning = cast( - PathPlanning, - self.module_manager.get_module( - "DefaultExtendActionRescue.PathPlanning", - "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", - ), - ) - case Mode.PRECOMPUTATION: - pass - case Mode.PRECOMPUTED: - pass + self._path_planning = cast( + PathPlanning, + self.module_manager.get_module( + "DefaultExtendActionRescue.PathPlanning", + "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", + ), + ) def precompute(self, precompute_data: PrecomputeData) -> ExtendAction: super().precompute(precompute_data) diff --git a/adf_core_python/implement/action/default_extend_action_transport.py b/adf_core_python/implement/action/default_extend_action_transport.py index 1ee2fd4..8e6c71a 100644 --- a/adf_core_python/implement/action/default_extend_action_transport.py +++ b/adf_core_python/implement/action/default_extend_action_transport.py @@ -15,7 +15,7 @@ from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo -from adf_core_python.core.agent.info.scenario_info import Mode, ScenarioInfo +from adf_core_python.core.agent.info.scenario_info import ScenarioInfo from adf_core_python.core.agent.info.world_info import WorldInfo from adf_core_python.core.agent.module.module_manager import ModuleManager from adf_core_python.core.agent.precompute.precompute_data import PrecomputeData @@ -44,19 +44,13 @@ def __init__( self.agent_info, ) - match self.scenario_info.get_mode(): - case Mode.NON_PRECOMPUTE: - self._path_planning: PathPlanning = cast( - PathPlanning, - self.module_manager.get_module( - "DefaultExtendActionMove.PathPlanning", - "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", - ), - ) - case Mode.PRECOMPUTATION: - pass - case Mode.PRECOMPUTED: - pass + self._path_planning: PathPlanning = cast( + PathPlanning, + self.module_manager.get_module( + "DefaultExtendActionMove.PathPlanning", + "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", + ), + ) def precompute(self, precompute_data: PrecomputeData) -> ExtendAction: super().precompute(precompute_data) diff --git a/adf_core_python/implement/module/algorithm/k_means_clustering.py b/adf_core_python/implement/module/algorithm/k_means_clustering.py index b40f7c4..57228b7 100644 --- a/adf_core_python/implement/module/algorithm/k_means_clustering.py +++ b/adf_core_python/implement/module/algorithm/k_means_clustering.py @@ -17,6 +17,7 @@ from adf_core_python.core.agent.info.scenario_info import ScenarioInfo from adf_core_python.core.agent.info.world_info import WorldInfo from adf_core_python.core.agent.module.module_manager import ModuleManager +from adf_core_python.core.agent.precompute.precompute_data import PrecomputeData from adf_core_python.core.component.module.algorithm.clustering import Clustering @@ -86,6 +87,32 @@ def __init__( def calculate(self) -> Clustering: return self + def precompute(self, precompute_data: PrecomputeData) -> Clustering: + cluster_entities = self.create_cluster(self._cluster_number, self.entities) + precompute_data.write_json_data( + { + "cluster_entities": [ + [entity.get_id().get_value() for entity in cluster] + for cluster in cluster_entities + ] + }, + self.__class__.__name__, + ) + return self + + def resume(self, precompute_data: PrecomputeData) -> Clustering: + data = precompute_data.read_json_data(self.__class__.__name__) + self.cluster_entities = [ + [ + entity + for entity_id in cluster + if (entity := self._world_info.get_entity(EntityID(entity_id))) + is not None + ] + for cluster in data["cluster_entities"] + ] + return self + def get_cluster_number(self) -> int: return self._cluster_number diff --git a/adf_core_python/implement/module/complex/default_road_detector.py b/adf_core_python/implement/module/complex/default_road_detector.py index 5e598b9..035cc61 100644 --- a/adf_core_python/implement/module/complex/default_road_detector.py +++ b/adf_core_python/implement/module/complex/default_road_detector.py @@ -9,7 +9,7 @@ from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo -from adf_core_python.core.agent.info.scenario_info import Mode, ScenarioInfo +from adf_core_python.core.agent.info.scenario_info import ScenarioInfo from adf_core_python.core.agent.info.world_info import WorldInfo from adf_core_python.core.agent.module.module_manager import ModuleManager from adf_core_python.core.agent.precompute.precompute_data import PrecomputeData @@ -31,15 +31,14 @@ def __init__( super().__init__( agent_info, world_info, scenario_info, module_manager, develop_data ) - match scenario_info.get_mode(): - case Mode.NON_PRECOMPUTE: - self._path_planning: PathPlanning = cast( - PathPlanning, - module_manager.get_module( - "DefaultRoadDetector.PathPlanning", - "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", - ), - ) + + self._path_planning: PathPlanning = cast( + PathPlanning, + module_manager.get_module( + "DefaultRoadDetector.PathPlanning", + "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", + ), + ) self.register_sub_module(self._path_planning) self._result = None diff --git a/adf_core_python/implement/tactics/default_tactics_ambulance_center.py b/adf_core_python/implement/tactics/default_tactics_ambulance_center.py index 909f448..d1dd248 100644 --- a/adf_core_python/implement/tactics/default_tactics_ambulance_center.py +++ b/adf_core_python/implement/tactics/default_tactics_ambulance_center.py @@ -3,7 +3,7 @@ from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo -from adf_core_python.core.agent.info.scenario_info import Mode, ScenarioInfo +from adf_core_python.core.agent.info.scenario_info import ScenarioInfo from adf_core_python.core.agent.info.world_info import WorldInfo from adf_core_python.core.agent.module.module_manager import ModuleManager from adf_core_python.core.agent.precompute.precompute_data import PrecomputeData @@ -26,17 +26,27 @@ def initialize( message_manager: MessageManager, develop_data: DevelopData, ) -> None: - match scenario_info.get_mode(): - case Mode.NON_PRECOMPUTE: - self._allocator: TargetAllocator = cast( - TargetAllocator, - module_manager.get_module( - "DefaultTacticsAmbulanceCenter.TargetAllocator", - "adf_core_python.implement.module.complex.default_ambulance_target_allocator.DefaultAmbulanceTargetAllocator", - ), - ) + self._allocator: TargetAllocator = cast( + TargetAllocator, + module_manager.get_module( + "DefaultTacticsAmbulanceCenter.TargetAllocator", + "adf_core_python.implement.module.complex.default_ambulance_target_allocator.DefaultAmbulanceTargetAllocator", + ), + ) self.register_module(self._allocator) + def precompute( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + message_manager: MessageManager, + develop_data: DevelopData, + ) -> None: + self.module_precompute(precompute_data) + def resume( self, agent_info: AgentInfo, diff --git a/adf_core_python/implement/tactics/default_tactics_ambulance_team.py b/adf_core_python/implement/tactics/default_tactics_ambulance_team.py index 888caf2..83d0cdf 100644 --- a/adf_core_python/implement/tactics/default_tactics_ambulance_team.py +++ b/adf_core_python/implement/tactics/default_tactics_ambulance_team.py @@ -7,7 +7,7 @@ from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo -from adf_core_python.core.agent.info.scenario_info import Mode, ScenarioInfo +from adf_core_python.core.agent.info.scenario_info import ScenarioInfo from adf_core_python.core.agent.info.world_info import WorldInfo from adf_core_python.core.agent.module.module_manager import ModuleManager from adf_core_python.core.agent.precompute.precompute_data import PrecomputeData @@ -39,30 +39,28 @@ def initialize( message_manager, develop_data, ) - match scenario_info.get_mode(): - case Mode.NON_PRECOMPUTE: - self._search: Search = cast( - Search, - module_manager.get_module( - "DefaultTacticsAmbulanceTeam.Search", - "adf_core_python.core.component.module.complex.search.Search", - ), - ) - self._human_detector: HumanDetector = cast( - HumanDetector, - module_manager.get_module( - "DefaultTacticsAmbulanceTeam.HumanDetector", - "adf_core_python.core.component.module.complex.human_detector.HumanDetector", - ), - ) - self._action_transport = module_manager.get_extend_action( - "DefaultTacticsAmbulanceTeam.ExtendActionTransport", - "adf_core_python.implement.action.default_extend_action_transport.DefaultExtendActionTransport", - ) - self._action_ext_move = module_manager.get_extend_action( - "DefaultTacticsAmbulanceTeam.ExtendActionMove", - "adf_core_python.implement.action.default_extend_action_move.DefaultExtendActionMove", - ) + self._search: Search = cast( + Search, + module_manager.get_module( + "DefaultTacticsAmbulanceTeam.Search", + "adf_core_python.core.component.module.complex.search.Search", + ), + ) + self._human_detector: HumanDetector = cast( + HumanDetector, + module_manager.get_module( + "DefaultTacticsAmbulanceTeam.HumanDetector", + "adf_core_python.core.component.module.complex.human_detector.HumanDetector", + ), + ) + self._action_transport = module_manager.get_extend_action( + "DefaultTacticsAmbulanceTeam.ExtendActionTransport", + "adf_core_python.implement.action.default_extend_action_transport.DefaultExtendActionTransport", + ) + self._action_ext_move = module_manager.get_extend_action( + "DefaultTacticsAmbulanceTeam.ExtendActionMove", + "adf_core_python.implement.action.default_extend_action_move.DefaultExtendActionMove", + ) self.register_module(self._search) self.register_module(self._human_detector) self.register_action(self._action_transport) diff --git a/adf_core_python/implement/tactics/default_tactics_fire_brigade.py b/adf_core_python/implement/tactics/default_tactics_fire_brigade.py index 4247b48..d0f8512 100644 --- a/adf_core_python/implement/tactics/default_tactics_fire_brigade.py +++ b/adf_core_python/implement/tactics/default_tactics_fire_brigade.py @@ -7,7 +7,7 @@ from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo -from adf_core_python.core.agent.info.scenario_info import Mode, ScenarioInfo +from adf_core_python.core.agent.info.scenario_info import ScenarioInfo from adf_core_python.core.agent.info.world_info import WorldInfo from adf_core_python.core.agent.module.module_manager import ModuleManager from adf_core_python.core.agent.precompute.precompute_data import PrecomputeData @@ -40,30 +40,28 @@ def initialize( develop_data, ) - match scenario_info.get_mode(): - case Mode.NON_PRECOMPUTE: - self._search: Search = cast( - Search, - module_manager.get_module( - "DefaultTacticsFireBrigade.Search", - "adf_core_python.core.component.module.complex.search.Search", - ), - ) - self._human_detector: HumanDetector = cast( - HumanDetector, - module_manager.get_module( - "DefaultTacticsFireBrigade.HumanDetector", - "adf_core_python.core.component.module.complex.human_detector.HumanDetector", - ), - ) - self._action_rescue = module_manager.get_extend_action( - "DefaultTacticsFireBrigade.ExtendActionRescue", - "adf_core_python.implement.action.default_extend_action_rescue.DefaultExtendActionRescue", - ) - self._action_ext_move = module_manager.get_extend_action( - "DefaultTacticsAmbulanceTeam.ExtendActionMove", - "adf_core_python.implement.action.default_extend_action_move.DefaultExtendActionMove", - ) + self._search: Search = cast( + Search, + module_manager.get_module( + "DefaultTacticsFireBrigade.Search", + "adf_core_python.core.component.module.complex.search.Search", + ), + ) + self._human_detector: HumanDetector = cast( + HumanDetector, + module_manager.get_module( + "DefaultTacticsFireBrigade.HumanDetector", + "adf_core_python.core.component.module.complex.human_detector.HumanDetector", + ), + ) + self._action_rescue = module_manager.get_extend_action( + "DefaultTacticsFireBrigade.ExtendActionRescue", + "adf_core_python.implement.action.default_extend_action_rescue.DefaultExtendActionRescue", + ) + self._action_ext_move = module_manager.get_extend_action( + "DefaultTacticsAmbulanceTeam.ExtendActionMove", + "adf_core_python.implement.action.default_extend_action_move.DefaultExtendActionMove", + ) self.register_module(self._search) self.register_module(self._human_detector) self.register_action(self._action_rescue) diff --git a/adf_core_python/implement/tactics/default_tactics_fire_station.py b/adf_core_python/implement/tactics/default_tactics_fire_station.py index 63693d7..6b3dcb2 100644 --- a/adf_core_python/implement/tactics/default_tactics_fire_station.py +++ b/adf_core_python/implement/tactics/default_tactics_fire_station.py @@ -3,7 +3,7 @@ from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo -from adf_core_python.core.agent.info.scenario_info import Mode, ScenarioInfo +from adf_core_python.core.agent.info.scenario_info import ScenarioInfo from adf_core_python.core.agent.info.world_info import WorldInfo from adf_core_python.core.agent.module.module_manager import ModuleManager from adf_core_python.core.agent.precompute.precompute_data import PrecomputeData @@ -26,15 +26,13 @@ def initialize( message_manager: MessageManager, develop_data: DevelopData, ) -> None: - match scenario_info.get_mode(): - case Mode.NON_PRECOMPUTE: - self._allocator: TargetAllocator = cast( - TargetAllocator, - module_manager.get_module( - "DefaultTacticsFireStation.TargetAllocator", - "adf_core_python.implement.module.complex.default_fire_target_allocator.DefaultFireTargetAllocator", - ), - ) + self._allocator: TargetAllocator = cast( + TargetAllocator, + module_manager.get_module( + "DefaultTacticsFireStation.TargetAllocator", + "adf_core_python.implement.module.complex.default_fire_target_allocator.DefaultFireTargetAllocator", + ), + ) self.register_module(self._allocator) def resume( @@ -49,6 +47,18 @@ def resume( ) -> None: self.module_resume(precompute_data) + def precompute( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + message_manager: MessageManager, + develop_data: DevelopData, + ) -> None: + self.module_precompute(precompute_data) + def prepare( self, agent_info: AgentInfo, diff --git a/adf_core_python/implement/tactics/default_tactics_police_force.py b/adf_core_python/implement/tactics/default_tactics_police_force.py index d605cba..63836a3 100644 --- a/adf_core_python/implement/tactics/default_tactics_police_force.py +++ b/adf_core_python/implement/tactics/default_tactics_police_force.py @@ -7,7 +7,7 @@ from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo -from adf_core_python.core.agent.info.scenario_info import Mode, ScenarioInfo +from adf_core_python.core.agent.info.scenario_info import ScenarioInfo from adf_core_python.core.agent.info.world_info import WorldInfo from adf_core_python.core.agent.module.module_manager import ModuleManager from adf_core_python.core.agent.precompute.precompute_data import PrecomputeData @@ -43,30 +43,28 @@ def initialize( # scenario_info.get_value("clear.repair.distance", "null") # ) - match scenario_info.get_mode(): - case Mode.NON_PRECOMPUTE: - self._search: Search = cast( - Search, - module_manager.get_module( - "DefaultTacticsPoliceForce.Search", - "adf_core_python.core.component.module.complex.search.Search", - ), - ) - self._road_detector: RoadDetector = cast( - RoadDetector, - module_manager.get_module( - "DefaultTacticsPoliceForce.RoadDetector", - "adf_core_python.core.component.module.complex.road_detector.RoadDetector", - ), - ) - self._action_ext_clear = module_manager.get_extend_action( - "DefaultTacticsPoliceForce.ExtendActionClear", - "adf_core_python.implement.action.default_extend_action_clear.DefaultExtendActionClear", - ) - self._action_ext_move = module_manager.get_extend_action( - "DefaultTacticsPoliceForce.ExtendActionMove", - "adf_core_python.implement.action.default_extend_action_move.DefaultExtendActionMove", - ) + self._search: Search = cast( + Search, + module_manager.get_module( + "DefaultTacticsPoliceForce.Search", + "adf_core_python.core.component.module.complex.search.Search", + ), + ) + self._road_detector: RoadDetector = cast( + RoadDetector, + module_manager.get_module( + "DefaultTacticsPoliceForce.RoadDetector", + "adf_core_python.core.component.module.complex.road_detector.RoadDetector", + ), + ) + self._action_ext_clear = module_manager.get_extend_action( + "DefaultTacticsPoliceForce.ExtendActionClear", + "adf_core_python.implement.action.default_extend_action_clear.DefaultExtendActionClear", + ) + self._action_ext_move = module_manager.get_extend_action( + "DefaultTacticsPoliceForce.ExtendActionMove", + "adf_core_python.implement.action.default_extend_action_move.DefaultExtendActionMove", + ) self.register_module(self._search) self.register_module(self._road_detector) self.register_action(self._action_ext_clear) diff --git a/adf_core_python/implement/tactics/default_tactics_police_office.py b/adf_core_python/implement/tactics/default_tactics_police_office.py index f2d54c9..554fe53 100644 --- a/adf_core_python/implement/tactics/default_tactics_police_office.py +++ b/adf_core_python/implement/tactics/default_tactics_police_office.py @@ -3,7 +3,7 @@ from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo -from adf_core_python.core.agent.info.scenario_info import Mode, ScenarioInfo +from adf_core_python.core.agent.info.scenario_info import ScenarioInfo from adf_core_python.core.agent.info.world_info import WorldInfo from adf_core_python.core.agent.module.module_manager import ModuleManager from adf_core_python.core.agent.precompute.precompute_data import PrecomputeData @@ -26,15 +26,13 @@ def initialize( message_manager: MessageManager, develop_data: DevelopData, ) -> None: - match scenario_info.get_mode(): - case Mode.NON_PRECOMPUTE: - self._allocator: TargetAllocator = cast( - TargetAllocator, - module_manager.get_module( - "DefaultTacticsPoliceOffice.TargetAllocator", - "adf_core_python.implement.module.complex.default_police_target_allocator.DefaultPoliceTargetAllocator", - ), - ) + self._allocator: TargetAllocator = cast( + TargetAllocator, + module_manager.get_module( + "DefaultTacticsPoliceOffice.TargetAllocator", + "adf_core_python.implement.module.complex.default_police_target_allocator.DefaultPoliceTargetAllocator", + ), + ) self.register_module(self._allocator) def resume( @@ -49,6 +47,18 @@ def resume( ) -> None: self.module_resume(precompute_data) + def precompute( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + message_manager: MessageManager, + develop_data: DevelopData, + ) -> None: + self.module_precompute(precompute_data) + def prepare( self, agent_info: AgentInfo, diff --git a/adf_core_python/launcher.py b/adf_core_python/launcher.py index 310ff9d..bd2025d 100644 --- a/adf_core_python/launcher.py +++ b/adf_core_python/launcher.py @@ -74,11 +74,10 @@ def __init__( ) parser.add_argument( "--precompute", - type=bool, + action="store_true", help="precompute flag", - metavar="", ) - parser.add_argument("--debug", type=bool, help="debug flag", metavar="") + parser.add_argument("--debug", action="store_true", help="debug flag") args = parser.parse_args() config_map = { diff --git a/config/launcher.yaml b/config/launcher.yaml index 1b6bdfd..7702d17 100644 --- a/config/launcher.yaml +++ b/config/launcher.yaml @@ -13,6 +13,8 @@ adf: agent: moduleconfig: filename: config/module.yaml + precompute: + dir_name: precompute develop: flag: true