From 9477e587a22cf1a8204488fd89e4b5d80c1c7845 Mon Sep 17 00:00:00 2001 From: shima004 Date: Mon, 4 Aug 2025 00:52:08 +0900 Subject: [PATCH 01/13] Update Python version and rcrs_core dependency in pyproject.toml - Bump Python version from 3.12 to 3.13 - Change rcrs_core dependency to point to the "improve" branch of the repository --- .../module/complex/sample_human_detector.py | 28 ++-- .../module/complex/sample_road_detector.py | 14 +- .../team_name/module/complex/sample_search.py | 7 +- adf_core_python/core/agent/action/action.py | 4 +- .../agent/action/ambulance/action_load.py | 11 +- .../agent/action/ambulance/action_rescue.py | 11 +- .../agent/action/ambulance/action_unload.py | 11 +- .../core/agent/action/common/action_move.py | 18 +-- .../core/agent/action/common/action_rest.py | 11 +- .../agent/action/fire/action_extinguish.py | 14 +- .../core/agent/action/fire/action_refill.py | 11 +- .../core/agent/action/fire/action_rescue.py | 11 +- .../core/agent/action/police/action_clear.py | 14 +- .../agent/action/police/action_clear_area.py | 11 +- adf_core_python/core/agent/agent.py | 138 ++++++++++-------- .../bundle/centralized/command_ambulance.py | 2 +- .../bundle/centralized/command_fire.py | 2 +- .../bundle/centralized/command_police.py | 2 +- .../bundle/centralized/command_scout.py | 2 +- .../bundle/centralized/message_report.py | 2 +- .../information/message_ambulance_team.py | 7 +- .../bundle/information/message_building.py | 6 +- .../bundle/information/message_civilian.py | 6 +- .../information/message_fire_brigade.py | 5 +- .../information/message_police_force.py | 5 +- .../bundle/information/message_road.py | 12 +- .../standard/bundle/standard_message.py | 2 +- .../standard/standard_communication_module.py | 4 +- .../standard/utility/apply_to_world_info.py | 20 +-- .../core/agent/config/module_config.py | 2 +- adf_core_python/core/agent/info/agent_info.py | 22 +-- adf_core_python/core/agent/info/world_info.py | 28 ++-- adf_core_python/core/agent/office/office.py | 2 +- .../core/agent/office/office_ambulance.py | 4 +- .../core/agent/office/office_fire.py | 2 +- .../core/agent/office/office_police.py | 2 +- adf_core_python/core/agent/platoon/platoon.py | 2 +- .../core/agent/platoon/platoon_ambulance.py | 2 +- .../core/agent/platoon/platoon_fire.py | 2 +- .../core/agent/platoon/platoon_police.py | 2 +- .../core/component/action/extend_action.py | 2 +- .../component/centralized/command_picker.py | 2 +- .../component/module/algorithm/clustering.py | 4 +- .../module/algorithm/path_planning.py | 2 +- .../complex/ambulance_target_allocator.py | 2 +- .../module/complex/fire_target_allocator.py | 2 +- .../module/complex/human_detector.py | 2 +- .../module/complex/police_target_allocator.py | 2 +- .../component/module/complex/road_detector.py | 2 +- .../core/component/module/complex/search.py | 2 +- .../module/complex/target_allocator.py | 2 +- .../module/complex/target_detector.py | 4 +- .../module/algorithm/gateway_clustering.py | 12 +- .../module/algorithm/gateway_path_planning.py | 8 +- .../module/complex/gateway_human_detector.py | 2 +- .../module/complex/gateway_road_detector.py | 2 +- .../complex/gateway_target_allocator.py | 2 +- .../module/complex/gateway_target_detector.py | 8 +- adf_core_python/core/gateway/gateway_agent.py | 9 +- .../core/gateway/gateway_module.py | 2 +- .../core/gateway/message/am_agent.py | 31 ++-- .../core/gateway/message/am_exec.py | 25 ++-- .../core/gateway/message/am_module.py | 23 ++- .../core/gateway/message/am_update.py | 31 ++-- .../core/gateway/message/ma_exec_response.py | 33 ++--- .../gateway/message/ma_module_response.py | 30 ++-- .../gateway/message/moduleMessageFactory.py | 4 +- adf_core_python/core/logger/logger.py | 6 +- .../action/default_extend_action_clear.py | 69 +++++---- .../action/default_extend_action_move.py | 14 +- .../action/default_extend_action_rescue.py | 25 ++-- .../action/default_extend_action_transport.py | 27 ++-- .../default_command_executor_ambulance.py | 7 +- .../default_command_executor_fire.py | 6 +- .../default_command_executor_police.py | 7 +- .../default_command_executor_scout.py | 14 +- .../default_command_executor_scout_police.py | 14 +- .../default_command_picker_ambulance.py | 9 +- .../default_command_picker_fire.py | 9 +- .../default_command_picker_police.py | 8 +- .../module/algorithm/a_star_path_planning.py | 8 +- .../algorithm/dijkstra_path_planning.py | 7 +- .../module/algorithm/k_means_clustering.py | 36 +++-- .../default_channel_subscriber.py | 6 +- .../default_message_coordinator.py | 4 +- .../default_ambulance_target_allocator.py | 19 +-- .../complex/default_fire_target_allocator.py | 19 +-- .../module/complex/default_human_detector.py | 26 ++-- .../default_police_target_allocator.py | 42 +++--- .../module/complex/default_road_detector.py | 14 +- .../module/complex/default_search.py | 7 +- .../default_tactics_ambulance_center.py | 2 +- .../tactics/default_tactics_ambulance_team.py | 2 +- .../tactics/default_tactics_fire_brigade.py | 2 +- .../tactics/default_tactics_fire_station.py | 2 +- .../tactics/default_tactics_police_force.py | 2 +- .../tactics/default_tactics_police_office.py | 2 +- poetry.lock | 18 +-- pyproject.toml | 4 +- 99 files changed, 533 insertions(+), 615 deletions(-) diff --git a/adf_core_python/cli/template/src/team_name/module/complex/sample_human_detector.py b/adf_core_python/cli/template/src/team_name/module/complex/sample_human_detector.py index 8b44545..1768cfc 100644 --- a/adf_core_python/cli/template/src/team_name/module/complex/sample_human_detector.py +++ b/adf_core_python/cli/template/src/team_name/module/complex/sample_human_detector.py @@ -1,10 +1,7 @@ from typing import Optional, cast -from rcrs_core.connection.URN import Entity as EntityURN -from rcrs_core.entities.civilian import Civilian -from rcrs_core.entities.entity import Entity -from rcrs_core.entities.human import Human -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import Civilian, Entity, EntityID, Human +from rcrscore.urn import EntityURN from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo @@ -46,7 +43,7 @@ def __init__( def calculate(self) -> HumanDetector: transport_human: Optional[Human] = self._agent_info.some_one_on_board() if transport_human is not None: - self._result = transport_human.get_id() + self._result = transport_human.get_entity_id() return self if self._result is not None: @@ -72,44 +69,45 @@ def _select_target(self) -> Optional[EntityID]: cluster_valid_human_entities: list[Entity] = [ entity for entity in cluster_entities - if self._is_valid_human(entity.get_id()) and isinstance(entity, Civilian) + if self._is_valid_human(entity.get_entity_id()) + and isinstance(entity, Civilian) ] if len(cluster_valid_human_entities) != 0: nearest_human_entity = cluster_valid_human_entities[0] nearest_distance = self._world_info.get_distance( self._agent_info.get_entity_id(), - nearest_human_entity.get_id(), + nearest_human_entity.get_entity_id(), ) for entity in cluster_valid_human_entities: distance = self._world_info.get_distance( self._agent_info.get_entity_id(), - entity.get_id(), + entity.get_entity_id(), ) if distance < nearest_distance: nearest_distance = distance nearest_human_entity = entity - return nearest_human_entity.get_id() + return nearest_human_entity.get_entity_id() world_valid_human_entities: list[Entity] = [ entity for entity in self._world_info.get_entities_of_types([Civilian]) - if self._is_valid_human(entity.get_id()) + if self._is_valid_human(entity.get_entity_id()) ] if len(world_valid_human_entities) != 0: nearest_human_entity = world_valid_human_entities[0] nearest_distance = self._world_info.get_distance( self._agent_info.get_entity_id(), - nearest_human_entity.get_id(), + nearest_human_entity.get_entity_id(), ) for entity in world_valid_human_entities: distance = self._world_info.get_distance( self._agent_info.get_entity_id(), - entity.get_id(), + entity.get_entity_id(), ) if distance < nearest_distance: nearest_distance = distance nearest_human_entity = entity - return nearest_human_entity.get_id() + return nearest_human_entity.get_entity_id() return None @@ -126,6 +124,8 @@ def _is_valid_human(self, target_entity_id: EntityID) -> bool: if buriedness is None: return False myself = self._agent_info.get_myself() + if myself is None: + return False if myself.get_urn() == EntityURN.FIRE_BRIGADE and buriedness == 0: return False if myself.get_urn() == EntityURN.AMBULANCE_TEAM and buriedness > 0: 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 2f554db..87e188a 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 @@ -1,10 +1,6 @@ from typing import Optional, cast -from rcrs_core.entities.building import Building -from rcrs_core.entities.gasStation import GasStation -from rcrs_core.entities.refuge import Refuge -from rcrs_core.entities.road import Road -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import Building, EntityID, GasStation, Refuge, Road from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData @@ -59,7 +55,7 @@ def resume(self, precompute_data: PrecomputeData) -> RoadDetector: for entity in entities: if not isinstance(entity, Building): continue - for entity_id in entity.get_neighbours(): + for entity_id in entity.get_neighbors(): neighbor = self._world_info.get_entity(entity_id) if isinstance(neighbor, Road): self._target_areas.add(entity_id) @@ -68,7 +64,7 @@ def resume(self, precompute_data: PrecomputeData) -> RoadDetector: for entity in self._world_info.get_entities_of_types([Refuge]): if not isinstance(entity, Building): continue - for entity_id in entity.get_neighbours(): + for entity_id in entity.get_neighbors(): neighbor = self._world_info.get_entity(entity_id) if isinstance(neighbor, Road): self._priority_roads.add(entity_id) @@ -86,7 +82,7 @@ def prepare(self) -> RoadDetector: ) for entity in entities: building: Building = cast(Building, entity) - for entity_id in building.get_neighbours(): + for entity_id in building.get_neighbors(): neighbor = self._world_info.get_entity(entity_id) if isinstance(neighbor, Road): self._target_areas.add(entity_id) @@ -94,7 +90,7 @@ def prepare(self) -> RoadDetector: self._priority_roads = set() for entity in self._world_info.get_entities_of_types([Refuge]): refuge: Refuge = cast(Refuge, entity) - for entity_id in refuge.get_neighbours(): + for entity_id in refuge.get_neighbors(): neighbor = self._world_info.get_entity(entity_id) if isinstance(neighbor, Road): self._priority_roads.add(entity_id) diff --git a/adf_core_python/cli/template/src/team_name/module/complex/sample_search.py b/adf_core_python/cli/template/src/team_name/module/complex/sample_search.py index d495c49..a441a07 100644 --- a/adf_core_python/cli/template/src/team_name/module/complex/sample_search.py +++ b/adf_core_python/cli/template/src/team_name/module/complex/sample_search.py @@ -1,9 +1,6 @@ from typing import Optional, cast -from rcrs_core.entities.building import Building -from rcrs_core.entities.entity import Entity -from rcrs_core.entities.refuge import Refuge -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import Building, Entity, EntityID, Refuge from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData @@ -98,7 +95,7 @@ def _get_search_targets(self) -> set[EntityID]: cluster_index ) building_entity_ids: list[EntityID] = [ - entity.get_id() + entity.get_entity_id() for entity in cluster_entities if isinstance(entity, Building) and not isinstance(entity, Refuge) ] diff --git a/adf_core_python/core/agent/action/action.py b/adf_core_python/core/agent/action/action.py index c7ab198..911b028 100644 --- a/adf_core_python/core/agent/action/action.py +++ b/adf_core_python/core/agent/action/action.py @@ -1,7 +1,7 @@ from abc import ABC, abstractmethod -from rcrs_core.commands.Command import Command -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.commands import Command +from rcrscore.entities import EntityID class Action(ABC): diff --git a/adf_core_python/core/agent/action/ambulance/action_load.py b/adf_core_python/core/agent/action/ambulance/action_load.py index c7ee299..1e9eee5 100644 --- a/adf_core_python/core/agent/action/ambulance/action_load.py +++ b/adf_core_python/core/agent/action/ambulance/action_load.py @@ -1,15 +1,8 @@ -from typing import TYPE_CHECKING - -from rcrs_core.commands.AKLoad import AKLoad -from rcrs_core.commands.Command import Command -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.commands import AKLoad, Command +from rcrscore.entities import EntityID from adf_core_python.core.agent.action.action import Action -if TYPE_CHECKING: - from rcrs_core.commands.Command import Command - from rcrs_core.worldmodel.entityID import EntityID - class ActionLoad(Action): def __init__(self, target_id: EntityID) -> None: diff --git a/adf_core_python/core/agent/action/ambulance/action_rescue.py b/adf_core_python/core/agent/action/ambulance/action_rescue.py index e4bfb1d..e3ad8e1 100644 --- a/adf_core_python/core/agent/action/ambulance/action_rescue.py +++ b/adf_core_python/core/agent/action/ambulance/action_rescue.py @@ -1,15 +1,8 @@ -from typing import TYPE_CHECKING - -from rcrs_core.commands.AKRescue import AKRescue -from rcrs_core.commands.Command import Command -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.commands import AKRescue, Command +from rcrscore.entities import EntityID from adf_core_python.core.agent.action.action import Action -if TYPE_CHECKING: - from rcrs_core.commands.Command import Command - from rcrs_core.worldmodel.entityID import EntityID - class ActionRescue(Action): def __init__(self, target_id: EntityID) -> None: diff --git a/adf_core_python/core/agent/action/ambulance/action_unload.py b/adf_core_python/core/agent/action/ambulance/action_unload.py index afe3f1a..2f725cb 100644 --- a/adf_core_python/core/agent/action/ambulance/action_unload.py +++ b/adf_core_python/core/agent/action/ambulance/action_unload.py @@ -1,15 +1,8 @@ -from typing import TYPE_CHECKING - -from rcrs_core.commands.AKUnload import AKUnload -from rcrs_core.commands.Command import Command -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.commands import AKUnload, Command +from rcrscore.entities import EntityID from adf_core_python.core.agent.action.action import Action -if TYPE_CHECKING: - from rcrs_core.commands.Command import Command - from rcrs_core.worldmodel.entityID import EntityID - class ActionUnload(Action): def get_command(self, agent_id: EntityID, time: int) -> Command: diff --git a/adf_core_python/core/agent/action/common/action_move.py b/adf_core_python/core/agent/action/common/action_move.py index 2baaba4..c2829a8 100644 --- a/adf_core_python/core/agent/action/common/action_move.py +++ b/adf_core_python/core/agent/action/common/action_move.py @@ -1,15 +1,10 @@ -from typing import TYPE_CHECKING, Optional +from typing import Optional -from rcrs_core.commands.AKMove import AKMove -from rcrs_core.commands.Command import Command -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.commands import AKMove, Command +from rcrscore.entities import EntityID from adf_core_python.core.agent.action.action import Action -if TYPE_CHECKING: - from rcrs_core.commands.Command import Command - from rcrs_core.worldmodel.entityID import EntityID - class ActionMove(Action): def __init__( @@ -32,11 +27,12 @@ def get_destination_y(self) -> Optional[int]: return self.destination_y def get_command(self, agent_id: EntityID, time: int) -> Command: - path: list[int] = [p.get_value() for p in self.path] if self.destination_x is not None and self.destination_y is not None: - return AKMove(agent_id, time, path, self.destination_x, self.destination_y) + return AKMove( + agent_id, time, self.path, self.destination_x, self.destination_y + ) else: - return AKMove(agent_id, time, path) + return AKMove(agent_id, time, self.path) def __str__(self) -> str: path: str = ", ".join([str(p) for p in self.path]) diff --git a/adf_core_python/core/agent/action/common/action_rest.py b/adf_core_python/core/agent/action/common/action_rest.py index ab86c82..94bfaea 100644 --- a/adf_core_python/core/agent/action/common/action_rest.py +++ b/adf_core_python/core/agent/action/common/action_rest.py @@ -1,15 +1,8 @@ -from typing import TYPE_CHECKING - -from rcrs_core.commands.AKRest import AKRest -from rcrs_core.commands.Command import Command -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.commands import AKRest, Command +from rcrscore.entities import EntityID from adf_core_python.core.agent.action.action import Action -if TYPE_CHECKING: - from rcrs_core.commands.Command import Command - from rcrs_core.worldmodel.entityID import EntityID - class ActionRest(Action): def get_command(self, agent_id: EntityID, time: int) -> Command: diff --git a/adf_core_python/core/agent/action/fire/action_extinguish.py b/adf_core_python/core/agent/action/fire/action_extinguish.py index 296bef6..64713a9 100644 --- a/adf_core_python/core/agent/action/fire/action_extinguish.py +++ b/adf_core_python/core/agent/action/fire/action_extinguish.py @@ -1,15 +1,8 @@ -from typing import TYPE_CHECKING - -from rcrs_core.commands.AKExtinguish import AKExtinguish -from rcrs_core.commands.Command import Command -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.commands import AKExtinguish, Command +from rcrscore.entities import EntityID from adf_core_python.core.agent.action.action import Action -if TYPE_CHECKING: - from rcrs_core.commands.Command import Command - from rcrs_core.worldmodel.entityID import EntityID - class ActionExtinguish(Action): def __init__(self, target_id: EntityID, max_power: int) -> None: @@ -17,8 +10,7 @@ def __init__(self, target_id: EntityID, max_power: int) -> None: self.max_power = max_power def get_command(self, agent_id: EntityID, time: int) -> Command: - # TODO: Implement AKEExtinguish - return AKExtinguish() + return AKExtinguish(agent_id, time, self.target_id, self.max_power) def __str__(self) -> str: return ( diff --git a/adf_core_python/core/agent/action/fire/action_refill.py b/adf_core_python/core/agent/action/fire/action_refill.py index bae2cc8..15c0242 100644 --- a/adf_core_python/core/agent/action/fire/action_refill.py +++ b/adf_core_python/core/agent/action/fire/action_refill.py @@ -1,15 +1,8 @@ -from typing import TYPE_CHECKING - -from rcrs_core.commands.AKRest import AKRest -from rcrs_core.commands.Command import Command -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.commands import AKRest, Command +from rcrscore.entities import EntityID from adf_core_python.core.agent.action.action import Action -if TYPE_CHECKING: - from rcrs_core.commands.Command import Command - from rcrs_core.worldmodel.entityID import EntityID - class ActionRefill(Action): def get_command(self, agent_id: EntityID, time: int) -> Command: diff --git a/adf_core_python/core/agent/action/fire/action_rescue.py b/adf_core_python/core/agent/action/fire/action_rescue.py index e4bfb1d..e3ad8e1 100644 --- a/adf_core_python/core/agent/action/fire/action_rescue.py +++ b/adf_core_python/core/agent/action/fire/action_rescue.py @@ -1,15 +1,8 @@ -from typing import TYPE_CHECKING - -from rcrs_core.commands.AKRescue import AKRescue -from rcrs_core.commands.Command import Command -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.commands import AKRescue, Command +from rcrscore.entities import EntityID from adf_core_python.core.agent.action.action import Action -if TYPE_CHECKING: - from rcrs_core.commands.Command import Command - from rcrs_core.worldmodel.entityID import EntityID - class ActionRescue(Action): def __init__(self, target_id: EntityID) -> None: diff --git a/adf_core_python/core/agent/action/police/action_clear.py b/adf_core_python/core/agent/action/police/action_clear.py index b343336..6ba35d3 100644 --- a/adf_core_python/core/agent/action/police/action_clear.py +++ b/adf_core_python/core/agent/action/police/action_clear.py @@ -1,23 +1,15 @@ -from typing import TYPE_CHECKING - -from rcrs_core.commands.AKClear import AKClear -from rcrs_core.commands.Command import Command -from rcrs_core.entities.blockade import Blockade -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.commands import AKClear, Command +from rcrscore.entities import Blockade, EntityID from adf_core_python.core.agent.action.action import Action -if TYPE_CHECKING: - from rcrs_core.commands.Command import Command - from rcrs_core.worldmodel.entityID import EntityID - class ActionClear(Action): def __init__(self, blockade: Blockade) -> None: self.blockade = blockade def get_command(self, agent_id: EntityID, time: int) -> Command: - return AKClear(agent_id, time, self.blockade.get_id()) + return AKClear(agent_id, time, self.blockade.get_entity_id()) def __str__(self) -> str: return f"ActionClear(blockade={self.blockade})" diff --git a/adf_core_python/core/agent/action/police/action_clear_area.py b/adf_core_python/core/agent/action/police/action_clear_area.py index 2531dd5..be92c8a 100644 --- a/adf_core_python/core/agent/action/police/action_clear_area.py +++ b/adf_core_python/core/agent/action/police/action_clear_area.py @@ -1,15 +1,8 @@ -from typing import TYPE_CHECKING - -from rcrs_core.commands.AKClearArea import AKClearArea -from rcrs_core.commands.Command import Command -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.commands import AKClearArea, Command +from rcrscore.entities import EntityID from adf_core_python.core.agent.action.action import Action -if TYPE_CHECKING: - from rcrs_core.commands.Command import Command - from rcrs_core.worldmodel.entityID import EntityID - class ActionClearArea(Action): def __init__(self, position_x: int, position_y: int) -> None: diff --git a/adf_core_python/core/agent/agent.py b/adf_core_python/core/agent/agent.py index b18fb67..e3409c4 100644 --- a/adf_core_python/core/agent/agent.py +++ b/adf_core_python/core/agent/agent.py @@ -5,32 +5,49 @@ from typing import Any, Callable, NoReturn, Optional from bitarray import bitarray -from rcrs_core.commands.AKClear import AKClear -from rcrs_core.commands.AKClearArea import AKClearArea -from rcrs_core.commands.AKLoad import AKLoad -from rcrs_core.commands.AKMove import AKMove -from rcrs_core.commands.AKRescue import AKRescue -from rcrs_core.commands.AKRest import AKRest -from rcrs_core.commands.AKSay import AKSay -from rcrs_core.commands.AKSpeak import AKSpeak -from rcrs_core.commands.AKSubscribe import AKSubscribe -from rcrs_core.commands.AKTell import AKTell -from rcrs_core.commands.AKUnload import AKUnload -from rcrs_core.commands.Command import Command -from rcrs_core.config.config import Config as RCRSConfig -from rcrs_core.connection.URN import Command as CommandURN -from rcrs_core.connection.URN import ComponentCommand as ComponentCommandMessageID -from rcrs_core.connection.URN import ComponentControlMSG as ComponentControlMessageID -from rcrs_core.connection.URN import Entity as EntityURN -from rcrs_core.messages.AKAcknowledge import AKAcknowledge -from rcrs_core.messages.AKConnect import AKConnect -from rcrs_core.messages.controlMessageFactory import ControlMessageFactory -from rcrs_core.messages.KAConnectError import KAConnectError -from rcrs_core.messages.KAConnectOK import KAConnectOK -from rcrs_core.messages.KASense import KASense -from rcrs_core.worldmodel.changeSet import ChangeSet -from rcrs_core.worldmodel.entityID import EntityID -from rcrs_core.worldmodel.worldmodel import WorldModel +from rcrscore.commands import ( + AKClear, + AKClearArea, + AKLoad, + AKMove, + AKRescue, + AKRest, + AKSay, + AKSpeak, + AKSubscribe, + AKTell, + AKUnload, + Command, +) +from rcrscore.config.config import Config as RCRSConfig + +# from rcrscore.connection.URN import Command as CommandURN +# from rcrscore.connection.URN import ComponentCommand as ComponentCommandMessageID +# from rcrscore.connection.URN import ComponentControlMSG as ComponentControlMessageID +# from rcrscore.connection.URN import Entity as EntityURN +from rcrscore.entities import EntityID + +# from rcrscore.messages.AKAcknowledge import AKAcknowledge +# from rcrscore.messages.AKConnect import AKConnect +# from rcrscore.messages.controlMessageFactory import ControlMessageFactory +# from rcrscore.messages.KAConnectError import KAConnectError +# from rcrscore.messages.KAConnectOK import KAConnectOK +# from rcrscore.messages.KASense import KASense +from rcrscore.messages import ( + AKAcknowledge, + AKConnect, + ControlMessageFactory, + KAConnectError, + KAConnectOK, + KASense, +) +from rcrscore.urn import ( + CommandURN, + ComponentCommandURN, + ComponentControlMessageURN, + EntityURN, +) +from rcrscore.worldmodel import ChangeSet, WorldModel from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.communication.standard.bundle.centralized.command_ambulance import ( @@ -229,7 +246,9 @@ def get_requested_entities(self) -> list[EntityURN]: def start_up(self, request_id: int) -> None: ak_connect = AKConnect() - self.send_msg(ak_connect.write(request_id, self)) + self.send_msg( + ak_connect.write(request_id, self.name, self.get_requested_entities()) + ) def message_received(self, msg: Any) -> None: c_msg = ControlMessageFactory().make_message(msg) @@ -264,14 +283,7 @@ def handle_connect_ok(self, msg: Any) -> None: if config is not None: for key, value in config.data.items(): self.config.set_value(key, value) - for key, value in config.int_data.items(): - self.config.set_value(key, value) - for key, value in config.float_data.items(): - self.config.set_value(key, value) - for key, value in config.boolean_data.items(): - self.config.set_value(key, value) - for key, value in config.array_data.items(): - self.config.set_value(key, value) + self.send_acknowledge(msg.request_id) self.post_connect() self.logger.info( @@ -284,8 +296,8 @@ def handle_connect_ok(self, msg: Any) -> None: self.finish_post_connect_event.set() - def handler_sense(self, msg: Any) -> None: - _id = EntityID(msg.agent_id) + def handler_sense(self, msg: KASense) -> None: + _id = msg.agent_id time = msg.time change_set = msg.change_set heard = msg.hear.commands @@ -295,24 +307,20 @@ def handler_sense(self, msg: Any) -> None: return heard_commands: list[Command] = [] - for herad_command in heard: - if herad_command.urn == CommandURN.AK_SPEAK: + for heard_command in heard: + if heard_command.urn == CommandURN.AK_SPEAK: heard_commands.append( AKSpeak( EntityID( - herad_command.components[ - ComponentControlMessageID.AgentID + heard_command.components[ + ComponentControlMessageURN.AgentID ].entityID ), - herad_command.components[ - ComponentControlMessageID.Time - ].intValue, - herad_command.components[ - ComponentCommandMessageID.Message - ].rawData, - herad_command.components[ - ComponentCommandMessageID.Channel + heard_command.components[ + ComponentControlMessageURN.Time ].intValue, + heard_command.components[ComponentCommandURN.Message].rawData, + heard_command.components[ComponentCommandURN.Channel].intValue, ) ) self.world_model.merge(change_set) @@ -328,55 +336,57 @@ def send_acknowledge(self, request_id: int) -> None: def send_clear(self, time: int, target: EntityID) -> None: cmd = AKClear(self.get_entity_id(), time, target) - msg = cmd.prepare_cmd() + msg = cmd.to_message_proto() self.send_msg(msg) def send_clear_area(self, time: int, x: int = -1, y: int = -1) -> None: cmd = AKClearArea(self.get_entity_id(), time, x, y) - msg = cmd.prepare_cmd() + msg = cmd.to_message_proto() self.send_msg(msg) def send_load(self, time: int, target: EntityID) -> None: cmd = AKLoad(self.get_entity_id(), time, target) - msg = cmd.prepare_cmd() + msg = cmd.to_message_proto() self.send_msg(msg) - def send_move(self, time: int, path: list[int], x: int = -1, y: int = -1) -> None: - cmd = AKMove(self.get_entity_id(), time, path[:], x, y) - msg = cmd.prepare_cmd() + def send_move( + self, time: int, path: list[EntityID], x: int = -1, y: int = -1 + ) -> None: + cmd = AKMove(self.get_entity_id(), time, path, x, y) + msg = cmd.to_message_proto() self.send_msg(msg) def send_rescue(self, time: int, target: EntityID) -> None: cmd = AKRescue(self.get_entity_id(), time, target) - msg = cmd.prepare_cmd() + msg = cmd.to_message_proto() self.send_msg(msg) def send_rest(self, time: int) -> None: cmd = AKRest(self.get_entity_id(), time) - msg = cmd.prepare_cmd() + msg = cmd.to_message_proto() self.send_msg(msg) - def send_say(self, time_step: int, message: str) -> None: + def send_say(self, time_step: int, message: bytes) -> None: cmd = AKSay(self.get_entity_id(), time_step, message) - msg = cmd.prepare_cmd() + msg = cmd.to_message_proto() self.send_msg(msg) def send_speak(self, time_step: int, message: bitarray, channel: int) -> None: cmd = AKSpeak(self.get_entity_id(), time_step, bytes(message), channel) # type: ignore - msg = cmd.prepare_cmd() + msg = cmd.to_message_proto() self.send_msg(msg) def send_subscribe(self, time: int, channels: list[int]) -> None: cmd = AKSubscribe(self.get_entity_id(), time, channels) - msg = cmd.prepare_cmd() + msg = cmd.to_message_proto() self.send_msg(msg) - def send_tell(self, time: int, message: str) -> None: + def send_tell(self, time: int, message: bytes) -> None: cmd = AKTell(self.get_entity_id(), time, message) - msg = cmd.prepare_cmd() + msg = cmd.to_message_proto() self.send_msg(msg) def send_unload(self, time: int) -> None: cmd = AKUnload(self.get_entity_id(), time) - msg = cmd.prepare_cmd() + msg = cmd.to_message_proto() self.send_msg(msg) diff --git a/adf_core_python/core/agent/communication/standard/bundle/centralized/command_ambulance.py b/adf_core_python/core/agent/communication/standard/bundle/centralized/command_ambulance.py index a5d6984..1a0a2f0 100644 --- a/adf_core_python/core/agent/communication/standard/bundle/centralized/command_ambulance.py +++ b/adf_core_python/core/agent/communication/standard/bundle/centralized/command_ambulance.py @@ -3,7 +3,7 @@ from typing import Optional from bitarray import bitarray -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import EntityID from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( StandardMessage, diff --git a/adf_core_python/core/agent/communication/standard/bundle/centralized/command_fire.py b/adf_core_python/core/agent/communication/standard/bundle/centralized/command_fire.py index cf61131..a4bd8ae 100644 --- a/adf_core_python/core/agent/communication/standard/bundle/centralized/command_fire.py +++ b/adf_core_python/core/agent/communication/standard/bundle/centralized/command_fire.py @@ -3,7 +3,7 @@ from typing import Optional from bitarray import bitarray -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import EntityID from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( StandardMessage, diff --git a/adf_core_python/core/agent/communication/standard/bundle/centralized/command_police.py b/adf_core_python/core/agent/communication/standard/bundle/centralized/command_police.py index 64b8e34..c57f2fb 100644 --- a/adf_core_python/core/agent/communication/standard/bundle/centralized/command_police.py +++ b/adf_core_python/core/agent/communication/standard/bundle/centralized/command_police.py @@ -3,7 +3,7 @@ from typing import Optional from bitarray import bitarray -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import EntityID from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( StandardMessage, diff --git a/adf_core_python/core/agent/communication/standard/bundle/centralized/command_scout.py b/adf_core_python/core/agent/communication/standard/bundle/centralized/command_scout.py index 138a1dd..4d82478 100644 --- a/adf_core_python/core/agent/communication/standard/bundle/centralized/command_scout.py +++ b/adf_core_python/core/agent/communication/standard/bundle/centralized/command_scout.py @@ -3,7 +3,7 @@ from typing import Optional from bitarray import bitarray -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import EntityID from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( StandardMessage, diff --git a/adf_core_python/core/agent/communication/standard/bundle/centralized/message_report.py b/adf_core_python/core/agent/communication/standard/bundle/centralized/message_report.py index 55f8907..99cf589 100644 --- a/adf_core_python/core/agent/communication/standard/bundle/centralized/message_report.py +++ b/adf_core_python/core/agent/communication/standard/bundle/centralized/message_report.py @@ -1,7 +1,7 @@ from __future__ import annotations from bitarray import bitarray -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import EntityID from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( StandardMessage, diff --git a/adf_core_python/core/agent/communication/standard/bundle/information/message_ambulance_team.py b/adf_core_python/core/agent/communication/standard/bundle/information/message_ambulance_team.py index 3a74aba..2fbe0ea 100644 --- a/adf_core_python/core/agent/communication/standard/bundle/information/message_ambulance_team.py +++ b/adf_core_python/core/agent/communication/standard/bundle/information/message_ambulance_team.py @@ -3,8 +3,7 @@ from typing import Optional from bitarray import bitarray -from rcrs_core.entities.ambulanceTeam import AmbulanceTeam -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import AmbulanceTeam, EntityID from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( StandardMessage, @@ -44,7 +43,9 @@ def __init__( ttl: Optional[int] = None, ): super().__init__(is_wireless_message, priority, sender_entity_id, ttl) - self._ambulance_team_entity_id: Optional[EntityID] = ambulance_team.get_id() + self._ambulance_team_entity_id: Optional[EntityID] = ( + ambulance_team.get_entity_id() + ) self._ambulance_team_hp: Optional[int] = ambulance_team.get_hp() or None self._ambulance_team_buriedness: Optional[int] = ( ambulance_team.get_buriedness() or None diff --git a/adf_core_python/core/agent/communication/standard/bundle/information/message_building.py b/adf_core_python/core/agent/communication/standard/bundle/information/message_building.py index be9f911..586f836 100644 --- a/adf_core_python/core/agent/communication/standard/bundle/information/message_building.py +++ b/adf_core_python/core/agent/communication/standard/bundle/information/message_building.py @@ -3,8 +3,8 @@ from typing import Optional from bitarray import bitarray -from rcrs_core.entities.building import Building -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import EntityID +from rcrscore.entities.building import Building from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( StandardMessage, @@ -33,7 +33,7 @@ def __init__( ttl: Optional[int] = None, ): super().__init__(is_wireless_message, priority, sender_entity_id, ttl) - self._building_entity_id: Optional[EntityID] = building.get_id() + self._building_entity_id: Optional[EntityID] = building.get_entity_id() self._building_brokenness: Optional[int] = building.get_brokenness() or None self._building_fireyness: Optional[int] = building.get_fieryness() or None self._building_temperature: Optional[int] = building.get_temperature() or None diff --git a/adf_core_python/core/agent/communication/standard/bundle/information/message_civilian.py b/adf_core_python/core/agent/communication/standard/bundle/information/message_civilian.py index a5a62b4..79b4ae7 100644 --- a/adf_core_python/core/agent/communication/standard/bundle/information/message_civilian.py +++ b/adf_core_python/core/agent/communication/standard/bundle/information/message_civilian.py @@ -3,8 +3,8 @@ from typing import Optional from bitarray import bitarray -from rcrs_core.entities.civilian import Civilian -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import EntityID +from rcrscore.entities.civilian import Civilian from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( StandardMessage, @@ -34,7 +34,7 @@ def __init__( ttl: Optional[int] = None, ): super().__init__(is_wireless_message, priority, sender_entity_id, ttl) - self._civilian_entity_id: Optional[EntityID] = civilian.get_id() + self._civilian_entity_id: Optional[EntityID] = civilian.get_entity_id() self._civilian_hp: Optional[int] = civilian.get_hp() or None self._civilian_buriedness: Optional[int] = civilian.get_buriedness() or None self._civilian_damage: Optional[int] = civilian.get_damage() or None diff --git a/adf_core_python/core/agent/communication/standard/bundle/information/message_fire_brigade.py b/adf_core_python/core/agent/communication/standard/bundle/information/message_fire_brigade.py index feefd51..0f41702 100644 --- a/adf_core_python/core/agent/communication/standard/bundle/information/message_fire_brigade.py +++ b/adf_core_python/core/agent/communication/standard/bundle/information/message_fire_brigade.py @@ -3,8 +3,7 @@ from typing import Optional from bitarray import bitarray -from rcrs_core.entities.fireBrigade import FireBrigade -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import EntityID, FireBrigade from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( StandardMessage, @@ -45,7 +44,7 @@ def __init__( ttl: Optional[int] = None, ): super().__init__(is_wireless_message, priority, sender_entity_id, ttl) - self._fire_brigade_entity_id: Optional[EntityID] = fire_brigade.get_id() + self._fire_brigade_entity_id: Optional[EntityID] = fire_brigade.get_entity_id() self._fire_brigade_hp: Optional[int] = fire_brigade.get_hp() or None self._fire_brigade_buriedness: Optional[int] = ( fire_brigade.get_buriedness() or None diff --git a/adf_core_python/core/agent/communication/standard/bundle/information/message_police_force.py b/adf_core_python/core/agent/communication/standard/bundle/information/message_police_force.py index f37432d..f4b72d0 100644 --- a/adf_core_python/core/agent/communication/standard/bundle/information/message_police_force.py +++ b/adf_core_python/core/agent/communication/standard/bundle/information/message_police_force.py @@ -3,8 +3,7 @@ from typing import Optional from bitarray import bitarray -from rcrs_core.entities.policeForce import PoliceForce -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import EntityID, PoliceForce from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( StandardMessage, @@ -42,7 +41,7 @@ def __init__( ttl: Optional[int] = None, ): super().__init__(is_wireless_message, priority, sender_entity_id, ttl) - self._police_force_entity_id: Optional[EntityID] = police_force.get_id() + self._police_force_entity_id: Optional[EntityID] = police_force.get_entity_id() self._police_force_hp: Optional[int] = police_force.get_hp() or None self._police_force_buriedness: Optional[int] = ( police_force.get_buriedness() or None diff --git a/adf_core_python/core/agent/communication/standard/bundle/information/message_road.py b/adf_core_python/core/agent/communication/standard/bundle/information/message_road.py index 474421c..747bfb5 100644 --- a/adf_core_python/core/agent/communication/standard/bundle/information/message_road.py +++ b/adf_core_python/core/agent/communication/standard/bundle/information/message_road.py @@ -3,9 +3,7 @@ from typing import Optional from bitarray import bitarray -from rcrs_core.entities.blockade import Blockade -from rcrs_core.entities.road import Road -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import Blockade, EntityID, Road from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( StandardMessage, @@ -43,15 +41,15 @@ def __init__( ttl: Optional[int] = None, ): super().__init__(is_wireless_message, priority, sender_entity_id, ttl) - self._road_entity_id: Optional[EntityID] = road.get_id() + self._road_entity_id: Optional[EntityID] = road.get_entity_id() self._road_blockade_entity_id: Optional[EntityID] = None self._road_blockade_repair_cost: Optional[int] = None self._road_blockade_x: Optional[int] = None self._road_blockade_y: Optional[int] = None if blockade: - self._road_blockade_entity_id = blockade.get_id() - self._road_blockade_repair_cost = blockade.get_repaire_cost() + self._road_blockade_entity_id = blockade.get_entity_id() + self._road_blockade_repair_cost = blockade.get_repair_cost() if is_send_blockade_location: self._road_blockade_x = blockade.get_x() or None self._road_blockade_y = blockade.get_y() or None @@ -146,7 +144,7 @@ def from_bits( ) road = Road(road_id or -1) blockade = Blockade(road_blockade_id or -1) - blockade.set_repaire_cost(road_blockade_repair_cost) + blockade.set_repair_cost(road_blockade_repair_cost) blockade.set_x(road_blockade_x) blockade.set_y(road_blockade_y) return MessageRoad( diff --git a/adf_core_python/core/agent/communication/standard/bundle/standard_message.py b/adf_core_python/core/agent/communication/standard/bundle/standard_message.py index bdec11b..34ec8f9 100644 --- a/adf_core_python/core/agent/communication/standard/bundle/standard_message.py +++ b/adf_core_python/core/agent/communication/standard/bundle/standard_message.py @@ -3,7 +3,7 @@ from typing import Optional from bitarray import bitarray -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import EntityID from adf_core_python.core.agent.communication.standard.bundle.standard_message_priority import ( StandardMessagePriority, diff --git a/adf_core_python/core/agent/communication/standard/standard_communication_module.py b/adf_core_python/core/agent/communication/standard/standard_communication_module.py index 3fdffb3..f502651 100644 --- a/adf_core_python/core/agent/communication/standard/standard_communication_module.py +++ b/adf_core_python/core/agent/communication/standard/standard_communication_module.py @@ -3,8 +3,8 @@ from typing import TYPE_CHECKING from bitarray import bitarray -from rcrs_core.commands.AKSpeak import AKSpeak -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.commands import AKSpeak +from rcrscore.entities import EntityID from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( diff --git a/adf_core_python/core/agent/communication/standard/utility/apply_to_world_info.py b/adf_core_python/core/agent/communication/standard/utility/apply_to_world_info.py index c1e7020..56b1f8f 100644 --- a/adf_core_python/core/agent/communication/standard/utility/apply_to_world_info.py +++ b/adf_core_python/core/agent/communication/standard/utility/apply_to_world_info.py @@ -1,10 +1,12 @@ -from rcrs_core.entities.ambulanceTeam import AmbulanceTeam -from rcrs_core.entities.blockade import Blockade -from rcrs_core.entities.building import Building -from rcrs_core.entities.civilian import Civilian -from rcrs_core.entities.fireBrigade import FireBrigade -from rcrs_core.entities.policeForce import PoliceForce -from rcrs_core.entities.road import Road +from rcrscore.entities import ( + AmbulanceTeam, + Blockade, + Building, + Civilian, + FireBrigade, + PoliceForce, + Road, +) from adf_core_python.core.agent.communication.standard.bundle.information.message_ambulance_team import ( MessageAmbulanceTeam, @@ -317,7 +319,7 @@ def _apply_to_world_info_road( if blockade is None: road_blockade = Blockade(blockade_entity_id.get_value()) if (repair_cost := message_road.get_road_blockade_repair_cost()) is not None: - road_blockade.set_repaire_cost(repair_cost) + road_blockade.set_repair_cost(repair_cost) if (x := message_road.get_road_blockade_x()) is not None: road_blockade.set_x(x) if (y := message_road.get_road_blockade_y()) is not None: @@ -328,7 +330,7 @@ def _apply_to_world_info_road( if ( repair_cost := message_road.get_road_blockade_repair_cost() ) is not None: - blockade.set_repaire_cost(repair_cost) + blockade.set_repair_cost(repair_cost) if (x := message_road.get_road_blockade_x()) is not None: blockade.set_x(x) if (y := message_road.get_road_blockade_y()) is not None: diff --git a/adf_core_python/core/agent/config/module_config.py b/adf_core_python/core/agent/config/module_config.py index 72a292a..7c65649 100644 --- a/adf_core_python/core/agent/config/module_config.py +++ b/adf_core_python/core/agent/config/module_config.py @@ -1,6 +1,6 @@ from typing import Any, Final -from rcrs_core.config.config import Config +from rcrscore.config.config import Config from yaml import safe_load diff --git a/adf_core_python/core/agent/info/agent_info.py b/adf_core_python/core/agent/info/agent_info.py index 23f6657..5dea6a5 100644 --- a/adf_core_python/core/agent/info/agent_info.py +++ b/adf_core_python/core/agent/info/agent_info.py @@ -3,13 +3,12 @@ from time import time from typing import TYPE_CHECKING -from rcrs_core.commands.Command import Command -from rcrs_core.entities.civilian import Civilian -from rcrs_core.entities.entity import Entity -from rcrs_core.entities.human import Human -from rcrs_core.worldmodel.changeSet import ChangeSet -from rcrs_core.worldmodel.entityID import EntityID -from rcrs_core.worldmodel.worldmodel import WorldModel +from rcrscore.commands import Command +from rcrscore.entities import EntityID +from rcrscore.entities.civilian import Civilian +from rcrscore.entities.entity import Entity +from rcrscore.entities.human import Human +from rcrscore.worldmodel import ChangeSet, WorldModel from adf_core_python.core.agent.action.action import Action @@ -83,7 +82,7 @@ def get_entity_id(self) -> EntityID: # TODO: Agent class should return EntityID instead of EntityID | None return self._agent.get_entity_id() - def get_myself(self) -> Entity: + def get_myself(self) -> Entity | None: """ Get the entity of the agent @@ -94,7 +93,7 @@ def get_myself(self) -> Entity: """ return self._world_model.get_entity(self.get_entity_id()) - def get_position_entity_id(self) -> EntityID: + def get_position_entity_id(self) -> EntityID | None: """ Get the position entity ID of the agent @@ -104,10 +103,13 @@ def get_position_entity_id(self) -> EntityID: Position entity ID of the agent """ entity = self._world_model.get_entity(self.get_entity_id()) + if entity is None: + return None + if isinstance(entity, Human): return entity.get_position() else: - return entity.get_id() + return entity.get_entity_id() def set_change_set(self, change_set: ChangeSet) -> None: """ diff --git a/adf_core_python/core/agent/info/world_info.py b/adf_core_python/core/agent/info/world_info.py index c4dec84..8ac55c9 100644 --- a/adf_core_python/core/agent/info/world_info.py +++ b/adf_core_python/core/agent/info/world_info.py @@ -1,12 +1,11 @@ from typing import Any, Optional, cast -from rcrs_core.entities.area import Area -from rcrs_core.entities.blockade import Blockade -from rcrs_core.entities.entity import Entity -from rcrs_core.entities.human import Human -from rcrs_core.worldmodel.changeSet import ChangeSet -from rcrs_core.worldmodel.entityID import EntityID -from rcrs_core.worldmodel.worldmodel import WorldModel +from rcrscore.entities import EntityID +from rcrscore.entities.area import Area +from rcrscore.entities.blockade import Blockade +from rcrscore.entities.entity import Entity +from rcrscore.entities.human import Human +from rcrscore.worldmodel import ChangeSet, WorldModel class WorldInfo: @@ -74,7 +73,7 @@ def get_entity_ids_of_types( entity_ids: list[EntityID] = [] for entity in self._world_model.get_entities(): if any(isinstance(entity, entity_type) for entity_type in entity_types): - entity_ids.append(entity.get_id()) + entity_ids.append(entity.get_entity_id()) return entity_ids @@ -145,7 +144,7 @@ def get_distance(self, entity_id1: EntityID, entity_id2: EntityID) -> float: return distance - def get_entity_position(self, entity_id: EntityID) -> EntityID: + def get_entity_position(self, entity_id: EntityID) -> EntityID | None: """ Get the entity position @@ -168,7 +167,7 @@ def get_entity_position(self, entity_id: EntityID) -> EntityID: if entity is None: raise ValueError(f"Invalid entity: entity_id={entity_id}, entity={entity}") if isinstance(entity, Area): - return entity.get_id() + return entity.get_entity_id() if isinstance(entity, Human): return entity.get_position() if isinstance(entity, Blockade): @@ -196,10 +195,11 @@ def get_blockades(self, area: Area) -> set[Blockade]: Blockade """ blockades = set() - for blockade_entity_id in area.get_blockades(): - blockades_entity = self.get_entity(blockade_entity_id) - if isinstance(blockades_entity, Blockade): - blockades.add(cast(Blockade, blockades_entity)) + if blockade_entity_ids := area.get_blockades(): + for blockade_entity_id in blockade_entity_ids: + blockades_entity = self.get_entity(blockade_entity_id) + if isinstance(blockades_entity, Blockade): + blockades.add(cast(Blockade, blockades_entity)) return blockades def add_entity(self, entity: Entity) -> None: diff --git a/adf_core_python/core/agent/office/office.py b/adf_core_python/core/agent/office/office.py index ae06c87..ea9a3b8 100644 --- a/adf_core_python/core/agent/office/office.py +++ b/adf_core_python/core/agent/office/office.py @@ -129,5 +129,5 @@ def think(self) -> None: self.send_msg( ActionRest() .get_command(self.agent_id, self._agent_info.get_time()) - .prepare_cmd() + .to_message_proto() ) diff --git a/adf_core_python/core/agent/office/office_ambulance.py b/adf_core_python/core/agent/office/office_ambulance.py index f746fd5..1df7e5e 100644 --- a/adf_core_python/core/agent/office/office_ambulance.py +++ b/adf_core_python/core/agent/office/office_ambulance.py @@ -1,7 +1,7 @@ from threading import Event from typing import Optional -from rcrs_core.connection.URN import Entity as EntityURN +from rcrscore.urn import EntityURN from adf_core_python.core.agent.config.module_config import ModuleConfig from adf_core_python.core.agent.develop.develop_data import DevelopData @@ -39,4 +39,4 @@ def precompute(self) -> None: pass def get_requested_entities(self) -> list[EntityURN]: - return [EntityURN.AMBULANCE_CENTRE] + return [EntityURN.AMBULANCE_CENTER] diff --git a/adf_core_python/core/agent/office/office_fire.py b/adf_core_python/core/agent/office/office_fire.py index 6128edd..766e35a 100644 --- a/adf_core_python/core/agent/office/office_fire.py +++ b/adf_core_python/core/agent/office/office_fire.py @@ -1,7 +1,7 @@ from threading import Event from typing import Optional -from rcrs_core.connection.URN import Entity as EntityURN +from rcrscore.urn import EntityURN from adf_core_python.core.agent.config.module_config import ModuleConfig from adf_core_python.core.agent.develop.develop_data import DevelopData diff --git a/adf_core_python/core/agent/office/office_police.py b/adf_core_python/core/agent/office/office_police.py index 9717ac2..67d4cc3 100644 --- a/adf_core_python/core/agent/office/office_police.py +++ b/adf_core_python/core/agent/office/office_police.py @@ -1,7 +1,7 @@ from threading import Event from typing import Optional -from rcrs_core.connection.URN import Entity as EntityURN +from rcrscore.urn import EntityURN from adf_core_python.core.agent.config.module_config import ModuleConfig from adf_core_python.core.agent.develop.develop_data import DevelopData diff --git a/adf_core_python/core/agent/platoon/platoon.py b/adf_core_python/core/agent/platoon/platoon.py index 2f2781c..8e9788c 100644 --- a/adf_core_python/core/agent/platoon/platoon.py +++ b/adf_core_python/core/agent/platoon/platoon.py @@ -133,5 +133,5 @@ def think(self) -> None: self.send_msg( action.get_command( self.agent_id, self._agent_info.get_time() - ).prepare_cmd() + ).to_message_proto() ) diff --git a/adf_core_python/core/agent/platoon/platoon_ambulance.py b/adf_core_python/core/agent/platoon/platoon_ambulance.py index 0daad4a..16a1127 100644 --- a/adf_core_python/core/agent/platoon/platoon_ambulance.py +++ b/adf_core_python/core/agent/platoon/platoon_ambulance.py @@ -1,7 +1,7 @@ from threading import Event from typing import Optional -from rcrs_core.connection.URN import Entity as EntityURN +from rcrscore.urn import EntityURN from adf_core_python.core.agent.config.module_config import ModuleConfig from adf_core_python.core.agent.develop.develop_data import DevelopData diff --git a/adf_core_python/core/agent/platoon/platoon_fire.py b/adf_core_python/core/agent/platoon/platoon_fire.py index 8debf99..13db7e0 100644 --- a/adf_core_python/core/agent/platoon/platoon_fire.py +++ b/adf_core_python/core/agent/platoon/platoon_fire.py @@ -1,7 +1,7 @@ from threading import Event from typing import Optional -from rcrs_core.connection.URN import Entity as EntityURN +from rcrscore.urn import EntityURN from adf_core_python.core.agent.config.module_config import ModuleConfig from adf_core_python.core.agent.develop.develop_data import DevelopData diff --git a/adf_core_python/core/agent/platoon/platoon_police.py b/adf_core_python/core/agent/platoon/platoon_police.py index 441602f..8f9c33a 100644 --- a/adf_core_python/core/agent/platoon/platoon_police.py +++ b/adf_core_python/core/agent/platoon/platoon_police.py @@ -1,7 +1,7 @@ from threading import Event from typing import Optional -from rcrs_core.connection.URN import Entity as EntityURN +from rcrscore.urn import EntityURN from adf_core_python.core.agent.config.module_config import ModuleConfig from adf_core_python.core.agent.develop.develop_data import DevelopData diff --git a/adf_core_python/core/component/action/extend_action.py b/adf_core_python/core/component/action/extend_action.py index fece605..1688e62 100644 --- a/adf_core_python/core/component/action/extend_action.py +++ b/adf_core_python/core/component/action/extend_action.py @@ -4,7 +4,7 @@ from typing import TYPE_CHECKING, Optional if TYPE_CHECKING: - from rcrs_core.worldmodel.entityID import EntityID + from rcrscore.entities import EntityID from adf_core_python.core.agent.action.action import Action from adf_core_python.core.agent.communication.message_manager import MessageManager diff --git a/adf_core_python/core/component/centralized/command_picker.py b/adf_core_python/core/component/centralized/command_picker.py index 19c869a..8fcea2f 100644 --- a/adf_core_python/core/component/centralized/command_picker.py +++ b/adf_core_python/core/component/centralized/command_picker.py @@ -3,7 +3,7 @@ from abc import ABC, abstractmethod from typing import TYPE_CHECKING -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import EntityID if TYPE_CHECKING: from adf_core_python.core.agent.develop.develop_data import DevelopData diff --git a/adf_core_python/core/component/module/algorithm/clustering.py b/adf_core_python/core/component/module/algorithm/clustering.py index 0a6bfdc..2594cb9 100644 --- a/adf_core_python/core/component/module/algorithm/clustering.py +++ b/adf_core_python/core/component/module/algorithm/clustering.py @@ -6,8 +6,8 @@ from adf_core_python.core.component.module.abstract_module import AbstractModule if TYPE_CHECKING: - from rcrs_core.entities.entity import Entity - from rcrs_core.worldmodel.entityID import EntityID + from rcrscore.entities import EntityID + from rcrscore.entities.entity import Entity from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData diff --git a/adf_core_python/core/component/module/algorithm/path_planning.py b/adf_core_python/core/component/module/algorithm/path_planning.py index 6445ac0..d7318f1 100644 --- a/adf_core_python/core/component/module/algorithm/path_planning.py +++ b/adf_core_python/core/component/module/algorithm/path_planning.py @@ -6,7 +6,7 @@ from adf_core_python.core.component.module.abstract_module import AbstractModule if TYPE_CHECKING: - from rcrs_core.worldmodel.entityID import EntityID + from rcrscore.entities import EntityID from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData diff --git a/adf_core_python/core/component/module/complex/ambulance_target_allocator.py b/adf_core_python/core/component/module/complex/ambulance_target_allocator.py index 7359e68..63e5a5f 100644 --- a/adf_core_python/core/component/module/complex/ambulance_target_allocator.py +++ b/adf_core_python/core/component/module/complex/ambulance_target_allocator.py @@ -8,7 +8,7 @@ ) if TYPE_CHECKING: - from rcrs_core.worldmodel.entityID import EntityID + from rcrscore.entities import EntityID from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData diff --git a/adf_core_python/core/component/module/complex/fire_target_allocator.py b/adf_core_python/core/component/module/complex/fire_target_allocator.py index 9e35373..2cf3ec2 100644 --- a/adf_core_python/core/component/module/complex/fire_target_allocator.py +++ b/adf_core_python/core/component/module/complex/fire_target_allocator.py @@ -8,7 +8,7 @@ ) if TYPE_CHECKING: - from rcrs_core.worldmodel.entityID import EntityID + from rcrscore.entities import EntityID from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData diff --git a/adf_core_python/core/component/module/complex/human_detector.py b/adf_core_python/core/component/module/complex/human_detector.py index 10a31e2..0e7ae6c 100644 --- a/adf_core_python/core/component/module/complex/human_detector.py +++ b/adf_core_python/core/component/module/complex/human_detector.py @@ -3,7 +3,7 @@ from abc import abstractmethod from typing import TYPE_CHECKING -from rcrs_core.entities.human import Human +from rcrscore.entities.human import Human from adf_core_python.core.component.module.complex.target_detector import ( TargetDetector, diff --git a/adf_core_python/core/component/module/complex/police_target_allocator.py b/adf_core_python/core/component/module/complex/police_target_allocator.py index bf31d15..a066304 100644 --- a/adf_core_python/core/component/module/complex/police_target_allocator.py +++ b/adf_core_python/core/component/module/complex/police_target_allocator.py @@ -8,7 +8,7 @@ ) if TYPE_CHECKING: - from rcrs_core.worldmodel.entityID import EntityID + from rcrscore.entities import EntityID from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData diff --git a/adf_core_python/core/component/module/complex/road_detector.py b/adf_core_python/core/component/module/complex/road_detector.py index 08b552d..888ea96 100644 --- a/adf_core_python/core/component/module/complex/road_detector.py +++ b/adf_core_python/core/component/module/complex/road_detector.py @@ -3,7 +3,7 @@ from abc import abstractmethod from typing import TYPE_CHECKING -from rcrs_core.entities.road import Road +from rcrscore.entities.road import Road from adf_core_python.core.component.module.complex.target_detector import ( TargetDetector, diff --git a/adf_core_python/core/component/module/complex/search.py b/adf_core_python/core/component/module/complex/search.py index 7715831..bfeddef 100644 --- a/adf_core_python/core/component/module/complex/search.py +++ b/adf_core_python/core/component/module/complex/search.py @@ -3,7 +3,7 @@ from abc import abstractmethod from typing import TYPE_CHECKING -from rcrs_core.entities.area import Area +from rcrscore.entities.area import Area from adf_core_python.core.component.module.complex.target_detector import ( TargetDetector, diff --git a/adf_core_python/core/component/module/complex/target_allocator.py b/adf_core_python/core/component/module/complex/target_allocator.py index 55869c9..88ef50f 100644 --- a/adf_core_python/core/component/module/complex/target_allocator.py +++ b/adf_core_python/core/component/module/complex/target_allocator.py @@ -6,7 +6,7 @@ from adf_core_python.core.component.module.abstract_module import AbstractModule if TYPE_CHECKING: - from rcrs_core.worldmodel.entityID import EntityID + from rcrscore.entities import EntityID from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData diff --git a/adf_core_python/core/component/module/complex/target_detector.py b/adf_core_python/core/component/module/complex/target_detector.py index 29fb4df..21a79e4 100644 --- a/adf_core_python/core/component/module/complex/target_detector.py +++ b/adf_core_python/core/component/module/complex/target_detector.py @@ -3,12 +3,12 @@ from abc import abstractmethod from typing import TYPE_CHECKING, Generic, Optional, TypeVar -from rcrs_core.entities.entity import Entity +from rcrscore.entities.entity import Entity from adf_core_python.core.component.module.abstract_module import AbstractModule if TYPE_CHECKING: - from rcrs_core.worldmodel.entityID import EntityID + from rcrscore.entities import EntityID from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData diff --git a/adf_core_python/core/gateway/component/module/algorithm/gateway_clustering.py b/adf_core_python/core/gateway/component/module/algorithm/gateway_clustering.py index 6518770..ade93a0 100644 --- a/adf_core_python/core/gateway/component/module/algorithm/gateway_clustering.py +++ b/adf_core_python/core/gateway/component/module/algorithm/gateway_clustering.py @@ -3,7 +3,7 @@ import json from typing import TYPE_CHECKING -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import EntityID from adf_core_python.core.component.module.algorithm.clustering import Clustering from adf_core_python.core.gateway.component.module.gateway_abstract_module import ( @@ -11,7 +11,7 @@ ) if TYPE_CHECKING: - from rcrs_core.entities.entity import Entity + from rcrscore.entities.entity import Entity from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData @@ -64,17 +64,17 @@ def calculate(self) -> GatewayClustering: def get_cluster_number(self) -> int: result = self._gateway_module.execute("getClusterNumber") - return int(result.get_value_or_default("ClusterNumber", "0")) + return int(result.get_value("ClusterNumber") or 0) def get_cluster_index(self, entity_id: EntityID) -> int: arguments: dict[str, str] = {"EntityID": str(entity_id.get_value())} result = self._gateway_module.execute("getClusterIndex(EntityID)", arguments) - return int(result.get_value_or_default("ClusterIndex", "0")) + return int(result.get_value("ClusterIndex") or 0) def get_cluster_entities(self, cluster_index: int) -> list[Entity]: arguments: dict[str, str] = {"Index": str(cluster_index)} result = self._gateway_module.execute("getClusterEntities(int)", arguments) - json_str = result.get_value_or_default("EntityIDs", "[]") + json_str = result.get_value("EntityIDs") or "[]" entity_ids: list[int] = json.loads(json_str) entities: list[Entity] = [] for entity_id in entity_ids: @@ -84,7 +84,7 @@ def get_cluster_entities(self, cluster_index: int) -> list[Entity]: def get_cluster_entity_ids(self, cluster_index: int) -> list[EntityID]: arguments: dict[str, str] = {"Index": str(cluster_index)} result = self._gateway_module.execute("getClusterEntityIDs(int)", arguments) - json_str = result.get_value_or_default("EntityIDs", "[]") + json_str = result.get_value("EntityIDs") or "[]" raw_entity_ids: list[int] = json.loads(json_str) entity_ids: list[EntityID] = [] for entity_id in raw_entity_ids: diff --git a/adf_core_python/core/gateway/component/module/algorithm/gateway_path_planning.py b/adf_core_python/core/gateway/component/module/algorithm/gateway_path_planning.py index 6a2bc4e..ef4df09 100644 --- a/adf_core_python/core/gateway/component/module/algorithm/gateway_path_planning.py +++ b/adf_core_python/core/gateway/component/module/algorithm/gateway_path_planning.py @@ -3,7 +3,7 @@ import json from typing import TYPE_CHECKING -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import EntityID from adf_core_python.core.component.module.algorithm.path_planning import PathPlanning from adf_core_python.core.gateway.component.module.gateway_abstract_module import ( @@ -70,7 +70,7 @@ def get_path( result = self._gateway_module.execute( "getResult(EntityID, EntityID)", arguments ) - json_str = result.get_value_or_default("Result", "[]") + json_str = result.get_value("Result") or "[]" raw_entity_ids: list[int] = json.loads(json_str) entity_ids: list[EntityID] = [] for entity_id in raw_entity_ids: @@ -89,7 +89,7 @@ def get_path_to_multiple_destinations( result = self._gateway_module.execute( "getResult(EntityID, List[EntityID])", arguments ) - json_str = result.get_value_or_default("Result", "[]") + json_str = result.get_value("Result") or "[]" raw_entity_ids: list[int] = json.loads(json_str) entity_ids: list[EntityID] = [] for entity_id in raw_entity_ids: @@ -104,4 +104,4 @@ def get_distance(self, from_entity_id: EntityID, to_entity_id: EntityID) -> floa result = self._gateway_module.execute( "getDistance(EntityID, EntityID)", arguments ) - return float(result.get_value_or_default("Result", "0.0")) + return float(result.get_value("Result") or 0.0) diff --git a/adf_core_python/core/gateway/component/module/complex/gateway_human_detector.py b/adf_core_python/core/gateway/component/module/complex/gateway_human_detector.py index 7fc6fe7..7692f07 100644 --- a/adf_core_python/core/gateway/component/module/complex/gateway_human_detector.py +++ b/adf_core_python/core/gateway/component/module/complex/gateway_human_detector.py @@ -2,7 +2,7 @@ from typing import TYPE_CHECKING -from rcrs_core.entities.human import Human +from rcrscore.entities.human import Human from adf_core_python.core.component.module.complex.human_detector import ( HumanDetector, diff --git a/adf_core_python/core/gateway/component/module/complex/gateway_road_detector.py b/adf_core_python/core/gateway/component/module/complex/gateway_road_detector.py index da275b9..bfceb81 100644 --- a/adf_core_python/core/gateway/component/module/complex/gateway_road_detector.py +++ b/adf_core_python/core/gateway/component/module/complex/gateway_road_detector.py @@ -2,7 +2,7 @@ from typing import TYPE_CHECKING -from rcrs_core.entities.road import Road +from rcrscore.entities.road import Road from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.component.module.complex.road_detector import RoadDetector diff --git a/adf_core_python/core/gateway/component/module/complex/gateway_target_allocator.py b/adf_core_python/core/gateway/component/module/complex/gateway_target_allocator.py index 98649a4..1f7a57f 100644 --- a/adf_core_python/core/gateway/component/module/complex/gateway_target_allocator.py +++ b/adf_core_python/core/gateway/component/module/complex/gateway_target_allocator.py @@ -2,7 +2,7 @@ from typing import TYPE_CHECKING -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import EntityID from adf_core_python.core.component.module.complex.target_allocator import ( TargetAllocator, diff --git a/adf_core_python/core/gateway/component/module/complex/gateway_target_detector.py b/adf_core_python/core/gateway/component/module/complex/gateway_target_detector.py index a58b25f..1f50383 100644 --- a/adf_core_python/core/gateway/component/module/complex/gateway_target_detector.py +++ b/adf_core_python/core/gateway/component/module/complex/gateway_target_detector.py @@ -1,9 +1,9 @@ from __future__ import annotations -from typing import Optional, Generic, TypeVar, TYPE_CHECKING +from typing import TYPE_CHECKING, Generic, Optional, TypeVar -from rcrs_core.entities.entity import Entity -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import EntityID +from rcrscore.entities.entity import Entity from adf_core_python.core.component.module.complex.target_detector import TargetDetector from adf_core_python.core.gateway.component.module.gateway_abstract_module import ( @@ -64,7 +64,7 @@ def calculate(self) -> GatewayTargetDetector[T]: def get_target_entity_id(self) -> Optional[EntityID]: result = self._gateway_module.execute("getTarget") - entity_id_str = result.get_value_or_default("EntityID", "-1") + entity_id_str = result.get_value("EntityID") or "-1" if entity_id_str == "-1": return None return EntityID(int(entity_id_str)) diff --git a/adf_core_python/core/gateway/gateway_agent.py b/adf_core_python/core/gateway/gateway_agent.py index 31008bb..7f04e19 100644 --- a/adf_core_python/core/gateway/gateway_agent.py +++ b/adf_core_python/core/gateway/gateway_agent.py @@ -1,8 +1,9 @@ from __future__ import annotations -from typing import Optional, TYPE_CHECKING, Callable +from typing import TYPE_CHECKING, Callable, Optional -from rcrs_core.connection import RCRSProto_pb2, URN +from rcrscore.proto import RCRSProto_pb2 +from rcrscore.urn import CommandURN from adf_core_python.core.agent.info.agent_info import AgentInfo from adf_core_python.core.agent.info.scenario_info import ScenarioInfo @@ -95,7 +96,7 @@ def update(self) -> None: def set_send_msg(self, connection_send_func: Callable) -> None: self.send_msg = connection_send_func - def message_received(self, msg: RCRSProto_pb2) -> None: + def message_received(self, msg: RCRSProto_pb2.MessageProto) -> None: c_msg = ModuleMessageFactory().make_message(msg) if isinstance(c_msg, MAModuleResponse): if c_msg.module_id is None or c_msg.class_name is None: @@ -112,7 +113,7 @@ def message_received(self, msg: RCRSProto_pb2) -> None: self._gateway_modules[c_msg.module_id].set_execute_response(c_msg.result) self._gateway_modules[c_msg.module_id].set_is_executed(True) - if msg.urn == URN.Command.AK_SPEAK: + if msg.urn == CommandURN.AK_SPEAK: if self.send_msg is None: raise RuntimeError("send_msg is None") self.send_msg(msg) diff --git a/adf_core_python/core/gateway/gateway_module.py b/adf_core_python/core/gateway/gateway_module.py index e79b239..99f9115 100644 --- a/adf_core_python/core/gateway/gateway_module.py +++ b/adf_core_python/core/gateway/gateway_module.py @@ -1,7 +1,7 @@ import uuid from typing import Optional -from rcrs_core.config.config import Config +from rcrscore.config.config import Config from adf_core_python.core.gateway.gateway_agent import GatewayAgent from adf_core_python.core.gateway.message.am_exec import AMExec diff --git a/adf_core_python/core/gateway/message/am_agent.py b/adf_core_python/core/gateway/message/am_agent.py index 3d6bc8d..aac4850 100644 --- a/adf_core_python/core/gateway/message/am_agent.py +++ b/adf_core_python/core/gateway/message/am_agent.py @@ -1,35 +1,30 @@ from typing import Any -from rcrs_core.connection import RCRSProto_pb2 -from rcrs_core.entities.entity import Entity -from rcrs_core.messages.message import Message -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import EntityID +from rcrscore.entities.entity import Entity +from rcrscore.messages import AKControlMessage +from rcrscore.proto import RCRSProto_pb2 +from rcrscore.urn.control_message import ControlMessageURN from adf_core_python.core.gateway.message.urn.urn import ( - ModuleMSG, ComponentModuleMSG, + ModuleMSG, ) -class AMAgent(Message): - def __init__(self) -> None: - super().__init__(ModuleMSG.AM_AGENT) - - def read(self) -> None: - pass - +class AMAgent(AKControlMessage): + @staticmethod def write( - self, agent_id: EntityID, entities: list[Entity], config: dict[str, Any], mode: int, - ) -> Any: + ) -> RCRSProto_pb2.MessageProto: entity_proto_list = [] for entity in entities: entity_proto = RCRSProto_pb2.EntityProto() entity_proto.urn = entity.get_urn() - entity_proto.entityID = entity.get_id().get_value() + entity_proto.entityID = entity.get_entity_id().get_value() property_proto_list = [] for k, v in entity.get_properties().items(): @@ -45,7 +40,7 @@ def write( config_proto.data[str(key)] = str(value) msg = RCRSProto_pb2.MessageProto() - msg.urn = self.get_urn() + msg.urn = AMAgent.get_urn() msg.components[ComponentModuleMSG.AgentID].entityID = agent_id.get_value() msg.components[ComponentModuleMSG.Entities].entityList.CopyFrom( entity_list_proto @@ -53,3 +48,7 @@ def write( msg.components[ComponentModuleMSG.Config].config.CopyFrom(config_proto) msg.components[ComponentModuleMSG.Mode].intValue = mode return msg + + @staticmethod + def get_urn() -> ControlMessageURN: + return ModuleMSG.AM_AGENT # type: ignore diff --git a/adf_core_python/core/gateway/message/am_exec.py b/adf_core_python/core/gateway/message/am_exec.py index 9bd36be..dd8508b 100644 --- a/adf_core_python/core/gateway/message/am_exec.py +++ b/adf_core_python/core/gateway/message/am_exec.py @@ -1,25 +1,20 @@ -from abc import ABC from typing import Any -from rcrs_core.connection import RCRSProto_pb2 -from rcrs_core.messages.message import Message +from rcrscore.messages import AKControlMessage +from rcrscore.proto import RCRSProto_pb2 +from rcrscore.urn.control_message import ControlMessageURN from adf_core_python.core.gateway.message.urn.urn import ( - ModuleMSG, ComponentModuleMSG, + ModuleMSG, ) -class AMExec(Message, ABC): - def __init__(self) -> None: - super().__init__(ModuleMSG.AM_EXEC) - - def read(self) -> None: - pass - - def write(self, module_id: str, method_name: str, arguments: dict[str, str]) -> Any: +class AMExec(AKControlMessage): + @staticmethod + def write(module_id: str, method_name: str, arguments: dict[str, str]) -> Any: msg = RCRSProto_pb2.MessageProto() - msg.urn = self.get_urn() + msg.urn = AMExec.get_urn() msg.components[ComponentModuleMSG.ModuleID].stringValue = module_id msg.components[ComponentModuleMSG.MethodName].stringValue = method_name config_proto = RCRSProto_pb2.ConfigProto() @@ -28,3 +23,7 @@ def write(self, module_id: str, method_name: str, arguments: dict[str, str]) -> msg.components[ComponentModuleMSG.Arguments].config.CopyFrom(config_proto) return msg + + @staticmethod + def get_urn() -> ControlMessageURN: + return ModuleMSG.AM_EXEC # type: ignore diff --git a/adf_core_python/core/gateway/message/am_module.py b/adf_core_python/core/gateway/message/am_module.py index 0dd26bc..6b31662 100644 --- a/adf_core_python/core/gateway/message/am_module.py +++ b/adf_core_python/core/gateway/message/am_module.py @@ -1,29 +1,24 @@ from typing import Any -from rcrs_core.connection import RCRSProto_pb2 -from rcrs_core.messages.message import Message +from rcrscore.messages import AKControlMessage +from rcrscore.proto import RCRSProto_pb2 +from rcrscore.urn.control_message import ControlMessageURN from adf_core_python.core.gateway.message.urn.urn import ( - ModuleMSG, ComponentModuleMSG, + ModuleMSG, ) -class AMModule(Message): - def __init__(self) -> None: - super().__init__(ModuleMSG.AM_MODULE) - - def read(self) -> None: - pass - +class AMModule(AKControlMessage): + @staticmethod def write( - self, module_id: str, module_name: str, default_class_name: str, ) -> Any: msg = RCRSProto_pb2.MessageProto() - msg.urn = self.get_urn() + msg.urn = AMModule.get_urn() msg.components[ComponentModuleMSG.ModuleID].stringValue = module_id msg.components[ComponentModuleMSG.ModuleName].stringValue = module_name msg.components[ @@ -31,3 +26,7 @@ def write( ].stringValue = default_class_name return msg + + @staticmethod + def get_urn() -> ControlMessageURN: + return ModuleMSG.AM_MODULE # type: ignore diff --git a/adf_core_python/core/gateway/message/am_update.py b/adf_core_python/core/gateway/message/am_update.py index 0988920..e6baa79 100644 --- a/adf_core_python/core/gateway/message/am_update.py +++ b/adf_core_python/core/gateway/message/am_update.py @@ -1,27 +1,22 @@ -from abc import ABC from typing import Any -from rcrs_core.commands.Command import Command -from rcrs_core.connection import RCRSProto_pb2 -from rcrs_core.messages.message import Message -from rcrs_core.worldmodel.changeSet import ChangeSet +from rcrscore.commands import Command +from rcrscore.messages import AKControlMessage +from rcrscore.proto import RCRSProto_pb2 +from rcrscore.urn.control_message import ControlMessageURN +from rcrscore.worldmodel import ChangeSet from adf_core_python.core.gateway.message.urn.urn import ( - ModuleMSG, ComponentModuleMSG, + ModuleMSG, ) -class AMUpdate(Message, ABC): - def __init__(self) -> None: - super().__init__(ModuleMSG.AM_UPDATE) - - def read(self) -> None: - pass - - def write(self, time: int, changed: ChangeSet, heard: list[Command]) -> Any: +class AMUpdate(AKControlMessage): + @staticmethod + def write(time: int, changed: ChangeSet, heard: list[Command]) -> Any: msg = RCRSProto_pb2.MessageProto() - msg.urn = self.get_urn() + msg.urn = AMUpdate.get_urn() msg.components[ComponentModuleMSG.Time].intValue = time msg.components[ComponentModuleMSG.Changed].changeSet.CopyFrom( changed.to_change_set_proto() @@ -30,9 +25,13 @@ def write(self, time: int, changed: ChangeSet, heard: list[Command]) -> Any: message_proto_list = [] if heard is not None: for h in heard: - message_proto_list.append(h.prepare_cmd()) + message_proto_list.append(h.to_message_proto()) message_list_proto.commands.extend(message_proto_list) msg.components[ComponentModuleMSG.Heard].commandList.CopyFrom( message_list_proto ) return msg + + @staticmethod + def get_urn() -> ControlMessageURN: + return ModuleMSG.AM_UPDATE # type: ignore diff --git a/adf_core_python/core/gateway/message/ma_exec_response.py b/adf_core_python/core/gateway/message/ma_exec_response.py index 8c68fbc..1e84021 100644 --- a/adf_core_python/core/gateway/message/ma_exec_response.py +++ b/adf_core_python/core/gateway/message/ma_exec_response.py @@ -1,28 +1,27 @@ -from abc import ABC - -from rcrs_core.config.config import Config -from rcrs_core.connection import RCRSProto_pb2 -from rcrs_core.messages.message import Message +from rcrscore.config.config import Config +from rcrscore.messages import KAControlMessage +from rcrscore.proto import RCRSProto_pb2 +from rcrscore.urn.control_message import ControlMessageURN from adf_core_python.core.gateway.message.urn.urn import ( - ModuleMSG, ComponentModuleMSG, + ModuleMSG, ) -class MAExecResponse(Message, ABC): - def __init__(self, data: RCRSProto_pb2) -> None: - super().__init__(ModuleMSG.MA_EXEC_RESPONSE) - self.module_id = None +class MAExecResponse(KAControlMessage): + def __init__(self, message_proto: RCRSProto_pb2.MessageProto) -> None: self.result = Config() - self.data = data - self.read() + self.read(message_proto) - def read(self) -> None: - self.module_id = self.data.components[ComponentModuleMSG.ModuleID].stringValue - result = self.data.components[ComponentModuleMSG.Result].config + def read(self, message_proto: RCRSProto_pb2.MessageProto) -> None: + self.module_id: str = message_proto.components[ + ComponentModuleMSG.ModuleID + ].stringValue + result = message_proto.components[ComponentModuleMSG.Result].config for key, value in result.data.items(): self.result.set_value(key, value) - def write(self) -> None: - pass + @staticmethod + def get_urn() -> ControlMessageURN: + return ModuleMSG.MA_EXEC_RESPONSE # type: ignore diff --git a/adf_core_python/core/gateway/message/ma_module_response.py b/adf_core_python/core/gateway/message/ma_module_response.py index c680419..8e879f3 100644 --- a/adf_core_python/core/gateway/message/ma_module_response.py +++ b/adf_core_python/core/gateway/message/ma_module_response.py @@ -1,26 +1,30 @@ from abc import ABC from typing import Optional -from rcrs_core.connection import RCRSProto_pb2 -from rcrs_core.messages.message import Message +from rcrscore.messages import KAControlMessage +from rcrscore.proto import RCRSProto_pb2 +from rcrscore.urn.control_message import ControlMessageURN from adf_core_python.core.gateway.message.urn.urn import ( - ModuleMSG, ComponentModuleMSG, + ModuleMSG, ) -class MAModuleResponse(Message, ABC): - def __init__(self, data: RCRSProto_pb2) -> None: - super().__init__(ModuleMSG.MA_MODULE_RESPONSE) +class MAModuleResponse(KAControlMessage, ABC): + def __init__(self, message_proto: RCRSProto_pb2.MessageProto) -> None: self.module_id: Optional[str] = None self.class_name: Optional[str] = None - self.data = data - self.read() + self.read(message_proto) - def read(self) -> None: - self.module_id = self.data.components[ComponentModuleMSG.ModuleID].stringValue - self.class_name = self.data.components[ComponentModuleMSG.ClassName].stringValue + def read(self, message_proto: RCRSProto_pb2.MessageProto) -> None: + self.module_id = message_proto.components[ + ComponentModuleMSG.ModuleID + ].stringValue + self.class_name = message_proto.components[ + ComponentModuleMSG.ClassName + ].stringValue - def write(self) -> None: - pass + @staticmethod + def get_urn() -> ControlMessageURN: + return ModuleMSG.MA_MODULE_RESPONSE # type: ignore diff --git a/adf_core_python/core/gateway/message/moduleMessageFactory.py b/adf_core_python/core/gateway/message/moduleMessageFactory.py index 6fac9d8..3874b25 100644 --- a/adf_core_python/core/gateway/message/moduleMessageFactory.py +++ b/adf_core_python/core/gateway/message/moduleMessageFactory.py @@ -1,6 +1,6 @@ from typing import Optional -from rcrs_core.connection import RCRSProto_pb2 +from rcrscore.proto import RCRSProto_pb2 from adf_core_python.core.gateway.message.ma_exec_response import MAExecResponse from adf_core_python.core.gateway.message.ma_module_response import ( @@ -14,7 +14,7 @@ def __init__(self) -> None: pass def make_message( - self, msg: RCRSProto_pb2 + self, msg: RCRSProto_pb2.MessageProto ) -> Optional[MAModuleResponse | MAExecResponse]: if msg.urn == ModuleMSG.MA_MODULE_RESPONSE: return MAModuleResponse(msg) diff --git a/adf_core_python/core/logger/logger.py b/adf_core_python/core/logger/logger.py index 16797e8..8b8f2f6 100644 --- a/adf_core_python/core/logger/logger.py +++ b/adf_core_python/core/logger/logger.py @@ -45,9 +45,13 @@ def get_agent_logger(name: str, agent_info: AgentInfo) -> structlog.BoundLogger: structlog.BoundLogger The logger with the given name and agent information. """ + agent = agent_info.get_myself() + if agent is None: + raise ValueError("Agent information is not available") + return structlog.get_logger(name).bind( agent_id=str(agent_info.get_entity_id()), - agent_type=str(agent_info.get_myself().get_urn().name), + agent_type=str(agent.get_urn().name), ) 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 d0a1912..879cbdf 100644 --- a/adf_core_python/implement/action/default_extend_action_clear.py +++ b/adf_core_python/implement/action/default_extend_action_clear.py @@ -2,16 +2,18 @@ import sys from typing import Optional, cast -from rcrs_core.entities.ambulanceTeam import AmbulanceTeam -from rcrs_core.entities.area import Area -from rcrs_core.entities.blockade import Blockade -from rcrs_core.entities.building import Building -from rcrs_core.entities.fireBrigade import FireBrigade -from rcrs_core.entities.human import Human -from rcrs_core.entities.policeForce import PoliceForce -from rcrs_core.entities.refuge import Refuge -from rcrs_core.entities.road import Road -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import ( + AmbulanceTeam, + Area, + Blockade, + Building, + EntityID, + FireBrigade, + Human, + PoliceForce, + Refuge, + Road, +) from shapely import LineString, Point, Polygon from adf_core_python.core.agent.action.action import Action @@ -261,7 +263,7 @@ def _get_rescue_action( for agent_entity in agent_entities: human = cast(Human, agent_entity) - if human.get_position().get_value() != road.get_id().get_value(): + if human.get_position().get_value() != road.get_entity_id().get_value(): continue human_x = human.get_x() @@ -294,10 +296,11 @@ def _get_rescue_action( return ActionClear(clear_blockade) another_distance = self.world_info.get_distance( - police_entity.get_id(), clear_blockade.get_id() + police_entity.get_entity_id(), + clear_blockade.get_entity_id(), ) blockade_distance = self.world_info.get_distance( - police_entity.get_id(), blockade.get_id() + police_entity.get_entity_id(), blockade.get_entity_id() ) if blockade_distance < another_distance: return action @@ -334,10 +337,12 @@ def _get_rescue_action( return ActionClear(clear_blockade) distance1 = self.world_info.get_distance( - police_entity.get_id(), clear_blockade.get_id() + police_entity.get_entity_id(), + clear_blockade.get_entity_id(), ) distance2 = self.world_info.get_distance( - police_entity.get_id(), blockade.get_id() + police_entity.get_entity_id(), + blockade.get_entity_id(), ) if distance1 > distance2: return ActionClearArea(clear_x, clear_y) @@ -346,7 +351,9 @@ def _get_rescue_action( elif distance < min_distance: min_distance = distance - move_action = ActionMove([road.get_id()], human_x, human_y) + move_action = ActionMove( + [road.get_entity_id()], human_x, human_y + ) if action_clear is not None: return action_clear @@ -412,7 +419,7 @@ def _get_intersect_edge_action( if best_point is not None: bp_x, bp_y = best_point if road.get_blockades() is None: - return ActionMove([road.get_id()], int(bp_x), int(bp_y)) + return ActionMove([road.get_entity_id()], int(bp_x), int(bp_y)) action_clear: Optional[ActionClearArea] = None clear_blockade: Optional[Blockade] = None @@ -446,7 +453,9 @@ def _get_intersect_edge_action( return ActionClear(clear_blockade) return action_clear elif action_move is None: - action_move = ActionMove([road.get_id()], int(bp_x), int(bp_y)) + action_move = ActionMove( + [road.get_entity_id()], int(bp_x), int(bp_y) + ) if action_clear is not None: return action_clear @@ -457,12 +466,12 @@ def _get_intersect_edge_action( cast(PoliceForce, self.agent_info.get_myself()), road ) if action is None: - action = ActionMove([road.get_id()], int(point_x), int(point_y)) + action = ActionMove([road.get_entity_id()], int(point_x), int(point_y)) return action def _get_move_points(self, road: Road) -> set[tuple[float, float]]: points: Optional[set[tuple[float, float]]] = self._move_point_cache.get( - road.get_id() + road.get_entity_id() ) if points is None: points = set() @@ -480,7 +489,7 @@ def _get_move_points(self, road: Road) -> set[tuple[float, float]]: if (mid_x, mid_y) in points: points.remove((mid_x, mid_y)) - self._move_point_cache[road.get_id()] = points + self._move_point_cache[road.get_entity_id()] = points return points @@ -568,10 +577,10 @@ def _get_area_clear_action( if self._is_intersecting_blockades(blockade, another): distance1 = self.world_info.get_distance( - police_entity.get_id(), blockade.get_id() + police_entity.get_entity_id(), blockade.get_entity_id() ) distance2 = self.world_info.get_distance( - police_entity.get_id(), another.get_id() + police_entity.get_entity_id(), another.get_entity_id() ) if distance1 <= distance2 and distance1 < min_distance: min_distance = distance1 @@ -632,7 +641,7 @@ def _get_neighbour_position_action( if position is None: return None - edge = target.get_edge_to(position.get_id()) + edge = target.get_edge_to(position.get_entity_id()) if edge is None: return None @@ -680,7 +689,9 @@ def _get_neighbour_position_action( if self.count >= self._forced_move: self.count = 0 return ActionMove( - [road.get_id()], int(clear_x), int(clear_y) + [road.get_entity_id()], + int(clear_x), + int(clear_y), ) self.count += 1 @@ -696,7 +707,7 @@ def _get_neighbour_position_action( return action_clear elif action_move is None: action_move = ActionMove( - [road.get_id()], int(mid_x), int(mid_y) + [road.get_entity_id()], int(mid_x), int(mid_y) ) if action_clear is not None: @@ -707,7 +718,7 @@ def _get_neighbour_position_action( if isinstance(target, Road): road = cast(Road, target) if road.get_blockades() == []: - return ActionMove([position.get_id(), target.get_id()]) + return ActionMove([position.get_entity_id(), target.get_entity_id()]) target_blockade: Optional[Blockade] = None min_point_distance = sys.float_info.max @@ -739,11 +750,11 @@ def _get_neighbour_position_action( ): if self.count >= self._forced_move: self.count = 0 - return ActionMove([road.get_id()], clear_x, clear_y) + return ActionMove([road.get_entity_id()], clear_x, clear_y) self.count += 1 self._old_clear_x = clear_x self._old_clear_y = clear_y return ActionClearArea(clear_x, clear_y) - return ActionMove([position.get_id(), target.get_id()]) + return ActionMove([position.get_entity_id(), target.get_entity_id()]) 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 e4936a4..b14baf3 100644 --- a/adf_core_python/implement/action/default_extend_action_move.py +++ b/adf_core_python/implement/action/default_extend_action_move.py @@ -1,10 +1,6 @@ from typing import Optional, cast -from rcrs_core.entities.area import Area -from rcrs_core.entities.blockade import Blockade -from rcrs_core.entities.entity import Entity -from rcrs_core.entities.human import Human -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import Area, Blockade, Entity, EntityID, Human from adf_core_python.core.agent.action.common.action_move import ActionMove from adf_core_python.core.agent.communication.message_manager import MessageManager @@ -83,7 +79,7 @@ def set_target_entity_id(self, target_entity_id: EntityID) -> ExtendAction: entity = self.world_info.get_entity(position) if entity is not None and isinstance(entity, Area): - self._target_entity_id = entity.get_id() + self._target_entity_id = entity.get_entity_id() return self @@ -94,8 +90,12 @@ def calculate(self) -> ExtendAction: if self._target_entity_id is None: return self + agent_position = agent.get_position() + if agent_position is None: + return self + path: list[EntityID] = self._path_planning.get_path( - agent.get_position(), self._target_entity_id + agent_position, self._target_entity_id ) if path is not None and len(path) != 0: 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 e76e96a..df1e067 100644 --- a/adf_core_python/implement/action/default_extend_action_rescue.py +++ b/adf_core_python/implement/action/default_extend_action_rescue.py @@ -1,10 +1,6 @@ from typing import Optional, cast -from rcrs_core.entities.area import Area -from rcrs_core.entities.blockade import Blockade -from rcrs_core.entities.fireBrigade import FireBrigade -from rcrs_core.entities.human import Human -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import Area, Blockade, EntityID, FireBrigade, Human from adf_core_python.core.agent.action.action import Action from adf_core_python.core.agent.action.ambulance.action_rescue import ActionRescue @@ -117,16 +113,19 @@ def _calc_rescue( return None agent_position_entity_id = agent.get_position() + if agent_position_entity_id is None: + return None + if isinstance(target_entity, Human): human = cast(Human, target_entity) if human.get_hp() == 0: return None target_position_entity_id = human.get_position() - if ( - agent_position_entity_id.get_value() - == target_position_entity_id.get_value() - ): + if target_position_entity_id is None: + return None + + if agent_position_entity_id == target_position_entity_id: buriedness = human.get_buriedness() if buriedness is not None and buriedness > 0: return ActionRescue(target_entity_id) @@ -141,10 +140,14 @@ def _calc_rescue( if isinstance(target_entity, Blockade): blockade = cast(Blockade, target_entity) - target_entity = self.world_info.get_entity(blockade.get_position()) + blockade_position = blockade.get_position() + if blockade_position is None: + return None + + target_entity = self.world_info.get_entity(blockade_position) if isinstance(target_entity, Area): path = self._path_planning.get_path( - agent_position_entity_id, target_entity.get_id() + agent_position_entity_id, target_entity.get_entity_id() ) if path != []: return ActionMove(path) 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 b1c9629..a64b23c 100644 --- a/adf_core_python/implement/action/default_extend_action_transport.py +++ b/adf_core_python/implement/action/default_extend_action_transport.py @@ -1,12 +1,14 @@ from typing import Optional, Union, cast -from rcrs_core.entities.ambulanceTeam import AmbulanceTeam -from rcrs_core.entities.area import Area -from rcrs_core.entities.civilian import Civilian -from rcrs_core.entities.entity import Entity -from rcrs_core.entities.human import Human -from rcrs_core.entities.refuge import Refuge -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import ( + AmbulanceTeam, + Area, + Civilian, + Entity, + EntityID, + Human, + Refuge, +) from adf_core_python.core.agent.action.ambulance.action_load import ActionLoad from adf_core_python.core.agent.action.ambulance.action_unload import ActionUnload @@ -98,7 +100,7 @@ def calculate(self) -> ExtendAction: agent: AmbulanceTeam = cast(AmbulanceTeam, self.agent_info.get_myself()) transport_human: Optional[Human] = self.agent_info.some_one_on_board() if transport_human is not None: - self._logger.debug(f"transport_human: {transport_human.get_id()}") + self._logger.debug(f"transport_human: {transport_human.get_entity_id()}") self.result = self.calc_unload( agent, self._path_planning, transport_human, self._target_entity_id ) @@ -133,7 +135,7 @@ def calc_rescue( target_position = human.get_position() if agent_position == target_position: if isinstance(human, Civilian) and ((human.get_buriedness() or 0) == 0): - return ActionLoad(human.get_id()) + return ActionLoad(human.get_entity_id()) else: path = path_planning.get_path(agent_position, target_position) if path is not None and len(path) > 0: @@ -141,7 +143,7 @@ def calc_rescue( return None if isinstance(target_entity, Area): - path = path_planning.get_path(agent_position, target_entity.get_id()) + path = path_planning.get_path(agent_position, target_entity.get_entity_id()) if path is not None and len(path) > 0: return ActionMove(path) @@ -161,10 +163,7 @@ def calc_unload( return ActionUnload() agent_position = agent.get_position() - if ( - target_id is None - or transport_human.get_id().get_value() == target_id.get_value() - ): + if target_id is None or transport_human.get_entity_id() == target_id: position = self.world_info.get_entity(agent_position) if position is None: return None diff --git a/adf_core_python/implement/centralized/default_command_executor_ambulance.py b/adf_core_python/implement/centralized/default_command_executor_ambulance.py index adfb80b..aa6bf81 100644 --- a/adf_core_python/implement/centralized/default_command_executor_ambulance.py +++ b/adf_core_python/implement/centralized/default_command_executor_ambulance.py @@ -1,11 +1,6 @@ from typing import Optional, cast -from rcrs_core.entities.ambulanceTeam import AmbulanceTeam -from rcrs_core.entities.area import Area -from rcrs_core.entities.civilian import Civilian -from rcrs_core.entities.human import Human -from rcrs_core.entities.refuge import Refuge -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import AmbulanceTeam, Area, Civilian, EntityID, Human, Refuge from adf_core_python.core.agent.action.common.action_move import ActionMove from adf_core_python.core.agent.action.common.action_rest import ActionRest diff --git a/adf_core_python/implement/centralized/default_command_executor_fire.py b/adf_core_python/implement/centralized/default_command_executor_fire.py index c4fdf64..7def460 100644 --- a/adf_core_python/implement/centralized/default_command_executor_fire.py +++ b/adf_core_python/implement/centralized/default_command_executor_fire.py @@ -1,10 +1,6 @@ from typing import Optional, cast -from rcrs_core.entities.area import Area -from rcrs_core.entities.civilian import Civilian -from rcrs_core.entities.human import Human -from rcrs_core.entities.refuge import Refuge -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import Area, Civilian, EntityID, Human, Refuge from adf_core_python.core.agent.action.common.action_move import ActionMove from adf_core_python.core.agent.action.common.action_rest import ActionRest diff --git a/adf_core_python/implement/centralized/default_command_executor_police.py b/adf_core_python/implement/centralized/default_command_executor_police.py index b137337..c5d756b 100644 --- a/adf_core_python/implement/centralized/default_command_executor_police.py +++ b/adf_core_python/implement/centralized/default_command_executor_police.py @@ -1,11 +1,6 @@ from typing import Optional, cast -from rcrs_core.entities.area import Area -from rcrs_core.entities.blockade import Blockade -from rcrs_core.entities.human import Human -from rcrs_core.entities.refuge import Refuge -from rcrs_core.entities.road import Road -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import Area, Blockade, EntityID, Human, Refuge, Road from adf_core_python.core.agent.action.common.action_move import ActionMove from adf_core_python.core.agent.action.common.action_rest import ActionRest diff --git a/adf_core_python/implement/centralized/default_command_executor_scout.py b/adf_core_python/implement/centralized/default_command_executor_scout.py index 28fdd78..0ff628b 100644 --- a/adf_core_python/implement/centralized/default_command_executor_scout.py +++ b/adf_core_python/implement/centralized/default_command_executor_scout.py @@ -1,9 +1,6 @@ from typing import Optional, cast -from rcrs_core.entities.area import Area -from rcrs_core.entities.human import Human -from rcrs_core.entities.refuge import Refuge -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import Area, EntityID, Human, Refuge from adf_core_python.core.agent.action.common.action_move import ActionMove from adf_core_python.core.agent.communication.message_manager import MessageManager @@ -72,8 +69,11 @@ def set_command(self, command: CommandScout) -> CommandExecutor: for entity in self._world_info.get_entities_of_types([Area]): if isinstance(entity, Refuge): continue - if self._world_info.get_distance(target, entity.get_id()) <= scout_distance: - self._targets.append(entity.get_id()) + if ( + self._world_info.get_distance(target, entity.get_entity_id()) + <= scout_distance + ): + self._targets.append(entity.get_entity_id()) return self @@ -151,7 +151,7 @@ def _is_command_completed(self) -> bool: case self.ACTION_SCOUT: if len(self._targets) != 0: for entity in self._world_info.get_entities_of_types([Area]): - self._targets.remove(entity.get_id()) + self._targets.remove(entity.get_entity_id()) return len(self._targets) == 0 case _: return True diff --git a/adf_core_python/implement/centralized/default_command_executor_scout_police.py b/adf_core_python/implement/centralized/default_command_executor_scout_police.py index e0345a5..c80d68a 100644 --- a/adf_core_python/implement/centralized/default_command_executor_scout_police.py +++ b/adf_core_python/implement/centralized/default_command_executor_scout_police.py @@ -1,9 +1,6 @@ from typing import Optional, cast -from rcrs_core.entities.area import Area -from rcrs_core.entities.human import Human -from rcrs_core.entities.refuge import Refuge -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import Area, EntityID, Human, Refuge from adf_core_python.core.agent.action.common.action_move import ActionMove from adf_core_python.core.agent.communication.message_manager import MessageManager @@ -77,8 +74,11 @@ def set_command(self, command: CommandScout) -> CommandExecutor: for entity in self._world_info.get_entities_of_types([Area]): if isinstance(entity, Refuge): continue - if self._world_info.get_distance(target, entity.get_id()) <= scout_distance: - self._targets.append(entity.get_id()) + if ( + self._world_info.get_distance(target, entity.get_entity_id()) + <= scout_distance + ): + self._targets.append(entity.get_entity_id()) return self @@ -163,7 +163,7 @@ def _is_command_completed(self) -> bool: case self.ACTION_SCOUT: if len(self._targets) != 0: for entity in self._world_info.get_entities_of_types([Area]): - self._targets.remove(entity.get_id()) + self._targets.remove(entity.get_entity_id()) return len(self._targets) == 0 case _: return True diff --git a/adf_core_python/implement/centralized/default_command_picker_ambulance.py b/adf_core_python/implement/centralized/default_command_picker_ambulance.py index b2a507d..edddf4e 100644 --- a/adf_core_python/implement/centralized/default_command_picker_ambulance.py +++ b/adf_core_python/implement/centralized/default_command_picker_ambulance.py @@ -1,9 +1,6 @@ from __future__ import annotations -from rcrs_core.entities.ambulanceTeam import AmbulanceTeam -from rcrs_core.entities.area import Area -from rcrs_core.entities.human import Human -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import AmbulanceTeam, Area, EntityID, Human from adf_core_python.core.agent.communication.standard.bundle.centralized.command_ambulance import ( CommandAmbulance, @@ -69,7 +66,7 @@ def calculate(self) -> CommandPicker: self._agent_info.get_entity_id(), CommandAmbulance.ACTION_RESCUE, StandardMessagePriority.NORMAL, - target.get_id(), + target.get_entity_id(), ) self.messages.append(command) @@ -80,7 +77,7 @@ def calculate(self) -> CommandPicker: self._agent_info.get_entity_id(), self.scout_distance, StandardMessagePriority.NORMAL, - target.get_id(), + target.get_entity_id(), ) self.messages.append(command) return self diff --git a/adf_core_python/implement/centralized/default_command_picker_fire.py b/adf_core_python/implement/centralized/default_command_picker_fire.py index bacb996..a5c8017 100644 --- a/adf_core_python/implement/centralized/default_command_picker_fire.py +++ b/adf_core_python/implement/centralized/default_command_picker_fire.py @@ -1,9 +1,6 @@ from __future__ import annotations -from rcrs_core.entities.area import Area -from rcrs_core.entities.fireBrigade import FireBrigade -from rcrs_core.entities.human import Human -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import Area, EntityID, FireBrigade, Human from adf_core_python.core.agent.communication.standard.bundle.centralized.command_ambulance import ( CommandAmbulance, @@ -69,7 +66,7 @@ def calculate(self) -> CommandPicker: self._agent_info.get_entity_id(), CommandAmbulance.ACTION_RESCUE, StandardMessagePriority.NORMAL, - target.get_id(), + target.get_entity_id(), ) self.messages.append(command) @@ -80,7 +77,7 @@ def calculate(self) -> CommandPicker: self._agent_info.get_entity_id(), self.scout_distance, StandardMessagePriority.NORMAL, - target.get_id(), + target.get_entity_id(), ) self.messages.append(command) return self diff --git a/adf_core_python/implement/centralized/default_command_picker_police.py b/adf_core_python/implement/centralized/default_command_picker_police.py index bbda78e..0dbde23 100644 --- a/adf_core_python/implement/centralized/default_command_picker_police.py +++ b/adf_core_python/implement/centralized/default_command_picker_police.py @@ -1,8 +1,6 @@ from __future__ import annotations -from rcrs_core.entities.area import Area -from rcrs_core.entities.policeForce import PoliceForce -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import Area, EntityID, PoliceForce from adf_core_python.core.agent.communication.standard.bundle.centralized.command_police import ( CommandPolice, @@ -59,11 +57,11 @@ def calculate(self) -> CommandPicker: if isinstance(target, Area): command = CommandPolice( True, - agent.get_id(), + agent.get_entity_id(), self._agent_info.get_entity_id(), CommandPolice.ACTION_AUTONOMY, StandardMessagePriority.NORMAL, - target.get_id(), + target.get_entity_id(), ) self.messages.append(command) return self diff --git a/adf_core_python/implement/module/algorithm/a_star_path_planning.py b/adf_core_python/implement/module/algorithm/a_star_path_planning.py index 6f2fce5..5a80339 100644 --- a/adf_core_python/implement/module/algorithm/a_star_path_planning.py +++ b/adf_core_python/implement/module/algorithm/a_star_path_planning.py @@ -1,8 +1,6 @@ from __future__ import annotations -from rcrs_core.entities.area import Area -from rcrs_core.entities.entity import Entity -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import Area, Entity, EntityID from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo @@ -30,9 +28,9 @@ def __init__( self._graph: dict[EntityID, set[EntityID]] = {} for entity in entities: if isinstance(entity, Area): - self._graph[entity.get_id()] = set( + self._graph[entity.get_entity_id()] = set( neighbor - for neighbor in entity.get_neighbours() # TODO: Fix rcrs_core typo + for neighbor in entity.get_neighbors() if neighbor != EntityID(0) ) diff --git a/adf_core_python/implement/module/algorithm/dijkstra_path_planning.py b/adf_core_python/implement/module/algorithm/dijkstra_path_planning.py index e8697d6..1a592a8 100644 --- a/adf_core_python/implement/module/algorithm/dijkstra_path_planning.py +++ b/adf_core_python/implement/module/algorithm/dijkstra_path_planning.py @@ -3,8 +3,7 @@ import heapq from typing import Optional -from rcrs_core.entities.area import Area -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import Area, EntityID from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo @@ -31,9 +30,9 @@ def __init__( for area in self._world_info.get_entities_of_types([Area]): if not isinstance(area, Area): continue - if (neighbors := area.get_neighbours()) is None: + if (neighbors := area.get_neighbors()) is None: continue - area_id = area.get_id() + area_id = area.get_entity_id() self.graph[area_id] = [ ( neighbor, 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 57228b7..9fe0517 100644 --- a/adf_core_python/implement/module/algorithm/k_means_clustering.py +++ b/adf_core_python/implement/module/algorithm/k_means_clustering.py @@ -1,15 +1,17 @@ import numpy as np -from rcrs_core.connection.URN import Entity as EntityURN -from rcrs_core.entities.ambulanceCenter import AmbulanceCentre -from rcrs_core.entities.building import Building -from rcrs_core.entities.entity import Entity -from rcrs_core.entities.fireStation import FireStation -from rcrs_core.entities.gasStation import GasStation -from rcrs_core.entities.hydrant import Hydrant -from rcrs_core.entities.policeOffice import PoliceOffice -from rcrs_core.entities.refuge import Refuge -from rcrs_core.entities.road import Road -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import ( + AmbulanceCenter, + Building, + Entity, + EntityID, + FireStation, + GasStation, + Hydrant, + PoliceOffice, + Refuge, + Road, +) +from rcrscore.urn import EntityURN from sklearn.cluster import KMeans from adf_core_python.core.agent.develop.develop_data import DevelopData @@ -64,16 +66,16 @@ def __init__( agent_info.get_myself().__class__, ] ), - key=lambda entity: entity.get_id().get_value(), + key=lambda entity: entity.get_entity_id().get_value(), ) self.entity_cluster_indices = { - entity.get_id(): idx for idx, entity in enumerate(sorted_entities) + entity.get_entity_id(): idx for idx, entity in enumerate(sorted_entities) } self.cluster_entities: list[list[Entity]] = [] self.entities: list[Entity] = world_info.get_entities_of_types( [ - AmbulanceCentre, + AmbulanceCenter, FireStation, GasStation, Hydrant, @@ -92,7 +94,7 @@ def precompute(self, precompute_data: PrecomputeData) -> Clustering: precompute_data.write_json_data( { "cluster_entities": [ - [entity.get_id().get_value() for entity in cluster] + [entity.get_entity_id().get_value() for entity in cluster] for cluster in cluster_entities ] }, @@ -127,7 +129,9 @@ def get_cluster_entities(self, cluster_index: int) -> list[Entity]: def get_cluster_entity_ids(self, cluster_index: int) -> list[EntityID]: if cluster_index >= len(self.cluster_entities): return [] - return [entity.get_id() for entity in self.cluster_entities[cluster_index]] + return [ + entity.get_entity_id() for entity in self.cluster_entities[cluster_index] + ] def prepare(self) -> Clustering: super().prepare() diff --git a/adf_core_python/implement/module/communication/default_channel_subscriber.py b/adf_core_python/implement/module/communication/default_channel_subscriber.py index d195c9a..398b720 100644 --- a/adf_core_python/implement/module/communication/default_channel_subscriber.py +++ b/adf_core_python/implement/module/communication/default_channel_subscriber.py @@ -2,7 +2,7 @@ from typing import TYPE_CHECKING -from rcrs_core.connection.URN import Entity as EntityURN +from rcrscore.urn import EntityURN from adf_core_python.core.agent.info.scenario_info import ScenarioInfoKeys from adf_core_python.core.component.communication.channel_subscriber import ( @@ -69,7 +69,7 @@ def get_channel_number( agent_index = 2 elif ( agent_type == EntityURN.AMBULANCE_TEAM - or agent_type == EntityURN.AMBULANCE_CENTRE + or agent_type == EntityURN.AMBULANCE_CENTER ): agent_index = 3 @@ -97,5 +97,5 @@ def get_channel_number( for i in range(max_channels): print( - f"AMB-{i}: {DefaultChannelSubscriber.get_channel_number(EntityURN.AMBULANCE_CENTRE, i, num_channels)}" + f"AMB-{i}: {DefaultChannelSubscriber.get_channel_number(EntityURN.AMBULANCE_CENTER, i, num_channels)}" ) diff --git a/adf_core_python/implement/module/communication/default_message_coordinator.py b/adf_core_python/implement/module/communication/default_message_coordinator.py index 92e1555..28c8490 100644 --- a/adf_core_python/implement/module/communication/default_message_coordinator.py +++ b/adf_core_python/implement/module/communication/default_message_coordinator.py @@ -1,6 +1,6 @@ from typing import Optional -from rcrs_core.connection.URN import Entity as EntityURN +from rcrscore.urn import EntityURN from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.communication.standard.bundle.centralized.command_ambulance import ( @@ -96,7 +96,7 @@ def coordinate( fire_brigade_messages.append(msg) elif agent_type == EntityURN.POLICE_OFFICE: police_messages.append(msg) - elif agent_type == EntityURN.AMBULANCE_CENTRE: + elif agent_type == EntityURN.AMBULANCE_CENTER: ambulance_messages.append(msg) elif isinstance(msg, MessageReport): if agent_type == EntityURN.FIRE_BRIGADE: diff --git a/adf_core_python/implement/module/complex/default_ambulance_target_allocator.py b/adf_core_python/implement/module/complex/default_ambulance_target_allocator.py index 912638b..50f0f35 100644 --- a/adf_core_python/implement/module/complex/default_ambulance_target_allocator.py +++ b/adf_core_python/implement/module/complex/default_ambulance_target_allocator.py @@ -1,10 +1,7 @@ from functools import cmp_to_key from typing import Callable, Optional -from rcrs_core.entities.ambulanceTeam import AmbulanceTeam -from rcrs_core.entities.entity import Entity -from rcrs_core.entities.human import Human -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import AmbulanceTeam, Entity, EntityID, Human from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData @@ -70,12 +67,12 @@ def calculate(self) -> AmbulanceTargetAllocator: agents, key=cmp_to_key(self._compare_by_distance(target_entity)) ) result = agents.pop(0) - info = self._ambulance_team_info_map[result.get_id()] + info = self._ambulance_team_info_map[result.get_entity_id()] if info is not None: info._can_new_action = False info._target = target info.command_time = current_time - self._ambulance_team_info_map[result.get_id()] = info + self._ambulance_team_info_map[result.get_entity_id()] = info removes.append(target) for r in removes: @@ -90,12 +87,12 @@ def calculate(self) -> AmbulanceTargetAllocator: agents, key=cmp_to_key(self._compare_by_distance(target_entity)) ) result = agents.pop(0) - info = self._ambulance_team_info_map[result.get_id()] + info = self._ambulance_team_info_map[result.get_entity_id()] if info is not None: info._can_new_action = False info._target = target info.command_time = current_time - self._ambulance_team_info_map[result.get_id()] = info + self._ambulance_team_info_map[result.get_entity_id()] = info removes.append(target) for r in removes: @@ -112,7 +109,7 @@ def _get_action_agents( ) -> list[AmbulanceTeam]: result = [] for entity in self._world_info.get_entities_of_types([AmbulanceTeam]): - info = info_map[entity.get_id()] + info = info_map[entity.get_entity_id()] if info is not None and info._can_new_action: result.append(entity) return result @@ -122,10 +119,10 @@ def _compare_by_distance( ) -> Callable[[Entity, Entity], int]: def _cmp_func(entity_a: Entity, entity_b: Entity) -> int: distance_a = self._world_info.get_distance( - target_entity.get_id(), entity_a.get_id() + target_entity.get_entity_id(), entity_a.get_entity_id() ) distance_b = self._world_info.get_distance( - target_entity.get_id(), entity_b.get_id() + target_entity.get_entity_id(), entity_b.get_entity_id() ) if distance_a < distance_b: return -1 diff --git a/adf_core_python/implement/module/complex/default_fire_target_allocator.py b/adf_core_python/implement/module/complex/default_fire_target_allocator.py index 56711c1..c32e716 100644 --- a/adf_core_python/implement/module/complex/default_fire_target_allocator.py +++ b/adf_core_python/implement/module/complex/default_fire_target_allocator.py @@ -1,10 +1,7 @@ from functools import cmp_to_key from typing import Callable, Optional -from rcrs_core.entities.entity import Entity -from rcrs_core.entities.fireBrigade import FireBrigade -from rcrs_core.entities.human import Human -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import Entity, EntityID, FireBrigade, Human from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData @@ -70,12 +67,12 @@ def calculate(self) -> FireTargetAllocator: agents, key=cmp_to_key(self._compare_by_distance(target_entity)) ) result = agents.pop(0) - info = self._fire_brigade_info_map[result.get_id()] + info = self._fire_brigade_info_map[result.get_entity_id()] if info is not None: info._can_new_action = False info._target = target info.command_time = current_time - self._fire_brigade_info_map[result.get_id()] = info + self._fire_brigade_info_map[result.get_entity_id()] = info removes.append(target) for r in removes: @@ -90,12 +87,12 @@ def calculate(self) -> FireTargetAllocator: agents, key=cmp_to_key(self._compare_by_distance(target_entity)) ) result = agents.pop(0) - info = self._fire_brigade_info_map[result.get_id()] + info = self._fire_brigade_info_map[result.get_entity_id()] if info is not None: info._can_new_action = False info._target = target info.command_time = current_time - self._fire_brigade_info_map[result.get_id()] = info + self._fire_brigade_info_map[result.get_entity_id()] = info removes.append(target) for r in removes: @@ -111,7 +108,7 @@ def _get_action_agents( ) -> list[FireBrigade]: result = [] for entity in self._world_info.get_entities_of_types([FireBrigade]): - info = info_map[entity.get_id()] + info = info_map[entity.get_entity_id()] if info is not None and info._can_new_action: result.append(entity) return result @@ -121,10 +118,10 @@ def _compare_by_distance( ) -> Callable[[Entity, Entity], int]: def _cmp_func(entity_a: Entity, entity_b: Entity) -> int: distance_a = self._world_info.get_distance( - target_entity.get_id(), entity_a.get_id() + target_entity.get_entity_id(), entity_a.get_entity_id() ) distance_b = self._world_info.get_distance( - target_entity.get_id(), entity_b.get_id() + target_entity.get_entity_id(), entity_b.get_entity_id() ) if distance_a < distance_b: return -1 diff --git a/adf_core_python/implement/module/complex/default_human_detector.py b/adf_core_python/implement/module/complex/default_human_detector.py index 4720226..a667524 100644 --- a/adf_core_python/implement/module/complex/default_human_detector.py +++ b/adf_core_python/implement/module/complex/default_human_detector.py @@ -1,10 +1,7 @@ from typing import Optional, cast -from rcrs_core.connection.URN import Entity as EntityURN -from rcrs_core.entities.civilian import Civilian -from rcrs_core.entities.entity import Entity -from rcrs_core.entities.human import Human -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import Civilian, Entity, EntityID, Human +from rcrscore.urn import EntityURN from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo @@ -46,7 +43,7 @@ def __init__( def calculate(self) -> HumanDetector: transport_human: Optional[Human] = self._agent_info.some_one_on_board() if transport_human is not None: - self._result = transport_human.get_id() + self._result = transport_human.get_entity_id() return self if self._result is not None: @@ -72,44 +69,45 @@ def _select_target(self) -> Optional[EntityID]: cluster_valid_human_entities: list[Entity] = [ entity for entity in cluster_entities - if self._is_valid_human(entity.get_id()) and isinstance(entity, Civilian) + if self._is_valid_human(entity.get_entity_id()) + and isinstance(entity, Civilian) ] if len(cluster_valid_human_entities) != 0: nearest_human_entity = cluster_valid_human_entities[0] nearest_distance = self._world_info.get_distance( self._agent_info.get_entity_id(), - nearest_human_entity.get_id(), + nearest_human_entity.get_entity_id(), ) for entity in cluster_valid_human_entities: distance = self._world_info.get_distance( self._agent_info.get_entity_id(), - entity.get_id(), + entity.get_entity_id(), ) if distance < nearest_distance: nearest_distance = distance nearest_human_entity = entity - return nearest_human_entity.get_id() + return nearest_human_entity.get_entity_id() world_valid_human_entities: list[Entity] = [ entity for entity in self._world_info.get_entities_of_types([Civilian]) - if self._is_valid_human(entity.get_id()) + if self._is_valid_human(entity.get_entity_id()) ] if len(world_valid_human_entities) != 0: nearest_human_entity = world_valid_human_entities[0] nearest_distance = self._world_info.get_distance( self._agent_info.get_entity_id(), - nearest_human_entity.get_id(), + nearest_human_entity.get_entity_id(), ) for entity in world_valid_human_entities: distance = self._world_info.get_distance( self._agent_info.get_entity_id(), - entity.get_id(), + entity.get_entity_id(), ) if distance < nearest_distance: nearest_distance = distance nearest_human_entity = entity - return nearest_human_entity.get_id() + return nearest_human_entity.get_entity_id() return None diff --git a/adf_core_python/implement/module/complex/default_police_target_allocator.py b/adf_core_python/implement/module/complex/default_police_target_allocator.py index 00d6702..0de8b3f 100644 --- a/adf_core_python/implement/module/complex/default_police_target_allocator.py +++ b/adf_core_python/implement/module/complex/default_police_target_allocator.py @@ -1,13 +1,15 @@ from functools import cmp_to_key from typing import Callable, Optional, cast -from rcrs_core.entities.building import Building -from rcrs_core.entities.entity import Entity -from rcrs_core.entities.gasStation import GasStation -from rcrs_core.entities.policeForce import PoliceForce -from rcrs_core.entities.refuge import Refuge -from rcrs_core.entities.road import Road -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import ( + Building, + Entity, + EntityID, + GasStation, + PoliceForce, + Refuge, + Road, +) from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData @@ -50,14 +52,14 @@ def resume(self, precompute_data: PrecomputeData) -> PoliceTargetAllocator: [Refuge, Building, GasStation] ): building: Building = cast(Building, entity) - for entity_id in building.get_neighbours(): + for entity_id in building.get_neighbors(): neighbor = self._world_info.get_entity(entity_id) if isinstance(neighbor, Road): self._target_areas.add(entity_id) for entity in self._world_info.get_entities_of_types([Refuge]): refuge: Refuge = cast(Refuge, entity) - for entity_id in refuge.get_neighbours(): + for entity_id in refuge.get_neighbors(): neighbor = self._world_info.get_entity(entity_id) if isinstance(neighbor, Road): self._priority_areas.add(entity_id) @@ -75,14 +77,14 @@ def prepare(self) -> PoliceTargetAllocator: [Refuge, Building, GasStation] ): building: Building = cast(Building, entity) - for entity_id in building.get_neighbours(): + for entity_id in building.get_neighbors(): neighbor = self._world_info.get_entity(entity_id) if isinstance(neighbor, Road): self._target_areas.add(entity_id) for entity in self._world_info.get_entities_of_types([Refuge]): refuge: Refuge = cast(Refuge, entity) - for entity_id in refuge.get_neighbours(): + for entity_id in refuge.get_neighbors(): neighbor = self._world_info.get_entity(entity_id) if isinstance(neighbor, Road): self._priority_areas.add(entity_id) @@ -107,12 +109,12 @@ def calculate(self) -> PoliceTargetAllocator: agents, key=cmp_to_key(self._compare_by_distance(target_entity)) ) result = agents.pop(0) - info = self._agent_info_map[result.get_id()] + info = self._agent_info_map[result.get_entity_id()] if info is not None: info._can_new_action = False info._target = target info.command_time = current_time - self._agent_info_map[result.get_id()] = info + self._agent_info_map[result.get_entity_id()] = info removes.append(target) for r in removes: @@ -128,13 +130,13 @@ def calculate(self) -> PoliceTargetAllocator: if len(areas) > 0: areas.sort(key=cmp_to_key(self._compare_by_distance(agent))) result = areas.pop(0) - self._target_areas.remove(result.get_id()) - info = self._agent_info_map[agent.get_id()] + self._target_areas.remove(result.get_entity_id()) + info = self._agent_info_map[agent.get_entity_id()] if info is not None: info._can_new_action = False - info._target = result.get_id() + info._target = result.get_entity_id() info.command_time = current_time - self._agent_info_map[agent.get_id()] = info + self._agent_info_map[agent.get_entity_id()] = info return self @@ -146,7 +148,7 @@ def _get_action_agents( ) -> list[PoliceForce]: result = [] for entity in self._world_info.get_entities_of_types([PoliceForce]): - info = info_map[entity.get_id()] + info = info_map[entity.get_entity_id()] if info is not None and info._can_new_action: result.append(entity) return result @@ -156,10 +158,10 @@ def _compare_by_distance( ) -> Callable[[Entity, Entity], int]: def _cmp_func(entity_a: Entity, entity_b: Entity) -> int: distance_a = self._world_info.get_distance( - target_entity.get_id(), entity_a.get_id() + target_entity.get_entity_id(), entity_a.get_entity_id() ) distance_b = self._world_info.get_distance( - target_entity.get_id(), entity_b.get_id() + target_entity.get_entity_id(), entity_b.get_entity_id() ) if distance_a < distance_b: return -1 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 035cc61..ad837a4 100644 --- a/adf_core_python/implement/module/complex/default_road_detector.py +++ b/adf_core_python/implement/module/complex/default_road_detector.py @@ -1,10 +1,6 @@ from typing import Optional, cast -from rcrs_core.entities.building import Building -from rcrs_core.entities.gasStation import GasStation -from rcrs_core.entities.refuge import Refuge -from rcrs_core.entities.road import Road -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import Building, EntityID, GasStation, Refuge, Road from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData @@ -59,7 +55,7 @@ def resume(self, precompute_data: PrecomputeData) -> RoadDetector: for entity in entities: if not isinstance(entity, Building): continue - for entity_id in entity.get_neighbours(): + for entity_id in entity.get_neighbors(): neighbor = self._world_info.get_entity(entity_id) if isinstance(neighbor, Road): self._target_areas.add(entity_id) @@ -68,7 +64,7 @@ def resume(self, precompute_data: PrecomputeData) -> RoadDetector: for entity in self._world_info.get_entities_of_types([Refuge]): if not isinstance(entity, Building): continue - for entity_id in entity.get_neighbours(): + for entity_id in entity.get_neighbors(): neighbor = self._world_info.get_entity(entity_id) if isinstance(neighbor, Road): self._priority_roads.add(entity_id) @@ -86,7 +82,7 @@ def prepare(self) -> RoadDetector: ) for entity in entities: building: Building = cast(Building, entity) - for entity_id in building.get_neighbours(): + for entity_id in building.get_neighbors(): neighbor = self._world_info.get_entity(entity_id) if isinstance(neighbor, Road): self._target_areas.add(entity_id) @@ -94,7 +90,7 @@ def prepare(self) -> RoadDetector: self._priority_roads = set() for entity in self._world_info.get_entities_of_types([Refuge]): refuge: Refuge = cast(Refuge, entity) - for entity_id in refuge.get_neighbours(): + for entity_id in refuge.get_neighbors(): neighbor = self._world_info.get_entity(entity_id) if isinstance(neighbor, Road): self._priority_roads.add(entity_id) diff --git a/adf_core_python/implement/module/complex/default_search.py b/adf_core_python/implement/module/complex/default_search.py index 05d7c88..0d5c714 100644 --- a/adf_core_python/implement/module/complex/default_search.py +++ b/adf_core_python/implement/module/complex/default_search.py @@ -1,9 +1,6 @@ from typing import Optional, cast -from rcrs_core.entities.building import Building -from rcrs_core.entities.entity import Entity -from rcrs_core.entities.refuge import Refuge -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import Building, Entity, EntityID, Refuge from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData @@ -98,7 +95,7 @@ def _get_search_targets(self) -> set[EntityID]: cluster_index ) building_entity_ids: list[EntityID] = [ - entity.get_id() + entity.get_entity_id() for entity in cluster_entities if isinstance(entity, Building) and not isinstance(entity, Refuge) ] 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 23a9d85..68c9ff8 100644 --- a/adf_core_python/implement/tactics/default_tactics_ambulance_center.py +++ b/adf_core_python/implement/tactics/default_tactics_ambulance_center.py @@ -1,6 +1,6 @@ from typing import cast -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import EntityID from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData 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 76b6c47..688c845 100644 --- a/adf_core_python/implement/tactics/default_tactics_ambulance_team.py +++ b/adf_core_python/implement/tactics/default_tactics_ambulance_team.py @@ -1,6 +1,6 @@ from typing import Optional, cast -from rcrs_core.entities.ambulanceTeam import AmbulanceTeam +from rcrscore.entities import AmbulanceTeam from adf_core_python.core.agent.action.action import Action from adf_core_python.core.agent.action.common.action_rest import ActionRest 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 0d9740e..de4f706 100644 --- a/adf_core_python/implement/tactics/default_tactics_fire_brigade.py +++ b/adf_core_python/implement/tactics/default_tactics_fire_brigade.py @@ -1,6 +1,6 @@ from typing import Optional, cast -from rcrs_core.entities.fireBrigade import FireBrigade +from rcrscore.entities import FireBrigade from adf_core_python.core.agent.action.action import Action from adf_core_python.core.agent.action.common.action_rest import ActionRest 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 0b15a3e..ef6425d 100644 --- a/adf_core_python/implement/tactics/default_tactics_fire_station.py +++ b/adf_core_python/implement/tactics/default_tactics_fire_station.py @@ -1,6 +1,6 @@ from typing import cast -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import EntityID from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData 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 6a1f2f6..8b75a07 100644 --- a/adf_core_python/implement/tactics/default_tactics_police_force.py +++ b/adf_core_python/implement/tactics/default_tactics_police_force.py @@ -1,6 +1,6 @@ from typing import Optional, cast -from rcrs_core.entities.policeForce import PoliceForce +from rcrscore.entities import PoliceForce from adf_core_python.core.agent.action.action import Action from adf_core_python.core.agent.action.common.action_rest import ActionRest 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 df095cc..d605244 100644 --- a/adf_core_python/implement/tactics/default_tactics_police_office.py +++ b/adf_core_python/implement/tactics/default_tactics_police_office.py @@ -1,6 +1,6 @@ from typing import cast -from rcrs_core.worldmodel.entityID import EntityID +from rcrscore.entities import EntityID from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.develop.develop_data import DevelopData diff --git a/poetry.lock b/poetry.lock index 0dc5c07..371973e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -980,24 +980,24 @@ files = [ ] [[package]] -name = "rcrs_core" +name = "rcrscore" version = "0.1.0" -description = "RoboCup Rescue Simulation(RCRS Agent Development Library)" +description = "Add your description here" optional = false -python-versions = "*" +python-versions = ">=3.13" groups = ["main"] files = [] develop = false [package.dependencies] -protobuf = ">=5.28" -rtree = "*" +protobuf = ">=6.31.1" +rtree = ">=1.4.0" [package.source] type = "git" url = "https://github.com/adf-python/rcrs-core-python" -reference = "v0.1.0" -resolved_reference = "42a20e312de20ea46f1e0622a82f41e81fc3514f" +reference = "improve" +resolved_reference = "288c666003039b77c09e91d0067f61ad2b125ce4" [[package]] name = "requests" @@ -1743,5 +1743,5 @@ test = ["pytest (>=6.0.0)", "setuptools (>=65)"] [metadata] lock-version = "2.1" -python-versions = "^3.12" -content-hash = "ca8c4ce733e53da7e9b9208c3341bcc8043863f16f8e4300e5cf2212495690c2" +python-versions = "^3.13" +content-hash = "0f25d8ec7e7a27c7ea9006b97135f44ede3114ec3a9a6f19702345464d0d7b51" diff --git a/pyproject.toml b/pyproject.toml index e2bb97b..080aba5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,8 +10,8 @@ readme = "README.md" package-mode = true [tool.poetry.dependencies] -python = "^3.12" -rcrs_core = { git = "https://github.com/adf-python/rcrs-core-python", tag = "v0.1.0" } +python = "^3.13" +rcrscore = { git = "https://github.com/adf-python/rcrs-core-python", branch = "improve" } pyyaml = "^6.0.2" types-pyyaml = "^6.0.12.20240808" scikit-learn = "^1.5.2" From 58a94b739d6abb1b940443f99bc0d387556640c4 Mon Sep 17 00:00:00 2001 From: shima004 Date: Mon, 4 Aug 2025 02:58:30 +0900 Subject: [PATCH 02/13] Refactor code for improved type safety and null handling --- .../module/complex/sample_road_detector.py | 21 ++-- .../team_name/module/complex/sample_search.py | 3 +- adf_core_python/core/agent/info/world_info.py | 4 +- .../module/algorithm/gateway_clustering.py | 4 +- .../complex/gateway_target_allocator.py | 5 +- .../core/gateway/gateway_module.py | 2 + .../action/default_extend_action_clear.py | 97 +++++++++++++------ .../action/default_extend_action_rescue.py | 4 +- .../action/default_extend_action_transport.py | 19 +++- .../default_command_executor_ambulance.py | 4 +- .../default_command_executor_police.py | 19 ++-- .../default_command_executor_scout.py | 17 ++-- .../default_command_executor_scout_police.py | 17 ++-- .../module/algorithm/a_star_path_planning.py | 6 +- .../algorithm/dijkstra_path_planning.py | 12 +-- .../module/algorithm/k_means_clustering.py | 7 +- .../default_ambulance_target_allocator.py | 7 +- .../complex/default_fire_target_allocator.py | 7 +- .../module/complex/default_human_detector.py | 2 + .../default_police_target_allocator.py | 19 ++-- .../module/complex/default_road_detector.py | 21 ++-- .../module/complex/default_search.py | 3 +- 22 files changed, 197 insertions(+), 103 deletions(-) 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 87e188a..2e71d61 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 @@ -37,7 +37,7 @@ def __init__( ) self.register_sub_module(self._path_planning) - self._result = None + self._result: Optional[EntityID] = None def precompute(self, precompute_data: PrecomputeData) -> RoadDetector: super().precompute(precompute_data) @@ -108,7 +108,7 @@ def update_info(self, message_manager: MessageManager) -> RoadDetector: if isinstance(entity, Building): self._result = None elif isinstance(entity, Road): - road: Road = cast(Road, entity) + road = entity if road.get_blockades() == []: self._target_areas.remove(self._result) self._result = None @@ -117,7 +117,9 @@ def update_info(self, message_manager: MessageManager) -> RoadDetector: def calculate(self) -> RoadDetector: if self._result is None: - position_entity_id: EntityID = self._agent_info.get_position_entity_id() + position_entity_id = self._agent_info.get_position_entity_id() + if position_entity_id is None: + return self if position_entity_id in self._target_areas: self._result = position_entity_id return self @@ -128,21 +130,22 @@ def calculate(self) -> RoadDetector: self._priority_roads = self._priority_roads - set(remove_list) if len(self._priority_roads) > 0: - _nearest_target_area = self._agent_info.get_position_entity_id() + agent_position = self._agent_info.get_position_entity_id() + if agent_position is None: + return self + _nearest_target_area = agent_position _nearest_distance = float("inf") for target_area in self._target_areas: if ( - self._world_info.get_distance( - self._agent_info.get_position_entity_id(), target_area - ) + self._world_info.get_distance(agent_position, target_area) < _nearest_distance ): _nearest_target_area = target_area _nearest_distance = self._world_info.get_distance( - self._agent_info.get_position_entity_id(), target_area + agent_position, target_area ) path: list[EntityID] = self._path_planning.get_path( - self._agent_info.get_position_entity_id(), _nearest_target_area + agent_position, _nearest_target_area ) if path is not None and len(path) > 0: self._result = path[-1] diff --git a/adf_core_python/cli/template/src/team_name/module/complex/sample_search.py b/adf_core_python/cli/template/src/team_name/module/complex/sample_search.py index a441a07..888f657 100644 --- a/adf_core_python/cli/template/src/team_name/module/complex/sample_search.py +++ b/adf_core_python/cli/template/src/team_name/module/complex/sample_search.py @@ -64,7 +64,8 @@ def update_info(self, message_manager: MessageManager) -> Search: ) searched_building_id = self._agent_info.get_position_entity_id() - self._unreached_building_ids.discard(searched_building_id) + if searched_building_id is not None: + self._unreached_building_ids.discard(searched_building_id) if len(self._unreached_building_ids) == 0: self._unreached_building_ids = self._get_search_targets() diff --git a/adf_core_python/core/agent/info/world_info.py b/adf_core_python/core/agent/info/world_info.py index 8ac55c9..acea5da 100644 --- a/adf_core_python/core/agent/info/world_info.py +++ b/adf_core_python/core/agent/info/world_info.py @@ -1,4 +1,4 @@ -from typing import Any, Optional, cast +from typing import Any, Optional from rcrscore.entities import EntityID from rcrscore.entities.area import Area @@ -199,7 +199,7 @@ def get_blockades(self, area: Area) -> set[Blockade]: for blockade_entity_id in blockade_entity_ids: blockades_entity = self.get_entity(blockade_entity_id) if isinstance(blockades_entity, Blockade): - blockades.add(cast(Blockade, blockades_entity)) + blockades.add(blockades_entity) return blockades def add_entity(self, entity: Entity) -> None: diff --git a/adf_core_python/core/gateway/component/module/algorithm/gateway_clustering.py b/adf_core_python/core/gateway/component/module/algorithm/gateway_clustering.py index ade93a0..c01047f 100644 --- a/adf_core_python/core/gateway/component/module/algorithm/gateway_clustering.py +++ b/adf_core_python/core/gateway/component/module/algorithm/gateway_clustering.py @@ -78,7 +78,9 @@ def get_cluster_entities(self, cluster_index: int) -> list[Entity]: entity_ids: list[int] = json.loads(json_str) entities: list[Entity] = [] for entity_id in entity_ids: - entities.append(self._world_info.get_entity(EntityID(entity_id))) + entity = self._world_info.get_entity(EntityID(entity_id)) + if entity is not None: + entities.append(entity) return entities def get_cluster_entity_ids(self, cluster_index: int) -> list[EntityID]: diff --git a/adf_core_python/core/gateway/component/module/complex/gateway_target_allocator.py b/adf_core_python/core/gateway/component/module/complex/gateway_target_allocator.py index 1f7a57f..df35491 100644 --- a/adf_core_python/core/gateway/component/module/complex/gateway_target_allocator.py +++ b/adf_core_python/core/gateway/component/module/complex/gateway_target_allocator.py @@ -63,11 +63,12 @@ def calculate(self) -> GatewayTargetAllocator: def get_result(self) -> dict[EntityID, EntityID]: response = self._gateway_module.execute("getResult") - response_keys = response.get_all_keys() + response_keys = response.data.keys() result: dict[EntityID, EntityID] = {} for key in response_keys: + value = response.get_value(key) result[EntityID(int(key))] = EntityID( - int(response.get_value_or_default(key, "-1")) + int(value if value is not None else "-1") ) return result diff --git a/adf_core_python/core/gateway/gateway_module.py b/adf_core_python/core/gateway/gateway_module.py index 99f9115..68bb446 100644 --- a/adf_core_python/core/gateway/gateway_module.py +++ b/adf_core_python/core/gateway/gateway_module.py @@ -54,6 +54,8 @@ def initialize(self, module_name: str, default_class_name: str) -> str: return self.get_gateway_class_name() def get_execute_response(self) -> Config: + if self._result is None: + raise RuntimeError("No execution result available") return self._result def set_execute_response(self, result: Config) -> None: 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 879cbdf..7e09b41 100644 --- a/adf_core_python/implement/action/default_extend_action_clear.py +++ b/adf_core_python/implement/action/default_extend_action_clear.py @@ -59,7 +59,7 @@ def __init__( ) ) - self._target_entity_id = None + self._target_entity_id: Optional[EntityID] = None self._move_point_cache: dict[EntityID, Optional[set[tuple[float, float]]]] = {} self._old_clear_x = 0 self._old_clear_y = 0 @@ -135,14 +135,14 @@ def calculate(self) -> ExtendAction: return self agent_position_entity_id = police_force.get_position() + if agent_position_entity_id is None: + return self target_entity = self.world_info.get_entity(self._target_entity_id) position_entity = self.world_info.get_entity(agent_position_entity_id) if target_entity is None or isinstance(target_entity, Area) is False: return self if isinstance(position_entity, Road): - self.result = self._get_rescue_action( - police_force, cast(Road, position_entity) - ) + self.result = self._get_rescue_action(police_force, position_entity) if self.result is not None: return self @@ -180,7 +180,7 @@ def calculate(self) -> ExtendAction: police_force, cast(Area, entity) ) if self.result is not None and isinstance(self.result, ActionMove): - action_move = cast(ActionMove, self.result) + action_move = self.result if action_move.is_destination_defined(): self.result = None @@ -193,15 +193,16 @@ def _need_rest(self, police_force: PoliceForce) -> bool: hp = police_force.get_hp() damage = police_force.get_damage() - if hp == 0 or damage == 0: + if hp is None or damage is None or hp == 0 or damage == 0: return False active_time = (hp / damage) + (1 if (hp % damage) != 0 else 0) if self._kernel_time == -1: self._kernel_time = self.scenario_info.get_value("kernel.timesteps", -1) - return damage >= self._threshold_rest or ( - active_time + self.agent_info.get_time() < self._kernel_time + return damage is not None and ( + damage >= self._threshold_rest + or (active_time + self.agent_info.get_time() < self._kernel_time) ) def _calc_rest( @@ -211,6 +212,8 @@ def _calc_rest( target_entity_ids: list[EntityID], ) -> Optional[Action]: position_entity_id = police_force.get_position() + if position_entity_id is None: + return None refuges = self.world_info.get_entity_ids_of_types([Refuge]) current_size = len(refuges) if position_entity_id in refuges: @@ -244,12 +247,13 @@ def _calc_rest( def _get_rescue_action( self, police_entity: PoliceForce, road: Road ) -> Optional[Action]: + road_blockades = road.get_blockades() blockades = set( [] - if road.get_blockades() is None + if road_blockades is None else [ cast(Blockade, self.world_info.get_entity(blockade_entity_id)) - for blockade_entity_id in road.get_blockades() + for blockade_entity_id in road_blockades ] ) agent_entities = set( @@ -263,15 +267,30 @@ def _get_rescue_action( for agent_entity in agent_entities: human = cast(Human, agent_entity) - if human.get_position().get_value() != road.get_entity_id().get_value(): + human_position = human.get_position() + if ( + human_position is None + or human_position.get_value() != road.get_entity_id().get_value() + ): continue human_x = human.get_x() human_y = human.get_y() + if ( + human_x is None + or human_y is None + or police_x is None + or police_y is None + ): + continue + action_clear: Optional[ActionClear | ActionClearArea] = None clear_blockade: Optional[Blockade] = None for blockade in blockades: - if not self._is_inside(human_x, human_y, blockade.get_apexes()): + blockade_apexes = blockade.get_apexes() + if blockade_apexes is None or not self._is_inside( + human_x, human_y, blockade_apexes + ): continue distance = self._get_distance(police_x, police_y, human_x, human_y) @@ -373,7 +392,10 @@ def _get_distance(self, x1: float, y1: float, x2: float, y2: float) -> float: def _is_intersecting_area( self, agent_x: float, agent_y: float, point_x: float, point_y: float, area: Area ) -> bool: - for edge in area.get_edges(): + edges = area.get_edges() + if edges is None: + return False + for edge in edges: start_x = edge.get_start_x() start_y = edge.get_start_y() end_x = edge.get_end_x() @@ -483,11 +505,13 @@ def _get_move_points(self, road: Road) -> set[tuple[float, float]]: if self._is_inside(mid_x, mid_y, apex): points.add((mid_x, mid_y)) - for edge in road.get_edges(): - mid_x = (edge.get_start_x() + edge.get_end_x()) / 2.0 - mid_y = (edge.get_start_y() + edge.get_end_y()) / 2.0 - if (mid_x, mid_y) in points: - points.remove((mid_x, mid_y)) + edges = road.get_edges() + if edges is not None: + for edge in edges: + mid_x = (edge.get_start_x() + edge.get_end_x()) / 2.0 + mid_y = (edge.get_start_y() + edge.get_end_y()) / 2.0 + if (mid_x, mid_y) in points: + points.remove((mid_x, mid_y)) self._move_point_cache[road.get_entity_id()] = points @@ -518,6 +542,8 @@ def _is_intersecting_blockade( blockade: Blockade, ) -> bool: apexes = blockade.get_apexes() + if apexes is None or len(apexes) < 4: + return False for i in range(0, len(apexes) - 3, 2): line1 = LineString( [(apexes[i], apexes[i + 1]), (apexes[i + 2], apexes[i + 3])] @@ -532,6 +558,8 @@ def _is_intersecting_blockades( ) -> bool: apexes1 = blockade1.get_apexes() apexes2 = blockade2.get_apexes() + if apexes1 is None or apexes2 is None or len(apexes1) < 4 or len(apexes2) < 4: + return False for i in range(0, len(apexes1) - 2, 2): for j in range(0, len(apexes2) - 2, 2): line1 = LineString( @@ -593,20 +621,26 @@ def _get_area_clear_action( if min_distance < self._clear_distance: return ActionClear(clear_blockade) else: - return ActionMove( - [police_entity.get_position()], - clear_blockade.get_x(), - clear_blockade.get_y(), - ) + position = police_entity.get_position() + if position is not None: + return ActionMove( + [position], + clear_blockade.get_x(), + clear_blockade.get_y(), + ) agent_x = police_entity.get_x() agent_y = police_entity.get_y() + if agent_x is None or agent_y is None: + return None clear_blockade = None min_point_distance = sys.float_info.max clear_x = 0 clear_y = 0 for blockade in blockades: apexes = blockade.get_apexes() + if apexes is None or len(apexes) < 4: + continue for i in range(0, len(apexes) - 2, 2): distance = self._get_distance( agent_x, agent_y, apexes[i], apexes[i + 1] @@ -625,7 +659,9 @@ def _get_area_clear_action( clear_x = int(agent_x + vector[0]) clear_y = int(agent_y + vector[1]) return ActionClearArea(clear_x, clear_y) - return ActionMove([police_entity.get_position()], clear_x, clear_y) + position = police_entity.get_position() + if position is not None: + return ActionMove([position], clear_x, clear_y) return None @@ -637,7 +673,12 @@ def _get_neighbour_position_action( ) -> Optional[Action]: agent_x = police_entity.get_x() agent_y = police_entity.get_y() - position = self.world_info.get_entity(police_entity.get_position()) + if agent_x is None or agent_y is None: + return None + position_id = police_entity.get_position() + if position_id is None: + return None + position = self.world_info.get_entity(position_id) if position is None: return None @@ -646,7 +687,7 @@ def _get_neighbour_position_action( return None if isinstance(position, Road): - road = cast(Road, position) + road = position if road.get_blockades() != []: mid_x = (edge.get_start_x() + edge.get_end_x()) / 2.0 mid_y = (edge.get_start_y() + edge.get_end_y()) / 2.0 @@ -716,7 +757,7 @@ def _get_neighbour_position_action( return action_move if isinstance(target, Road): - road = cast(Road, target) + road = target if road.get_blockades() == []: return ActionMove([position.get_entity_id(), target.get_entity_id()]) @@ -726,6 +767,8 @@ def _get_neighbour_position_action( clear_y = 0 for blockade in self.world_info.get_blockades(road): apexes = blockade.get_apexes() + if apexes is None or len(apexes) < 4: + continue for i in range(0, len(apexes) - 2, 2): distance = self._get_distance( agent_x, agent_y, apexes[i], apexes[i + 1] 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 df1e067..b4624bb 100644 --- a/adf_core_python/implement/action/default_extend_action_rescue.py +++ b/adf_core_python/implement/action/default_extend_action_rescue.py @@ -117,7 +117,7 @@ def _calc_rescue( return None if isinstance(target_entity, Human): - human = cast(Human, target_entity) + human = target_entity if human.get_hp() == 0: return None @@ -139,7 +139,7 @@ def _calc_rescue( return None if isinstance(target_entity, Blockade): - blockade = cast(Blockade, target_entity) + blockade = target_entity blockade_position = blockade.get_position() if blockade_position is None: return None 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 a64b23c..5fe0b9d 100644 --- a/adf_core_python/implement/action/default_extend_action_transport.py +++ b/adf_core_python/implement/action/default_extend_action_transport.py @@ -125,6 +125,8 @@ def calc_rescue( return None agent_position = agent.get_position() + if agent_position is None: + return None if isinstance(target_entity, Human): human = target_entity if human.get_position() is None: @@ -133,6 +135,8 @@ def calc_rescue( return None target_position = human.get_position() + if target_position is None: + return None if agent_position == target_position: if isinstance(human, Civilian) and ((human.get_buriedness() or 0) == 0): return ActionLoad(human.get_entity_id()) @@ -143,6 +147,8 @@ def calc_rescue( return None if isinstance(target_entity, Area): + if agent_position is None: + return None path = path_planning.get_path(agent_position, target_entity.get_entity_id()) if path is not None and len(path) > 0: return ActionMove(path) @@ -163,6 +169,8 @@ def calc_unload( return ActionUnload() agent_position = agent.get_position() + if agent_position is None: + return None if target_id is None or transport_human.get_entity_id() == target_id: position = self.world_info.get_entity(agent_position) if position is None: @@ -181,10 +189,11 @@ def calc_unload( target_entity = self.world_info.get_entity(target_id) if isinstance(target_entity, Human): - human = cast(Human, target_entity) - if human.get_position() is not None: + human = target_entity + human_position = human.get_position() + if human_position is not None: return self.calc_refuge_action( - agent, path_planning, human.get_position(), True + agent, path_planning, human_position, True ) path = self.get_nearest_refuge_path(agent, path_planning) if path is not None and len(path) > 0: @@ -200,6 +209,8 @@ def calc_refuge_action( is_unload: bool, ) -> Optional[ActionMove | ActionUnload | ActionRest]: position = human.get_position() + if position is None: + return None refuges = self.world_info.get_entity_ids_of_types([Refuge]) size = len(refuges) @@ -235,6 +246,8 @@ def get_nearest_refuge_path( self, human: Human, path_planning: PathPlanning ) -> list[EntityID]: position = human.get_position() + if position is None: + return [] refuges = self.world_info.get_entity_ids_of_types([Refuge]) nearest_path = None diff --git a/adf_core_python/implement/centralized/default_command_executor_ambulance.py b/adf_core_python/implement/centralized/default_command_executor_ambulance.py index aa6bf81..d4783c6 100644 --- a/adf_core_python/implement/centralized/default_command_executor_ambulance.py +++ b/adf_core_python/implement/centralized/default_command_executor_ambulance.py @@ -254,8 +254,8 @@ def _is_command_completed(self) -> bool: if isinstance(human, Civilian): self._command_type = self.ACTION_RESCUE return self._is_command_completed() - if human.get_position() is not None: - position = human.get_position() + position = human.get_position() + if position is not None: if position in self._world_info.get_entity_ids_of_types( [AmbulanceTeam] ): diff --git a/adf_core_python/implement/centralized/default_command_executor_police.py b/adf_core_python/implement/centralized/default_command_executor_police.py index c5d756b..abfb51f 100644 --- a/adf_core_python/implement/centralized/default_command_executor_police.py +++ b/adf_core_python/implement/centralized/default_command_executor_police.py @@ -202,11 +202,13 @@ def _is_command_completed(self) -> bool: match self._command_type: case self.ACTION_REST: if self._target is None: - return agent.get_damage() == 0 + damage = agent.get_damage() + return damage is not None and damage == 0 if (target_entity := self._world_info.get_entity(self._target)) is None: return False if isinstance(target_entity, Refuge): - return agent.get_damage() == 0 + damage = agent.get_damage() + return damage is not None and damage == 0 return False case self.ACTION_MOVE: return ( @@ -218,17 +220,19 @@ def _is_command_completed(self) -> bool: return True entity = self._world_info.get_entity(self._target) if isinstance(entity, Road): - if entity.get_blockades is not None: - return len(entity.get_blockades()) == 0 + blockades = entity.get_blockades() + if blockades is not None: + return len(blockades) == 0 return self._agent_info.get_position_entity_id() == self._target return True case self.ACTION_AUTONOMY: if self._target is not None: target_entity = self._world_info.get_entity(self._target) if isinstance(target_entity, Refuge): + damage = agent.get_damage() self._command_type = ( self.ACTION_REST - if agent.get_damage() > 0 + if damage is not None and damage > 0 else self.ACTION_CLEAR ) return self._is_command_completed() @@ -238,8 +242,9 @@ def _is_command_completed(self) -> bool: elif isinstance(target_entity, Human): if target_entity.get_hp() == 0: return True - if target_entity.get_position() is not None and isinstance( - self._world_info.get_entity(target_entity.get_position()), + position = target_entity.get_position() + if position is not None and isinstance( + self._world_info.get_entity(position), Area, ): self._target = target_entity.get_position() diff --git a/adf_core_python/implement/centralized/default_command_executor_scout.py b/adf_core_python/implement/centralized/default_command_executor_scout.py index 0ff628b..7941ed5 100644 --- a/adf_core_python/implement/centralized/default_command_executor_scout.py +++ b/adf_core_python/implement/centralized/default_command_executor_scout.py @@ -1,6 +1,6 @@ from typing import Optional, cast -from rcrscore.entities import Area, EntityID, Human, Refuge +from rcrscore.entities import Building, EntityID, Human, Refuge, Road from adf_core_python.core.agent.action.common.action_move import ActionMove from adf_core_python.core.agent.communication.message_manager import MessageManager @@ -59,6 +59,8 @@ def set_command(self, command: CommandScout) -> CommandExecutor: target = command.get_command_target_entity_id() if target is None: target = self._agent_info.get_position_entity_id() + if target is None: + return self self._command_type = self.ACTION_SCOUT self._commander = command.get_sender_entity_id() @@ -66,7 +68,7 @@ def set_command(self, command: CommandScout) -> CommandExecutor: if (scout_distance := command.get_scout_range()) is None: return self - for entity in self._world_info.get_entities_of_types([Area]): + for entity in self._world_info.get_entities_of_types([Road, Building]): if isinstance(entity, Refuge): continue if ( @@ -83,9 +85,10 @@ def calculate(self) -> CommandExecutor: case self.ACTION_SCOUT: if len(self._targets) == 0: return self - path = self._path_planning.get_path( - self._agent_info.get_position_entity_id(), self._targets[0] - ) + agent_position = self._agent_info.get_position_entity_id() + if agent_position is None: + return self + path = self._path_planning.get_path(agent_position, self._targets[0]) if path is None: return self self._result = ActionMove(path) @@ -150,7 +153,9 @@ def _is_command_completed(self) -> bool: match self._command_type: case self.ACTION_SCOUT: if len(self._targets) != 0: - for entity in self._world_info.get_entities_of_types([Area]): + for entity in self._world_info.get_entities_of_types( + [Road, Building] + ): self._targets.remove(entity.get_entity_id()) return len(self._targets) == 0 case _: diff --git a/adf_core_python/implement/centralized/default_command_executor_scout_police.py b/adf_core_python/implement/centralized/default_command_executor_scout_police.py index c80d68a..f1806ad 100644 --- a/adf_core_python/implement/centralized/default_command_executor_scout_police.py +++ b/adf_core_python/implement/centralized/default_command_executor_scout_police.py @@ -1,6 +1,6 @@ from typing import Optional, cast -from rcrscore.entities import Area, EntityID, Human, Refuge +from rcrscore.entities import Building, EntityID, Human, Refuge, Road from adf_core_python.core.agent.action.common.action_move import ActionMove from adf_core_python.core.agent.communication.message_manager import MessageManager @@ -64,6 +64,8 @@ def set_command(self, command: CommandScout) -> CommandExecutor: target = command.get_command_target_entity_id() if target is None: target = self._agent_info.get_position_entity_id() + if target is None: + return self self._command_type = self.ACTION_SCOUT self._commander = command.get_sender_entity_id() @@ -71,7 +73,7 @@ def set_command(self, command: CommandScout) -> CommandExecutor: if (scout_distance := command.get_scout_range()) is None: return self - for entity in self._world_info.get_entities_of_types([Area]): + for entity in self._world_info.get_entities_of_types([Road, Building, Refuge]): if isinstance(entity, Refuge): continue if ( @@ -88,9 +90,10 @@ def calculate(self) -> CommandExecutor: case self.ACTION_SCOUT: if len(self._targets) == 0: return self - path = self._path_planning.get_path( - self._agent_info.get_position_entity_id(), self._targets[0] - ) + agent_position = self._agent_info.get_position_entity_id() + if agent_position is None: + return self + path = self._path_planning.get_path(agent_position, self._targets[0]) if path is None: return self action = ( @@ -162,7 +165,9 @@ def _is_command_completed(self) -> bool: match self._command_type: case self.ACTION_SCOUT: if len(self._targets) != 0: - for entity in self._world_info.get_entities_of_types([Area]): + for entity in self._world_info.get_entities_of_types( + [Road, Building, Refuge] + ): self._targets.remove(entity.get_entity_id()) return len(self._targets) == 0 case _: diff --git a/adf_core_python/implement/module/algorithm/a_star_path_planning.py b/adf_core_python/implement/module/algorithm/a_star_path_planning.py index 5a80339..e31cef3 100644 --- a/adf_core_python/implement/module/algorithm/a_star_path_planning.py +++ b/adf_core_python/implement/module/algorithm/a_star_path_planning.py @@ -1,6 +1,6 @@ from __future__ import annotations -from rcrscore.entities import Area, Entity, EntityID +from rcrscore.entities import Area, Building, Entity, EntityID, Road from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo @@ -24,7 +24,9 @@ def __init__( super().__init__( agent_info, world_info, scenario_info, module_manager, develop_data ) - entities: list[Entity] = self._world_info.get_entities_of_types([Area]) + entities: list[Entity] = self._world_info.get_entities_of_types( + [Building, Road] + ) self._graph: dict[EntityID, set[EntityID]] = {} for entity in entities: if isinstance(entity, Area): diff --git a/adf_core_python/implement/module/algorithm/dijkstra_path_planning.py b/adf_core_python/implement/module/algorithm/dijkstra_path_planning.py index 1a592a8..dac1549 100644 --- a/adf_core_python/implement/module/algorithm/dijkstra_path_planning.py +++ b/adf_core_python/implement/module/algorithm/dijkstra_path_planning.py @@ -3,7 +3,7 @@ import heapq from typing import Optional -from rcrscore.entities import Area, EntityID +from rcrscore.entities import Area, Building, EntityID, Road from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo @@ -27,7 +27,7 @@ def __init__( ) self.graph: dict[EntityID, list[tuple[EntityID, float]]] = {} # グラフの構築 - for area in self._world_info.get_entities_of_types([Area]): + for area in self._world_info.get_entities_of_types([Road, Building]): if not isinstance(area, Area): continue if (neighbors := area.get_neighbors()) is None: @@ -71,10 +71,10 @@ def get_path( previous[neighbor] = current_node path: list[EntityID] = [] - current_node = to_entity_id - while current_node is not None: - path.append(current_node) - current_node = previous[current_node] + current_path_node: Optional[EntityID] = to_entity_id + while current_path_node is not None: + path.append(current_path_node) + current_path_node = previous.get(current_path_node) return path[::-1] 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 9fe0517..a567abe 100644 --- a/adf_core_python/implement/module/algorithm/k_means_clustering.py +++ b/adf_core_python/implement/module/algorithm/k_means_clustering.py @@ -35,7 +35,10 @@ def __init__( super().__init__( agent_info, world_info, scenario_info, module_manager, develop_data ) - match agent_info.get_myself().get_urn(): + myself = agent_info.get_myself() + if myself is None: + raise RuntimeError("Could not get agent entity") + match myself.get_urn(): case EntityURN.AMBULANCE_TEAM: self._cluster_number = int( scenario_info.get_value( @@ -63,7 +66,7 @@ def __init__( sorted_entities = sorted( world_info.get_entities_of_types( [ - agent_info.get_myself().__class__, + myself.__class__, ] ), key=lambda entity: entity.get_entity_id().get_value(), diff --git a/adf_core_python/implement/module/complex/default_ambulance_target_allocator.py b/adf_core_python/implement/module/complex/default_ambulance_target_allocator.py index 50f0f35..bdeb89a 100644 --- a/adf_core_python/implement/module/complex/default_ambulance_target_allocator.py +++ b/adf_core_python/implement/module/complex/default_ambulance_target_allocator.py @@ -109,9 +109,10 @@ def _get_action_agents( ) -> list[AmbulanceTeam]: result = [] for entity in self._world_info.get_entities_of_types([AmbulanceTeam]): - info = info_map[entity.get_entity_id()] - if info is not None and info._can_new_action: - result.append(entity) + if isinstance(entity, AmbulanceTeam): + info = info_map[entity.get_entity_id()] + if info is not None and info._can_new_action: + result.append(entity) return result def _compare_by_distance( diff --git a/adf_core_python/implement/module/complex/default_fire_target_allocator.py b/adf_core_python/implement/module/complex/default_fire_target_allocator.py index c32e716..4373d5d 100644 --- a/adf_core_python/implement/module/complex/default_fire_target_allocator.py +++ b/adf_core_python/implement/module/complex/default_fire_target_allocator.py @@ -108,9 +108,10 @@ def _get_action_agents( ) -> list[FireBrigade]: result = [] for entity in self._world_info.get_entities_of_types([FireBrigade]): - info = info_map[entity.get_entity_id()] - if info is not None and info._can_new_action: - result.append(entity) + if isinstance(entity, FireBrigade): + info = info_map[entity.get_entity_id()] + if info is not None and info._can_new_action: + result.append(entity) return result def _compare_by_distance( diff --git a/adf_core_python/implement/module/complex/default_human_detector.py b/adf_core_python/implement/module/complex/default_human_detector.py index a667524..8f5e860 100644 --- a/adf_core_python/implement/module/complex/default_human_detector.py +++ b/adf_core_python/implement/module/complex/default_human_detector.py @@ -124,6 +124,8 @@ def _is_valid_human(self, target_entity_id: EntityID) -> bool: if buriedness is None: return False myself = self._agent_info.get_myself() + if myself is None: + return False if myself.get_urn() == EntityURN.FIRE_BRIGADE and buriedness == 0: return False if myself.get_urn() == EntityURN.AMBULANCE_TEAM and buriedness > 0: diff --git a/adf_core_python/implement/module/complex/default_police_target_allocator.py b/adf_core_python/implement/module/complex/default_police_target_allocator.py index 0de8b3f..9499ebb 100644 --- a/adf_core_python/implement/module/complex/default_police_target_allocator.py +++ b/adf_core_python/implement/module/complex/default_police_target_allocator.py @@ -108,13 +108,13 @@ def calculate(self) -> PoliceTargetAllocator: agents = sorted( agents, key=cmp_to_key(self._compare_by_distance(target_entity)) ) - result = agents.pop(0) - info = self._agent_info_map[result.get_entity_id()] + selected_agent = agents.pop(0) + info = self._agent_info_map[selected_agent.get_entity_id()] if info is not None: info._can_new_action = False info._target = target info.command_time = current_time - self._agent_info_map[result.get_entity_id()] = info + self._agent_info_map[selected_agent.get_entity_id()] = info removes.append(target) for r in removes: @@ -129,12 +129,12 @@ def calculate(self) -> PoliceTargetAllocator: for agent in agents: if len(areas) > 0: areas.sort(key=cmp_to_key(self._compare_by_distance(agent))) - result = areas.pop(0) - self._target_areas.remove(result.get_entity_id()) + target_area: Entity = areas.pop(0) + self._target_areas.remove(target_area.get_entity_id()) info = self._agent_info_map[agent.get_entity_id()] if info is not None: info._can_new_action = False - info._target = result.get_entity_id() + info._target = target_area.get_entity_id() info.command_time = current_time self._agent_info_map[agent.get_entity_id()] = info @@ -148,9 +148,10 @@ def _get_action_agents( ) -> list[PoliceForce]: result = [] for entity in self._world_info.get_entities_of_types([PoliceForce]): - info = info_map[entity.get_entity_id()] - if info is not None and info._can_new_action: - result.append(entity) + if isinstance(entity, PoliceForce): + info = info_map[entity.get_entity_id()] + if info is not None and info._can_new_action: + result.append(entity) return result def _compare_by_distance( 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 ad837a4..ed7a02d 100644 --- a/adf_core_python/implement/module/complex/default_road_detector.py +++ b/adf_core_python/implement/module/complex/default_road_detector.py @@ -37,7 +37,7 @@ def __init__( ) self.register_sub_module(self._path_planning) - self._result = None + self._result: Optional[EntityID] = None def precompute(self, precompute_data: PrecomputeData) -> RoadDetector: super().precompute(precompute_data) @@ -108,7 +108,7 @@ def update_info(self, message_manager: MessageManager) -> RoadDetector: if isinstance(entity, Building): self._result = None elif isinstance(entity, Road): - road: Road = cast(Road, entity) + road = entity if road.get_blockades() == []: self._target_areas.remove(self._result) self._result = None @@ -117,7 +117,9 @@ def update_info(self, message_manager: MessageManager) -> RoadDetector: def calculate(self) -> RoadDetector: if self._result is None: - position_entity_id: EntityID = self._agent_info.get_position_entity_id() + position_entity_id = self._agent_info.get_position_entity_id() + if position_entity_id is None: + return self if position_entity_id in self._target_areas: self._result = position_entity_id return self @@ -128,21 +130,22 @@ def calculate(self) -> RoadDetector: self._priority_roads = self._priority_roads - set(remove_list) if len(self._priority_roads) > 0: - _nearest_target_area = self._agent_info.get_position_entity_id() + agent_position = self._agent_info.get_position_entity_id() + if agent_position is None: + return self + _nearest_target_area = agent_position _nearest_distance = float("inf") for target_area in self._target_areas: if ( - self._world_info.get_distance( - self._agent_info.get_position_entity_id(), target_area - ) + self._world_info.get_distance(agent_position, target_area) < _nearest_distance ): _nearest_target_area = target_area _nearest_distance = self._world_info.get_distance( - self._agent_info.get_position_entity_id(), target_area + agent_position, target_area ) path: list[EntityID] = self._path_planning.get_path( - self._agent_info.get_position_entity_id(), _nearest_target_area + agent_position, _nearest_target_area ) if path is not None and len(path) > 0: self._result = path[-1] diff --git a/adf_core_python/implement/module/complex/default_search.py b/adf_core_python/implement/module/complex/default_search.py index 0d5c714..1050029 100644 --- a/adf_core_python/implement/module/complex/default_search.py +++ b/adf_core_python/implement/module/complex/default_search.py @@ -64,7 +64,8 @@ def update_info(self, message_manager: MessageManager) -> Search: ) searched_building_id = self._agent_info.get_position_entity_id() - self._unreached_building_ids.discard(searched_building_id) + if searched_building_id is not None: + self._unreached_building_ids.discard(searched_building_id) if len(self._unreached_building_ids) == 0: self._unreached_building_ids = self._get_search_targets() From 44d72c52ffc62006d414411f74a4d67fac7be99d Mon Sep 17 00:00:00 2001 From: shima004 Date: Mon, 4 Aug 2025 15:05:48 +0900 Subject: [PATCH 03/13] move: add src file --- .../core/agent/precompute/precompute_data.py | 75 ------------------- adf_core_python/implement/tactics/__init__.py | 0 .../adf_core_python}/__init__.py | 0 .../adf_core_python}/cli/__init__.py | 0 .../adf_core_python}/cli/cli.py | 0 .../cli/template/config/development.json | 0 .../cli/template/config/launcher.yaml | 0 .../cli/template/config/module.yaml | 0 .../adf_core_python}/cli/template/main.py | 0 .../cli/template/src/team_name/__init__.py | 0 .../template/src/team_name/module/__init__.py | 0 .../src/team_name/module/complex/__init__.py | 0 .../module/complex/sample_human_detector.py | 0 .../module/complex/sample_road_detector.py | 0 .../team_name/module/complex/sample_search.py | 0 .../adf_core_python}/core/__init__.py | 0 .../adf_core_python}/core/agent/__init__.py | 0 .../core/agent/action/__init__.py | 0 .../core/agent/action/action.py | 0 .../core/agent/action/ambulance/__init__.py | 0 .../agent/action/ambulance/action_load.py | 0 .../agent/action/ambulance/action_rescue.py | 0 .../agent/action/ambulance/action_unload.py | 0 .../core/agent/action/common/__init__.py | 0 .../core/agent/action/common/action_move.py | 0 .../core/agent/action/common/action_rest.py | 0 .../core/agent/action/fire/__init__.py | 0 .../agent/action/fire/action_extinguish.py | 0 .../core/agent/action/fire/action_refill.py | 0 .../core/agent/action/fire/action_rescue.py | 0 .../core/agent/action/police/__init__.py | 0 .../core/agent/action/police/action_clear.py | 0 .../agent/action/police/action_clear_area.py | 0 .../adf_core_python}/core/agent/agent.py | 0 .../core/agent/communication/__init__.py | 0 .../agent/communication/message_manager.py | 0 .../agent/communication/standard/__init__.py | 0 .../communication/standard/bundle/__init__.py | 0 .../standard/bundle/centralized/__init__.py | 0 .../bundle/centralized/command_ambulance.py | 0 .../bundle/centralized/command_fire.py | 0 .../bundle/centralized/command_police.py | 0 .../bundle/centralized/command_scout.py | 0 .../bundle/centralized/message_report.py | 0 .../standard/bundle/information/__init__.py | 0 .../information/message_ambulance_team.py | 0 .../bundle/information/message_building.py | 0 .../bundle/information/message_civilian.py | 0 .../information/message_fire_brigade.py | 0 .../information/message_police_force.py | 0 .../bundle/information/message_road.py | 0 .../standard/bundle/standard_message.py | 0 .../bundle/standard_message_priority.py | 0 .../standard/standard_communication_module.py | 0 .../standard/utility/__init__.py | 0 .../standard/utility/apply_to_world_info.py | 0 .../utility/bitarray_with_exits_flag.py | 0 .../core/agent/config/__init__.py | 0 .../core/agent/config/module_config.py | 0 .../core/agent/develop/__init__.py | 0 .../core/agent/develop/develop_data.py | 0 .../core/agent/info/__init__.py | 0 .../core/agent/info/agent_info.py | 0 .../core/agent/info/scenario_info.py | 0 .../core/agent/info/world_info.py | 0 .../core/agent/module/__init__.py | 0 .../core/agent/module/module_manager.py | 0 .../core/agent/office/office.py | 0 .../core/agent/office/office_ambulance.py | 0 .../core/agent/office/office_fire.py | 0 .../core/agent/office/office_police.py | 0 .../core/agent/platoon/__init__.py | 0 .../core/agent/platoon/platoon.py | 0 .../core/agent/platoon/platoon_ambulance.py | 0 .../core/agent/platoon/platoon_fire.py | 0 .../core/agent/platoon/platoon_police.py | 0 .../core/component}/__init__.py | 0 .../core/component/abstract_loader.py | 0 .../core/component/action}/__init__.py | 0 .../core/component/action/extend_action.py | 0 .../component/centralized/command_executor.py | 0 .../component/centralized/command_picker.py | 0 .../core/component/communication}/__init__.py | 0 .../communication/channel_subscriber.py | 0 .../communication/communication_message.py | 0 .../communication/communication_module.py | 0 .../communication/message_coordinator.py | 0 .../core/component/module}/__init__.py | 0 .../core/component/module/abstract_module.py | 0 .../component/module/algorithm}/__init__.py | 0 .../component/module/algorithm/clustering.py | 0 .../module/algorithm/path_planning.py | 0 .../component/module/complex}/__init__.py | 0 .../complex/ambulance_target_allocator.py | 0 .../module/complex/fire_target_allocator.py | 0 .../module/complex/human_detector.py | 0 .../module/complex/police_target_allocator.py | 0 .../component/module/complex/road_detector.py | 0 .../core/component/module/complex/search.py | 0 .../module/complex/target_allocator.py | 0 .../module/complex/target_detector.py | 0 .../core/component/tactics}/__init__.py | 0 .../core/component/tactics/tactics_agent.py | 0 .../tactics/tactics_ambulance_center.py | 0 .../tactics/tactics_ambulance_team.py | 0 .../core/component/tactics/tactics_center.py | 0 .../component/tactics/tactics_fire_brigade.py | 0 .../component/tactics/tactics_fire_station.py | 0 .../component/tactics/tactics_police_force.py | 0 .../tactics/tactics_police_office.py | 0 .../adf_core_python/core/config}/__init__.py | 0 .../adf_core_python}/core/config/config.py | 0 .../adf_core_python/core/gateway}/__init__.py | 0 .../core/gateway/component}/__init__.py | 0 .../gateway/component/module}/__init__.py | 0 .../component/module/algorithm}/__init__.py | 0 .../module/algorithm/gateway_clustering.py | 0 .../module/algorithm/gateway_path_planning.py | 0 .../component/module/complex}/__init__.py | 0 .../gateway_ambulance_target_allocator.py | 0 .../complex/gateway_fire_target_allocator.py | 0 .../module/complex/gateway_human_detector.py | 0 .../gateway_police_target_allocator.py | 0 .../module/complex/gateway_road_detector.py | 0 .../module/complex/gateway_search.py | 0 .../complex/gateway_target_allocator.py | 0 .../module/complex/gateway_target_detector.py | 0 .../module/gateway_abstract_module.py | 0 .../core/gateway/gateway_agent.py | 0 .../core/gateway/gateway_launcher.py | 0 .../core/gateway/gateway_module.py | 0 .../core/gateway/message}/__init__.py | 0 .../core/gateway/message/am_agent.py | 0 .../core/gateway/message/am_exec.py | 0 .../core/gateway/message/am_module.py | 0 .../core/gateway/message/am_update.py | 0 .../core/gateway/message/ma_exec_response.py | 0 .../gateway/message/ma_module_response.py | 0 .../gateway/message/moduleMessageFactory.py | 0 .../core/gateway/message/urn}/__init__.py | 0 .../core/gateway/message/urn/urn.py | 0 .../core/gateway/module_dict.py | 0 .../core/launcher}/__init__.py | 0 .../core/launcher/agent_launcher.py | 0 .../core/launcher/config_key.py | 0 .../core/launcher/connect}/__init__.py | 0 .../launcher/connect/component_launcher.py | 0 .../core/launcher/connect/connection.py | 0 .../core/launcher/connect/connector.py | 0 .../connect/connector_ambulance_center.py | 0 .../connect/connector_ambulance_team.py | 0 .../connect/connector_fire_brigade.py | 0 .../connect/connector_fire_station.py | 0 .../connect/connector_police_force.py | 0 .../connect/connector_police_office.py | 0 .../launcher/connect/error/agent_error.py | 0 .../launcher/connect/error/server_error.py | 0 .../adf_core_python/core/logger}/__init__.py | 0 .../adf_core_python}/core/logger/logger.py | 0 .../adf_core_python/implement}/__init__.py | 0 .../implement/action}/__init__.py | 0 .../action/default_extend_action_clear.py | 0 .../action/default_extend_action_move.py | 0 .../action/default_extend_action_rescue.py | 0 .../action/default_extend_action_transport.py | 0 .../default_command_executor_ambulance.py | 0 .../default_command_executor_fire.py | 0 .../default_command_executor_police.py | 0 .../default_command_executor_scout.py | 0 .../default_command_executor_scout_police.py | 0 .../default_command_picker_ambulance.py | 0 .../default_command_picker_fire.py | 0 .../default_command_picker_police.py | 0 .../implement/default_loader.py | 0 .../implement/module}/__init__.py | 0 .../implement/module/algorithm}/__init__.py | 0 .../module/algorithm/a_star_path_planning.py | 0 .../algorithm/dijkstra_path_planning.py | 0 .../module/algorithm/k_means_clustering.py | 0 .../module/communication}/__init__.py | 0 .../default_channel_subscriber.py | 0 .../default_message_coordinator.py | 0 .../implement/module/complex}/__init__.py | 0 .../default_ambulance_target_allocator.py | 0 .../complex/default_fire_target_allocator.py | 0 .../module/complex/default_human_detector.py | 0 .../default_police_target_allocator.py | 0 .../module/complex/default_road_detector.py | 0 .../module/complex/default_search.py | 0 .../implement/tactics}/__init__.py | 0 .../default_tactics_ambulance_center.py | 0 .../tactics/default_tactics_ambulance_team.py | 0 .../tactics/default_tactics_fire_brigade.py | 0 .../tactics/default_tactics_fire_station.py | 0 .../tactics/default_tactics_police_force.py | 0 .../tactics/default_tactics_police_office.py | 0 .../adf_core_python}/launcher.py | 0 197 files changed, 75 deletions(-) delete mode 100644 adf_core_python/core/agent/precompute/precompute_data.py delete mode 100644 adf_core_python/implement/tactics/__init__.py rename {adf_core_python => src/adf_core_python}/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/cli/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/cli/cli.py (100%) rename {adf_core_python => src/adf_core_python}/cli/template/config/development.json (100%) rename {adf_core_python => src/adf_core_python}/cli/template/config/launcher.yaml (100%) rename {adf_core_python => src/adf_core_python}/cli/template/config/module.yaml (100%) rename {adf_core_python => src/adf_core_python}/cli/template/main.py (100%) rename {adf_core_python => src/adf_core_python}/cli/template/src/team_name/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/cli/template/src/team_name/module/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/cli/template/src/team_name/module/complex/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/cli/template/src/team_name/module/complex/sample_human_detector.py (100%) rename {adf_core_python => src/adf_core_python}/cli/template/src/team_name/module/complex/sample_road_detector.py (100%) rename {adf_core_python => src/adf_core_python}/cli/template/src/team_name/module/complex/sample_search.py (100%) rename {adf_core_python => src/adf_core_python}/core/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/action/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/action/action.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/action/ambulance/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/action/ambulance/action_load.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/action/ambulance/action_rescue.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/action/ambulance/action_unload.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/action/common/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/action/common/action_move.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/action/common/action_rest.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/action/fire/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/action/fire/action_extinguish.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/action/fire/action_refill.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/action/fire/action_rescue.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/action/police/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/action/police/action_clear.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/action/police/action_clear_area.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/agent.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/communication/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/communication/message_manager.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/communication/standard/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/communication/standard/bundle/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/communication/standard/bundle/centralized/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/communication/standard/bundle/centralized/command_ambulance.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/communication/standard/bundle/centralized/command_fire.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/communication/standard/bundle/centralized/command_police.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/communication/standard/bundle/centralized/command_scout.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/communication/standard/bundle/centralized/message_report.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/communication/standard/bundle/information/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/communication/standard/bundle/information/message_ambulance_team.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/communication/standard/bundle/information/message_building.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/communication/standard/bundle/information/message_civilian.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/communication/standard/bundle/information/message_fire_brigade.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/communication/standard/bundle/information/message_police_force.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/communication/standard/bundle/information/message_road.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/communication/standard/bundle/standard_message.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/communication/standard/bundle/standard_message_priority.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/communication/standard/standard_communication_module.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/communication/standard/utility/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/communication/standard/utility/apply_to_world_info.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/communication/standard/utility/bitarray_with_exits_flag.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/config/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/config/module_config.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/develop/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/develop/develop_data.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/info/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/info/agent_info.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/info/scenario_info.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/info/world_info.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/module/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/module/module_manager.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/office/office.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/office/office_ambulance.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/office/office_fire.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/office/office_police.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/platoon/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/platoon/platoon.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/platoon/platoon_ambulance.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/platoon/platoon_fire.py (100%) rename {adf_core_python => src/adf_core_python}/core/agent/platoon/platoon_police.py (100%) rename {adf_core_python/core/agent/precompute => src/adf_core_python/core/component}/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/abstract_loader.py (100%) rename {adf_core_python/core/component => src/adf_core_python/core/component/action}/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/action/extend_action.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/centralized/command_executor.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/centralized/command_picker.py (100%) rename {adf_core_python/core/component/action => src/adf_core_python/core/component/communication}/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/communication/channel_subscriber.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/communication/communication_message.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/communication/communication_module.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/communication/message_coordinator.py (100%) rename {adf_core_python/core/component/communication => src/adf_core_python/core/component/module}/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/module/abstract_module.py (100%) rename {adf_core_python/core/component/module => src/adf_core_python/core/component/module/algorithm}/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/module/algorithm/clustering.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/module/algorithm/path_planning.py (100%) rename {adf_core_python/core/component/module/algorithm => src/adf_core_python/core/component/module/complex}/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/module/complex/ambulance_target_allocator.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/module/complex/fire_target_allocator.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/module/complex/human_detector.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/module/complex/police_target_allocator.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/module/complex/road_detector.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/module/complex/search.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/module/complex/target_allocator.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/module/complex/target_detector.py (100%) rename {adf_core_python/core/component/module/complex => src/adf_core_python/core/component/tactics}/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/tactics/tactics_agent.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/tactics/tactics_ambulance_center.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/tactics/tactics_ambulance_team.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/tactics/tactics_center.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/tactics/tactics_fire_brigade.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/tactics/tactics_fire_station.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/tactics/tactics_police_force.py (100%) rename {adf_core_python => src/adf_core_python}/core/component/tactics/tactics_police_office.py (100%) rename {adf_core_python/core/component/tactics => src/adf_core_python/core/config}/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/config/config.py (100%) rename {adf_core_python/core/config => src/adf_core_python/core/gateway}/__init__.py (100%) rename {adf_core_python/core/gateway => src/adf_core_python/core/gateway/component}/__init__.py (100%) rename {adf_core_python/core/gateway/component => src/adf_core_python/core/gateway/component/module}/__init__.py (100%) rename {adf_core_python/core/gateway/component/module => src/adf_core_python/core/gateway/component/module/algorithm}/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/gateway/component/module/algorithm/gateway_clustering.py (100%) rename {adf_core_python => src/adf_core_python}/core/gateway/component/module/algorithm/gateway_path_planning.py (100%) rename {adf_core_python/core/gateway/component/module/algorithm => src/adf_core_python/core/gateway/component/module/complex}/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/gateway/component/module/complex/gateway_ambulance_target_allocator.py (100%) rename {adf_core_python => src/adf_core_python}/core/gateway/component/module/complex/gateway_fire_target_allocator.py (100%) rename {adf_core_python => src/adf_core_python}/core/gateway/component/module/complex/gateway_human_detector.py (100%) rename {adf_core_python => src/adf_core_python}/core/gateway/component/module/complex/gateway_police_target_allocator.py (100%) rename {adf_core_python => src/adf_core_python}/core/gateway/component/module/complex/gateway_road_detector.py (100%) rename {adf_core_python => src/adf_core_python}/core/gateway/component/module/complex/gateway_search.py (100%) rename {adf_core_python => src/adf_core_python}/core/gateway/component/module/complex/gateway_target_allocator.py (100%) rename {adf_core_python => src/adf_core_python}/core/gateway/component/module/complex/gateway_target_detector.py (100%) rename {adf_core_python => src/adf_core_python}/core/gateway/component/module/gateway_abstract_module.py (100%) rename {adf_core_python => src/adf_core_python}/core/gateway/gateway_agent.py (100%) rename {adf_core_python => src/adf_core_python}/core/gateway/gateway_launcher.py (100%) rename {adf_core_python => src/adf_core_python}/core/gateway/gateway_module.py (100%) rename {adf_core_python/core/gateway/component/module/complex => src/adf_core_python/core/gateway/message}/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/gateway/message/am_agent.py (100%) rename {adf_core_python => src/adf_core_python}/core/gateway/message/am_exec.py (100%) rename {adf_core_python => src/adf_core_python}/core/gateway/message/am_module.py (100%) rename {adf_core_python => src/adf_core_python}/core/gateway/message/am_update.py (100%) rename {adf_core_python => src/adf_core_python}/core/gateway/message/ma_exec_response.py (100%) rename {adf_core_python => src/adf_core_python}/core/gateway/message/ma_module_response.py (100%) rename {adf_core_python => src/adf_core_python}/core/gateway/message/moduleMessageFactory.py (100%) rename {adf_core_python/core/gateway/message => src/adf_core_python/core/gateway/message/urn}/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/gateway/message/urn/urn.py (100%) rename {adf_core_python => src/adf_core_python}/core/gateway/module_dict.py (100%) rename {adf_core_python/core/gateway/message/urn => src/adf_core_python/core/launcher}/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/launcher/agent_launcher.py (100%) rename {adf_core_python => src/adf_core_python}/core/launcher/config_key.py (100%) rename {adf_core_python/core/launcher => src/adf_core_python/core/launcher/connect}/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/launcher/connect/component_launcher.py (100%) rename {adf_core_python => src/adf_core_python}/core/launcher/connect/connection.py (100%) rename {adf_core_python => src/adf_core_python}/core/launcher/connect/connector.py (100%) rename {adf_core_python => src/adf_core_python}/core/launcher/connect/connector_ambulance_center.py (100%) rename {adf_core_python => src/adf_core_python}/core/launcher/connect/connector_ambulance_team.py (100%) rename {adf_core_python => src/adf_core_python}/core/launcher/connect/connector_fire_brigade.py (100%) rename {adf_core_python => src/adf_core_python}/core/launcher/connect/connector_fire_station.py (100%) rename {adf_core_python => src/adf_core_python}/core/launcher/connect/connector_police_force.py (100%) rename {adf_core_python => src/adf_core_python}/core/launcher/connect/connector_police_office.py (100%) rename {adf_core_python => src/adf_core_python}/core/launcher/connect/error/agent_error.py (100%) rename {adf_core_python => src/adf_core_python}/core/launcher/connect/error/server_error.py (100%) rename {adf_core_python/core/launcher/connect => src/adf_core_python/core/logger}/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/core/logger/logger.py (100%) rename {adf_core_python/core/logger => src/adf_core_python/implement}/__init__.py (100%) rename {adf_core_python/implement => src/adf_core_python/implement/action}/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/implement/action/default_extend_action_clear.py (100%) rename {adf_core_python => src/adf_core_python}/implement/action/default_extend_action_move.py (100%) rename {adf_core_python => src/adf_core_python}/implement/action/default_extend_action_rescue.py (100%) rename {adf_core_python => src/adf_core_python}/implement/action/default_extend_action_transport.py (100%) rename {adf_core_python => src/adf_core_python}/implement/centralized/default_command_executor_ambulance.py (100%) rename {adf_core_python => src/adf_core_python}/implement/centralized/default_command_executor_fire.py (100%) rename {adf_core_python => src/adf_core_python}/implement/centralized/default_command_executor_police.py (100%) rename {adf_core_python => src/adf_core_python}/implement/centralized/default_command_executor_scout.py (100%) rename {adf_core_python => src/adf_core_python}/implement/centralized/default_command_executor_scout_police.py (100%) rename {adf_core_python => src/adf_core_python}/implement/centralized/default_command_picker_ambulance.py (100%) rename {adf_core_python => src/adf_core_python}/implement/centralized/default_command_picker_fire.py (100%) rename {adf_core_python => src/adf_core_python}/implement/centralized/default_command_picker_police.py (100%) rename {adf_core_python => src/adf_core_python}/implement/default_loader.py (100%) rename {adf_core_python/implement/action => src/adf_core_python/implement/module}/__init__.py (100%) rename {adf_core_python/implement/module => src/adf_core_python/implement/module/algorithm}/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/implement/module/algorithm/a_star_path_planning.py (100%) rename {adf_core_python => src/adf_core_python}/implement/module/algorithm/dijkstra_path_planning.py (100%) rename {adf_core_python => src/adf_core_python}/implement/module/algorithm/k_means_clustering.py (100%) rename {adf_core_python/implement/module/algorithm => src/adf_core_python/implement/module/communication}/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/implement/module/communication/default_channel_subscriber.py (100%) rename {adf_core_python => src/adf_core_python}/implement/module/communication/default_message_coordinator.py (100%) rename {adf_core_python/implement/module/communication => src/adf_core_python/implement/module/complex}/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/implement/module/complex/default_ambulance_target_allocator.py (100%) rename {adf_core_python => src/adf_core_python}/implement/module/complex/default_fire_target_allocator.py (100%) rename {adf_core_python => src/adf_core_python}/implement/module/complex/default_human_detector.py (100%) rename {adf_core_python => src/adf_core_python}/implement/module/complex/default_police_target_allocator.py (100%) rename {adf_core_python => src/adf_core_python}/implement/module/complex/default_road_detector.py (100%) rename {adf_core_python => src/adf_core_python}/implement/module/complex/default_search.py (100%) rename {adf_core_python/implement/module/complex => src/adf_core_python/implement/tactics}/__init__.py (100%) rename {adf_core_python => src/adf_core_python}/implement/tactics/default_tactics_ambulance_center.py (100%) rename {adf_core_python => src/adf_core_python}/implement/tactics/default_tactics_ambulance_team.py (100%) rename {adf_core_python => src/adf_core_python}/implement/tactics/default_tactics_fire_brigade.py (100%) rename {adf_core_python => src/adf_core_python}/implement/tactics/default_tactics_fire_station.py (100%) rename {adf_core_python => src/adf_core_python}/implement/tactics/default_tactics_police_force.py (100%) rename {adf_core_python => src/adf_core_python}/implement/tactics/default_tactics_police_office.py (100%) rename {adf_core_python => src/adf_core_python}/launcher.py (100%) diff --git a/adf_core_python/core/agent/precompute/precompute_data.py b/adf_core_python/core/agent/precompute/precompute_data.py deleted file mode 100644 index 41b2029..0000000 --- a/adf_core_python/core/agent/precompute/precompute_data.py +++ /dev/null @@ -1,75 +0,0 @@ -import json -import os - -ENCODE = "utf-8" - - -class PrecomputeData: - 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/implement/tactics/__init__.py b/adf_core_python/implement/tactics/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/adf_core_python/__init__.py b/src/adf_core_python/__init__.py similarity index 100% rename from adf_core_python/__init__.py rename to src/adf_core_python/__init__.py diff --git a/adf_core_python/cli/__init__.py b/src/adf_core_python/cli/__init__.py similarity index 100% rename from adf_core_python/cli/__init__.py rename to src/adf_core_python/cli/__init__.py diff --git a/adf_core_python/cli/cli.py b/src/adf_core_python/cli/cli.py similarity index 100% rename from adf_core_python/cli/cli.py rename to src/adf_core_python/cli/cli.py diff --git a/adf_core_python/cli/template/config/development.json b/src/adf_core_python/cli/template/config/development.json similarity index 100% rename from adf_core_python/cli/template/config/development.json rename to src/adf_core_python/cli/template/config/development.json diff --git a/adf_core_python/cli/template/config/launcher.yaml b/src/adf_core_python/cli/template/config/launcher.yaml similarity index 100% rename from adf_core_python/cli/template/config/launcher.yaml rename to src/adf_core_python/cli/template/config/launcher.yaml diff --git a/adf_core_python/cli/template/config/module.yaml b/src/adf_core_python/cli/template/config/module.yaml similarity index 100% rename from adf_core_python/cli/template/config/module.yaml rename to src/adf_core_python/cli/template/config/module.yaml diff --git a/adf_core_python/cli/template/main.py b/src/adf_core_python/cli/template/main.py similarity index 100% rename from adf_core_python/cli/template/main.py rename to src/adf_core_python/cli/template/main.py diff --git a/adf_core_python/cli/template/src/team_name/__init__.py b/src/adf_core_python/cli/template/src/team_name/__init__.py similarity index 100% rename from adf_core_python/cli/template/src/team_name/__init__.py rename to src/adf_core_python/cli/template/src/team_name/__init__.py diff --git a/adf_core_python/cli/template/src/team_name/module/__init__.py b/src/adf_core_python/cli/template/src/team_name/module/__init__.py similarity index 100% rename from adf_core_python/cli/template/src/team_name/module/__init__.py rename to src/adf_core_python/cli/template/src/team_name/module/__init__.py diff --git a/adf_core_python/cli/template/src/team_name/module/complex/__init__.py b/src/adf_core_python/cli/template/src/team_name/module/complex/__init__.py similarity index 100% rename from adf_core_python/cli/template/src/team_name/module/complex/__init__.py rename to src/adf_core_python/cli/template/src/team_name/module/complex/__init__.py diff --git a/adf_core_python/cli/template/src/team_name/module/complex/sample_human_detector.py b/src/adf_core_python/cli/template/src/team_name/module/complex/sample_human_detector.py similarity index 100% rename from adf_core_python/cli/template/src/team_name/module/complex/sample_human_detector.py rename to src/adf_core_python/cli/template/src/team_name/module/complex/sample_human_detector.py diff --git a/adf_core_python/cli/template/src/team_name/module/complex/sample_road_detector.py b/src/adf_core_python/cli/template/src/team_name/module/complex/sample_road_detector.py similarity index 100% rename from adf_core_python/cli/template/src/team_name/module/complex/sample_road_detector.py rename to src/adf_core_python/cli/template/src/team_name/module/complex/sample_road_detector.py diff --git a/adf_core_python/cli/template/src/team_name/module/complex/sample_search.py b/src/adf_core_python/cli/template/src/team_name/module/complex/sample_search.py similarity index 100% rename from adf_core_python/cli/template/src/team_name/module/complex/sample_search.py rename to src/adf_core_python/cli/template/src/team_name/module/complex/sample_search.py diff --git a/adf_core_python/core/__init__.py b/src/adf_core_python/core/__init__.py similarity index 100% rename from adf_core_python/core/__init__.py rename to src/adf_core_python/core/__init__.py diff --git a/adf_core_python/core/agent/__init__.py b/src/adf_core_python/core/agent/__init__.py similarity index 100% rename from adf_core_python/core/agent/__init__.py rename to src/adf_core_python/core/agent/__init__.py diff --git a/adf_core_python/core/agent/action/__init__.py b/src/adf_core_python/core/agent/action/__init__.py similarity index 100% rename from adf_core_python/core/agent/action/__init__.py rename to src/adf_core_python/core/agent/action/__init__.py diff --git a/adf_core_python/core/agent/action/action.py b/src/adf_core_python/core/agent/action/action.py similarity index 100% rename from adf_core_python/core/agent/action/action.py rename to src/adf_core_python/core/agent/action/action.py diff --git a/adf_core_python/core/agent/action/ambulance/__init__.py b/src/adf_core_python/core/agent/action/ambulance/__init__.py similarity index 100% rename from adf_core_python/core/agent/action/ambulance/__init__.py rename to src/adf_core_python/core/agent/action/ambulance/__init__.py diff --git a/adf_core_python/core/agent/action/ambulance/action_load.py b/src/adf_core_python/core/agent/action/ambulance/action_load.py similarity index 100% rename from adf_core_python/core/agent/action/ambulance/action_load.py rename to src/adf_core_python/core/agent/action/ambulance/action_load.py diff --git a/adf_core_python/core/agent/action/ambulance/action_rescue.py b/src/adf_core_python/core/agent/action/ambulance/action_rescue.py similarity index 100% rename from adf_core_python/core/agent/action/ambulance/action_rescue.py rename to src/adf_core_python/core/agent/action/ambulance/action_rescue.py diff --git a/adf_core_python/core/agent/action/ambulance/action_unload.py b/src/adf_core_python/core/agent/action/ambulance/action_unload.py similarity index 100% rename from adf_core_python/core/agent/action/ambulance/action_unload.py rename to src/adf_core_python/core/agent/action/ambulance/action_unload.py diff --git a/adf_core_python/core/agent/action/common/__init__.py b/src/adf_core_python/core/agent/action/common/__init__.py similarity index 100% rename from adf_core_python/core/agent/action/common/__init__.py rename to src/adf_core_python/core/agent/action/common/__init__.py diff --git a/adf_core_python/core/agent/action/common/action_move.py b/src/adf_core_python/core/agent/action/common/action_move.py similarity index 100% rename from adf_core_python/core/agent/action/common/action_move.py rename to src/adf_core_python/core/agent/action/common/action_move.py diff --git a/adf_core_python/core/agent/action/common/action_rest.py b/src/adf_core_python/core/agent/action/common/action_rest.py similarity index 100% rename from adf_core_python/core/agent/action/common/action_rest.py rename to src/adf_core_python/core/agent/action/common/action_rest.py diff --git a/adf_core_python/core/agent/action/fire/__init__.py b/src/adf_core_python/core/agent/action/fire/__init__.py similarity index 100% rename from adf_core_python/core/agent/action/fire/__init__.py rename to src/adf_core_python/core/agent/action/fire/__init__.py diff --git a/adf_core_python/core/agent/action/fire/action_extinguish.py b/src/adf_core_python/core/agent/action/fire/action_extinguish.py similarity index 100% rename from adf_core_python/core/agent/action/fire/action_extinguish.py rename to src/adf_core_python/core/agent/action/fire/action_extinguish.py diff --git a/adf_core_python/core/agent/action/fire/action_refill.py b/src/adf_core_python/core/agent/action/fire/action_refill.py similarity index 100% rename from adf_core_python/core/agent/action/fire/action_refill.py rename to src/adf_core_python/core/agent/action/fire/action_refill.py diff --git a/adf_core_python/core/agent/action/fire/action_rescue.py b/src/adf_core_python/core/agent/action/fire/action_rescue.py similarity index 100% rename from adf_core_python/core/agent/action/fire/action_rescue.py rename to src/adf_core_python/core/agent/action/fire/action_rescue.py diff --git a/adf_core_python/core/agent/action/police/__init__.py b/src/adf_core_python/core/agent/action/police/__init__.py similarity index 100% rename from adf_core_python/core/agent/action/police/__init__.py rename to src/adf_core_python/core/agent/action/police/__init__.py diff --git a/adf_core_python/core/agent/action/police/action_clear.py b/src/adf_core_python/core/agent/action/police/action_clear.py similarity index 100% rename from adf_core_python/core/agent/action/police/action_clear.py rename to src/adf_core_python/core/agent/action/police/action_clear.py diff --git a/adf_core_python/core/agent/action/police/action_clear_area.py b/src/adf_core_python/core/agent/action/police/action_clear_area.py similarity index 100% rename from adf_core_python/core/agent/action/police/action_clear_area.py rename to src/adf_core_python/core/agent/action/police/action_clear_area.py diff --git a/adf_core_python/core/agent/agent.py b/src/adf_core_python/core/agent/agent.py similarity index 100% rename from adf_core_python/core/agent/agent.py rename to src/adf_core_python/core/agent/agent.py diff --git a/adf_core_python/core/agent/communication/__init__.py b/src/adf_core_python/core/agent/communication/__init__.py similarity index 100% rename from adf_core_python/core/agent/communication/__init__.py rename to src/adf_core_python/core/agent/communication/__init__.py diff --git a/adf_core_python/core/agent/communication/message_manager.py b/src/adf_core_python/core/agent/communication/message_manager.py similarity index 100% rename from adf_core_python/core/agent/communication/message_manager.py rename to src/adf_core_python/core/agent/communication/message_manager.py diff --git a/adf_core_python/core/agent/communication/standard/__init__.py b/src/adf_core_python/core/agent/communication/standard/__init__.py similarity index 100% rename from adf_core_python/core/agent/communication/standard/__init__.py rename to src/adf_core_python/core/agent/communication/standard/__init__.py diff --git a/adf_core_python/core/agent/communication/standard/bundle/__init__.py b/src/adf_core_python/core/agent/communication/standard/bundle/__init__.py similarity index 100% rename from adf_core_python/core/agent/communication/standard/bundle/__init__.py rename to src/adf_core_python/core/agent/communication/standard/bundle/__init__.py diff --git a/adf_core_python/core/agent/communication/standard/bundle/centralized/__init__.py b/src/adf_core_python/core/agent/communication/standard/bundle/centralized/__init__.py similarity index 100% rename from adf_core_python/core/agent/communication/standard/bundle/centralized/__init__.py rename to src/adf_core_python/core/agent/communication/standard/bundle/centralized/__init__.py diff --git a/adf_core_python/core/agent/communication/standard/bundle/centralized/command_ambulance.py b/src/adf_core_python/core/agent/communication/standard/bundle/centralized/command_ambulance.py similarity index 100% rename from adf_core_python/core/agent/communication/standard/bundle/centralized/command_ambulance.py rename to src/adf_core_python/core/agent/communication/standard/bundle/centralized/command_ambulance.py diff --git a/adf_core_python/core/agent/communication/standard/bundle/centralized/command_fire.py b/src/adf_core_python/core/agent/communication/standard/bundle/centralized/command_fire.py similarity index 100% rename from adf_core_python/core/agent/communication/standard/bundle/centralized/command_fire.py rename to src/adf_core_python/core/agent/communication/standard/bundle/centralized/command_fire.py diff --git a/adf_core_python/core/agent/communication/standard/bundle/centralized/command_police.py b/src/adf_core_python/core/agent/communication/standard/bundle/centralized/command_police.py similarity index 100% rename from adf_core_python/core/agent/communication/standard/bundle/centralized/command_police.py rename to src/adf_core_python/core/agent/communication/standard/bundle/centralized/command_police.py diff --git a/adf_core_python/core/agent/communication/standard/bundle/centralized/command_scout.py b/src/adf_core_python/core/agent/communication/standard/bundle/centralized/command_scout.py similarity index 100% rename from adf_core_python/core/agent/communication/standard/bundle/centralized/command_scout.py rename to src/adf_core_python/core/agent/communication/standard/bundle/centralized/command_scout.py diff --git a/adf_core_python/core/agent/communication/standard/bundle/centralized/message_report.py b/src/adf_core_python/core/agent/communication/standard/bundle/centralized/message_report.py similarity index 100% rename from adf_core_python/core/agent/communication/standard/bundle/centralized/message_report.py rename to src/adf_core_python/core/agent/communication/standard/bundle/centralized/message_report.py diff --git a/adf_core_python/core/agent/communication/standard/bundle/information/__init__.py b/src/adf_core_python/core/agent/communication/standard/bundle/information/__init__.py similarity index 100% rename from adf_core_python/core/agent/communication/standard/bundle/information/__init__.py rename to src/adf_core_python/core/agent/communication/standard/bundle/information/__init__.py diff --git a/adf_core_python/core/agent/communication/standard/bundle/information/message_ambulance_team.py b/src/adf_core_python/core/agent/communication/standard/bundle/information/message_ambulance_team.py similarity index 100% rename from adf_core_python/core/agent/communication/standard/bundle/information/message_ambulance_team.py rename to src/adf_core_python/core/agent/communication/standard/bundle/information/message_ambulance_team.py diff --git a/adf_core_python/core/agent/communication/standard/bundle/information/message_building.py b/src/adf_core_python/core/agent/communication/standard/bundle/information/message_building.py similarity index 100% rename from adf_core_python/core/agent/communication/standard/bundle/information/message_building.py rename to src/adf_core_python/core/agent/communication/standard/bundle/information/message_building.py diff --git a/adf_core_python/core/agent/communication/standard/bundle/information/message_civilian.py b/src/adf_core_python/core/agent/communication/standard/bundle/information/message_civilian.py similarity index 100% rename from adf_core_python/core/agent/communication/standard/bundle/information/message_civilian.py rename to src/adf_core_python/core/agent/communication/standard/bundle/information/message_civilian.py diff --git a/adf_core_python/core/agent/communication/standard/bundle/information/message_fire_brigade.py b/src/adf_core_python/core/agent/communication/standard/bundle/information/message_fire_brigade.py similarity index 100% rename from adf_core_python/core/agent/communication/standard/bundle/information/message_fire_brigade.py rename to src/adf_core_python/core/agent/communication/standard/bundle/information/message_fire_brigade.py diff --git a/adf_core_python/core/agent/communication/standard/bundle/information/message_police_force.py b/src/adf_core_python/core/agent/communication/standard/bundle/information/message_police_force.py similarity index 100% rename from adf_core_python/core/agent/communication/standard/bundle/information/message_police_force.py rename to src/adf_core_python/core/agent/communication/standard/bundle/information/message_police_force.py diff --git a/adf_core_python/core/agent/communication/standard/bundle/information/message_road.py b/src/adf_core_python/core/agent/communication/standard/bundle/information/message_road.py similarity index 100% rename from adf_core_python/core/agent/communication/standard/bundle/information/message_road.py rename to src/adf_core_python/core/agent/communication/standard/bundle/information/message_road.py diff --git a/adf_core_python/core/agent/communication/standard/bundle/standard_message.py b/src/adf_core_python/core/agent/communication/standard/bundle/standard_message.py similarity index 100% rename from adf_core_python/core/agent/communication/standard/bundle/standard_message.py rename to src/adf_core_python/core/agent/communication/standard/bundle/standard_message.py diff --git a/adf_core_python/core/agent/communication/standard/bundle/standard_message_priority.py b/src/adf_core_python/core/agent/communication/standard/bundle/standard_message_priority.py similarity index 100% rename from adf_core_python/core/agent/communication/standard/bundle/standard_message_priority.py rename to src/adf_core_python/core/agent/communication/standard/bundle/standard_message_priority.py diff --git a/adf_core_python/core/agent/communication/standard/standard_communication_module.py b/src/adf_core_python/core/agent/communication/standard/standard_communication_module.py similarity index 100% rename from adf_core_python/core/agent/communication/standard/standard_communication_module.py rename to src/adf_core_python/core/agent/communication/standard/standard_communication_module.py diff --git a/adf_core_python/core/agent/communication/standard/utility/__init__.py b/src/adf_core_python/core/agent/communication/standard/utility/__init__.py similarity index 100% rename from adf_core_python/core/agent/communication/standard/utility/__init__.py rename to src/adf_core_python/core/agent/communication/standard/utility/__init__.py diff --git a/adf_core_python/core/agent/communication/standard/utility/apply_to_world_info.py b/src/adf_core_python/core/agent/communication/standard/utility/apply_to_world_info.py similarity index 100% rename from adf_core_python/core/agent/communication/standard/utility/apply_to_world_info.py rename to src/adf_core_python/core/agent/communication/standard/utility/apply_to_world_info.py diff --git a/adf_core_python/core/agent/communication/standard/utility/bitarray_with_exits_flag.py b/src/adf_core_python/core/agent/communication/standard/utility/bitarray_with_exits_flag.py similarity index 100% rename from adf_core_python/core/agent/communication/standard/utility/bitarray_with_exits_flag.py rename to src/adf_core_python/core/agent/communication/standard/utility/bitarray_with_exits_flag.py diff --git a/adf_core_python/core/agent/config/__init__.py b/src/adf_core_python/core/agent/config/__init__.py similarity index 100% rename from adf_core_python/core/agent/config/__init__.py rename to src/adf_core_python/core/agent/config/__init__.py diff --git a/adf_core_python/core/agent/config/module_config.py b/src/adf_core_python/core/agent/config/module_config.py similarity index 100% rename from adf_core_python/core/agent/config/module_config.py rename to src/adf_core_python/core/agent/config/module_config.py diff --git a/adf_core_python/core/agent/develop/__init__.py b/src/adf_core_python/core/agent/develop/__init__.py similarity index 100% rename from adf_core_python/core/agent/develop/__init__.py rename to src/adf_core_python/core/agent/develop/__init__.py diff --git a/adf_core_python/core/agent/develop/develop_data.py b/src/adf_core_python/core/agent/develop/develop_data.py similarity index 100% rename from adf_core_python/core/agent/develop/develop_data.py rename to src/adf_core_python/core/agent/develop/develop_data.py diff --git a/adf_core_python/core/agent/info/__init__.py b/src/adf_core_python/core/agent/info/__init__.py similarity index 100% rename from adf_core_python/core/agent/info/__init__.py rename to src/adf_core_python/core/agent/info/__init__.py diff --git a/adf_core_python/core/agent/info/agent_info.py b/src/adf_core_python/core/agent/info/agent_info.py similarity index 100% rename from adf_core_python/core/agent/info/agent_info.py rename to src/adf_core_python/core/agent/info/agent_info.py diff --git a/adf_core_python/core/agent/info/scenario_info.py b/src/adf_core_python/core/agent/info/scenario_info.py similarity index 100% rename from adf_core_python/core/agent/info/scenario_info.py rename to src/adf_core_python/core/agent/info/scenario_info.py diff --git a/adf_core_python/core/agent/info/world_info.py b/src/adf_core_python/core/agent/info/world_info.py similarity index 100% rename from adf_core_python/core/agent/info/world_info.py rename to src/adf_core_python/core/agent/info/world_info.py diff --git a/adf_core_python/core/agent/module/__init__.py b/src/adf_core_python/core/agent/module/__init__.py similarity index 100% rename from adf_core_python/core/agent/module/__init__.py rename to src/adf_core_python/core/agent/module/__init__.py diff --git a/adf_core_python/core/agent/module/module_manager.py b/src/adf_core_python/core/agent/module/module_manager.py similarity index 100% rename from adf_core_python/core/agent/module/module_manager.py rename to src/adf_core_python/core/agent/module/module_manager.py diff --git a/adf_core_python/core/agent/office/office.py b/src/adf_core_python/core/agent/office/office.py similarity index 100% rename from adf_core_python/core/agent/office/office.py rename to src/adf_core_python/core/agent/office/office.py diff --git a/adf_core_python/core/agent/office/office_ambulance.py b/src/adf_core_python/core/agent/office/office_ambulance.py similarity index 100% rename from adf_core_python/core/agent/office/office_ambulance.py rename to src/adf_core_python/core/agent/office/office_ambulance.py diff --git a/adf_core_python/core/agent/office/office_fire.py b/src/adf_core_python/core/agent/office/office_fire.py similarity index 100% rename from adf_core_python/core/agent/office/office_fire.py rename to src/adf_core_python/core/agent/office/office_fire.py diff --git a/adf_core_python/core/agent/office/office_police.py b/src/adf_core_python/core/agent/office/office_police.py similarity index 100% rename from adf_core_python/core/agent/office/office_police.py rename to src/adf_core_python/core/agent/office/office_police.py diff --git a/adf_core_python/core/agent/platoon/__init__.py b/src/adf_core_python/core/agent/platoon/__init__.py similarity index 100% rename from adf_core_python/core/agent/platoon/__init__.py rename to src/adf_core_python/core/agent/platoon/__init__.py diff --git a/adf_core_python/core/agent/platoon/platoon.py b/src/adf_core_python/core/agent/platoon/platoon.py similarity index 100% rename from adf_core_python/core/agent/platoon/platoon.py rename to src/adf_core_python/core/agent/platoon/platoon.py diff --git a/adf_core_python/core/agent/platoon/platoon_ambulance.py b/src/adf_core_python/core/agent/platoon/platoon_ambulance.py similarity index 100% rename from adf_core_python/core/agent/platoon/platoon_ambulance.py rename to src/adf_core_python/core/agent/platoon/platoon_ambulance.py diff --git a/adf_core_python/core/agent/platoon/platoon_fire.py b/src/adf_core_python/core/agent/platoon/platoon_fire.py similarity index 100% rename from adf_core_python/core/agent/platoon/platoon_fire.py rename to src/adf_core_python/core/agent/platoon/platoon_fire.py diff --git a/adf_core_python/core/agent/platoon/platoon_police.py b/src/adf_core_python/core/agent/platoon/platoon_police.py similarity index 100% rename from adf_core_python/core/agent/platoon/platoon_police.py rename to src/adf_core_python/core/agent/platoon/platoon_police.py diff --git a/adf_core_python/core/agent/precompute/__init__.py b/src/adf_core_python/core/component/__init__.py similarity index 100% rename from adf_core_python/core/agent/precompute/__init__.py rename to src/adf_core_python/core/component/__init__.py diff --git a/adf_core_python/core/component/abstract_loader.py b/src/adf_core_python/core/component/abstract_loader.py similarity index 100% rename from adf_core_python/core/component/abstract_loader.py rename to src/adf_core_python/core/component/abstract_loader.py diff --git a/adf_core_python/core/component/__init__.py b/src/adf_core_python/core/component/action/__init__.py similarity index 100% rename from adf_core_python/core/component/__init__.py rename to src/adf_core_python/core/component/action/__init__.py diff --git a/adf_core_python/core/component/action/extend_action.py b/src/adf_core_python/core/component/action/extend_action.py similarity index 100% rename from adf_core_python/core/component/action/extend_action.py rename to src/adf_core_python/core/component/action/extend_action.py diff --git a/adf_core_python/core/component/centralized/command_executor.py b/src/adf_core_python/core/component/centralized/command_executor.py similarity index 100% rename from adf_core_python/core/component/centralized/command_executor.py rename to src/adf_core_python/core/component/centralized/command_executor.py diff --git a/adf_core_python/core/component/centralized/command_picker.py b/src/adf_core_python/core/component/centralized/command_picker.py similarity index 100% rename from adf_core_python/core/component/centralized/command_picker.py rename to src/adf_core_python/core/component/centralized/command_picker.py diff --git a/adf_core_python/core/component/action/__init__.py b/src/adf_core_python/core/component/communication/__init__.py similarity index 100% rename from adf_core_python/core/component/action/__init__.py rename to src/adf_core_python/core/component/communication/__init__.py diff --git a/adf_core_python/core/component/communication/channel_subscriber.py b/src/adf_core_python/core/component/communication/channel_subscriber.py similarity index 100% rename from adf_core_python/core/component/communication/channel_subscriber.py rename to src/adf_core_python/core/component/communication/channel_subscriber.py diff --git a/adf_core_python/core/component/communication/communication_message.py b/src/adf_core_python/core/component/communication/communication_message.py similarity index 100% rename from adf_core_python/core/component/communication/communication_message.py rename to src/adf_core_python/core/component/communication/communication_message.py diff --git a/adf_core_python/core/component/communication/communication_module.py b/src/adf_core_python/core/component/communication/communication_module.py similarity index 100% rename from adf_core_python/core/component/communication/communication_module.py rename to src/adf_core_python/core/component/communication/communication_module.py diff --git a/adf_core_python/core/component/communication/message_coordinator.py b/src/adf_core_python/core/component/communication/message_coordinator.py similarity index 100% rename from adf_core_python/core/component/communication/message_coordinator.py rename to src/adf_core_python/core/component/communication/message_coordinator.py diff --git a/adf_core_python/core/component/communication/__init__.py b/src/adf_core_python/core/component/module/__init__.py similarity index 100% rename from adf_core_python/core/component/communication/__init__.py rename to src/adf_core_python/core/component/module/__init__.py diff --git a/adf_core_python/core/component/module/abstract_module.py b/src/adf_core_python/core/component/module/abstract_module.py similarity index 100% rename from adf_core_python/core/component/module/abstract_module.py rename to src/adf_core_python/core/component/module/abstract_module.py diff --git a/adf_core_python/core/component/module/__init__.py b/src/adf_core_python/core/component/module/algorithm/__init__.py similarity index 100% rename from adf_core_python/core/component/module/__init__.py rename to src/adf_core_python/core/component/module/algorithm/__init__.py diff --git a/adf_core_python/core/component/module/algorithm/clustering.py b/src/adf_core_python/core/component/module/algorithm/clustering.py similarity index 100% rename from adf_core_python/core/component/module/algorithm/clustering.py rename to src/adf_core_python/core/component/module/algorithm/clustering.py diff --git a/adf_core_python/core/component/module/algorithm/path_planning.py b/src/adf_core_python/core/component/module/algorithm/path_planning.py similarity index 100% rename from adf_core_python/core/component/module/algorithm/path_planning.py rename to src/adf_core_python/core/component/module/algorithm/path_planning.py diff --git a/adf_core_python/core/component/module/algorithm/__init__.py b/src/adf_core_python/core/component/module/complex/__init__.py similarity index 100% rename from adf_core_python/core/component/module/algorithm/__init__.py rename to src/adf_core_python/core/component/module/complex/__init__.py diff --git a/adf_core_python/core/component/module/complex/ambulance_target_allocator.py b/src/adf_core_python/core/component/module/complex/ambulance_target_allocator.py similarity index 100% rename from adf_core_python/core/component/module/complex/ambulance_target_allocator.py rename to src/adf_core_python/core/component/module/complex/ambulance_target_allocator.py diff --git a/adf_core_python/core/component/module/complex/fire_target_allocator.py b/src/adf_core_python/core/component/module/complex/fire_target_allocator.py similarity index 100% rename from adf_core_python/core/component/module/complex/fire_target_allocator.py rename to src/adf_core_python/core/component/module/complex/fire_target_allocator.py diff --git a/adf_core_python/core/component/module/complex/human_detector.py b/src/adf_core_python/core/component/module/complex/human_detector.py similarity index 100% rename from adf_core_python/core/component/module/complex/human_detector.py rename to src/adf_core_python/core/component/module/complex/human_detector.py diff --git a/adf_core_python/core/component/module/complex/police_target_allocator.py b/src/adf_core_python/core/component/module/complex/police_target_allocator.py similarity index 100% rename from adf_core_python/core/component/module/complex/police_target_allocator.py rename to src/adf_core_python/core/component/module/complex/police_target_allocator.py diff --git a/adf_core_python/core/component/module/complex/road_detector.py b/src/adf_core_python/core/component/module/complex/road_detector.py similarity index 100% rename from adf_core_python/core/component/module/complex/road_detector.py rename to src/adf_core_python/core/component/module/complex/road_detector.py diff --git a/adf_core_python/core/component/module/complex/search.py b/src/adf_core_python/core/component/module/complex/search.py similarity index 100% rename from adf_core_python/core/component/module/complex/search.py rename to src/adf_core_python/core/component/module/complex/search.py diff --git a/adf_core_python/core/component/module/complex/target_allocator.py b/src/adf_core_python/core/component/module/complex/target_allocator.py similarity index 100% rename from adf_core_python/core/component/module/complex/target_allocator.py rename to src/adf_core_python/core/component/module/complex/target_allocator.py diff --git a/adf_core_python/core/component/module/complex/target_detector.py b/src/adf_core_python/core/component/module/complex/target_detector.py similarity index 100% rename from adf_core_python/core/component/module/complex/target_detector.py rename to src/adf_core_python/core/component/module/complex/target_detector.py diff --git a/adf_core_python/core/component/module/complex/__init__.py b/src/adf_core_python/core/component/tactics/__init__.py similarity index 100% rename from adf_core_python/core/component/module/complex/__init__.py rename to src/adf_core_python/core/component/tactics/__init__.py diff --git a/adf_core_python/core/component/tactics/tactics_agent.py b/src/adf_core_python/core/component/tactics/tactics_agent.py similarity index 100% rename from adf_core_python/core/component/tactics/tactics_agent.py rename to src/adf_core_python/core/component/tactics/tactics_agent.py diff --git a/adf_core_python/core/component/tactics/tactics_ambulance_center.py b/src/adf_core_python/core/component/tactics/tactics_ambulance_center.py similarity index 100% rename from adf_core_python/core/component/tactics/tactics_ambulance_center.py rename to src/adf_core_python/core/component/tactics/tactics_ambulance_center.py diff --git a/adf_core_python/core/component/tactics/tactics_ambulance_team.py b/src/adf_core_python/core/component/tactics/tactics_ambulance_team.py similarity index 100% rename from adf_core_python/core/component/tactics/tactics_ambulance_team.py rename to src/adf_core_python/core/component/tactics/tactics_ambulance_team.py diff --git a/adf_core_python/core/component/tactics/tactics_center.py b/src/adf_core_python/core/component/tactics/tactics_center.py similarity index 100% rename from adf_core_python/core/component/tactics/tactics_center.py rename to src/adf_core_python/core/component/tactics/tactics_center.py diff --git a/adf_core_python/core/component/tactics/tactics_fire_brigade.py b/src/adf_core_python/core/component/tactics/tactics_fire_brigade.py similarity index 100% rename from adf_core_python/core/component/tactics/tactics_fire_brigade.py rename to src/adf_core_python/core/component/tactics/tactics_fire_brigade.py diff --git a/adf_core_python/core/component/tactics/tactics_fire_station.py b/src/adf_core_python/core/component/tactics/tactics_fire_station.py similarity index 100% rename from adf_core_python/core/component/tactics/tactics_fire_station.py rename to src/adf_core_python/core/component/tactics/tactics_fire_station.py diff --git a/adf_core_python/core/component/tactics/tactics_police_force.py b/src/adf_core_python/core/component/tactics/tactics_police_force.py similarity index 100% rename from adf_core_python/core/component/tactics/tactics_police_force.py rename to src/adf_core_python/core/component/tactics/tactics_police_force.py diff --git a/adf_core_python/core/component/tactics/tactics_police_office.py b/src/adf_core_python/core/component/tactics/tactics_police_office.py similarity index 100% rename from adf_core_python/core/component/tactics/tactics_police_office.py rename to src/adf_core_python/core/component/tactics/tactics_police_office.py diff --git a/adf_core_python/core/component/tactics/__init__.py b/src/adf_core_python/core/config/__init__.py similarity index 100% rename from adf_core_python/core/component/tactics/__init__.py rename to src/adf_core_python/core/config/__init__.py diff --git a/adf_core_python/core/config/config.py b/src/adf_core_python/core/config/config.py similarity index 100% rename from adf_core_python/core/config/config.py rename to src/adf_core_python/core/config/config.py diff --git a/adf_core_python/core/config/__init__.py b/src/adf_core_python/core/gateway/__init__.py similarity index 100% rename from adf_core_python/core/config/__init__.py rename to src/adf_core_python/core/gateway/__init__.py diff --git a/adf_core_python/core/gateway/__init__.py b/src/adf_core_python/core/gateway/component/__init__.py similarity index 100% rename from adf_core_python/core/gateway/__init__.py rename to src/adf_core_python/core/gateway/component/__init__.py diff --git a/adf_core_python/core/gateway/component/__init__.py b/src/adf_core_python/core/gateway/component/module/__init__.py similarity index 100% rename from adf_core_python/core/gateway/component/__init__.py rename to src/adf_core_python/core/gateway/component/module/__init__.py diff --git a/adf_core_python/core/gateway/component/module/__init__.py b/src/adf_core_python/core/gateway/component/module/algorithm/__init__.py similarity index 100% rename from adf_core_python/core/gateway/component/module/__init__.py rename to src/adf_core_python/core/gateway/component/module/algorithm/__init__.py diff --git a/adf_core_python/core/gateway/component/module/algorithm/gateway_clustering.py b/src/adf_core_python/core/gateway/component/module/algorithm/gateway_clustering.py similarity index 100% rename from adf_core_python/core/gateway/component/module/algorithm/gateway_clustering.py rename to src/adf_core_python/core/gateway/component/module/algorithm/gateway_clustering.py diff --git a/adf_core_python/core/gateway/component/module/algorithm/gateway_path_planning.py b/src/adf_core_python/core/gateway/component/module/algorithm/gateway_path_planning.py similarity index 100% rename from adf_core_python/core/gateway/component/module/algorithm/gateway_path_planning.py rename to src/adf_core_python/core/gateway/component/module/algorithm/gateway_path_planning.py diff --git a/adf_core_python/core/gateway/component/module/algorithm/__init__.py b/src/adf_core_python/core/gateway/component/module/complex/__init__.py similarity index 100% rename from adf_core_python/core/gateway/component/module/algorithm/__init__.py rename to src/adf_core_python/core/gateway/component/module/complex/__init__.py diff --git a/adf_core_python/core/gateway/component/module/complex/gateway_ambulance_target_allocator.py b/src/adf_core_python/core/gateway/component/module/complex/gateway_ambulance_target_allocator.py similarity index 100% rename from adf_core_python/core/gateway/component/module/complex/gateway_ambulance_target_allocator.py rename to src/adf_core_python/core/gateway/component/module/complex/gateway_ambulance_target_allocator.py diff --git a/adf_core_python/core/gateway/component/module/complex/gateway_fire_target_allocator.py b/src/adf_core_python/core/gateway/component/module/complex/gateway_fire_target_allocator.py similarity index 100% rename from adf_core_python/core/gateway/component/module/complex/gateway_fire_target_allocator.py rename to src/adf_core_python/core/gateway/component/module/complex/gateway_fire_target_allocator.py diff --git a/adf_core_python/core/gateway/component/module/complex/gateway_human_detector.py b/src/adf_core_python/core/gateway/component/module/complex/gateway_human_detector.py similarity index 100% rename from adf_core_python/core/gateway/component/module/complex/gateway_human_detector.py rename to src/adf_core_python/core/gateway/component/module/complex/gateway_human_detector.py diff --git a/adf_core_python/core/gateway/component/module/complex/gateway_police_target_allocator.py b/src/adf_core_python/core/gateway/component/module/complex/gateway_police_target_allocator.py similarity index 100% rename from adf_core_python/core/gateway/component/module/complex/gateway_police_target_allocator.py rename to src/adf_core_python/core/gateway/component/module/complex/gateway_police_target_allocator.py diff --git a/adf_core_python/core/gateway/component/module/complex/gateway_road_detector.py b/src/adf_core_python/core/gateway/component/module/complex/gateway_road_detector.py similarity index 100% rename from adf_core_python/core/gateway/component/module/complex/gateway_road_detector.py rename to src/adf_core_python/core/gateway/component/module/complex/gateway_road_detector.py diff --git a/adf_core_python/core/gateway/component/module/complex/gateway_search.py b/src/adf_core_python/core/gateway/component/module/complex/gateway_search.py similarity index 100% rename from adf_core_python/core/gateway/component/module/complex/gateway_search.py rename to src/adf_core_python/core/gateway/component/module/complex/gateway_search.py diff --git a/adf_core_python/core/gateway/component/module/complex/gateway_target_allocator.py b/src/adf_core_python/core/gateway/component/module/complex/gateway_target_allocator.py similarity index 100% rename from adf_core_python/core/gateway/component/module/complex/gateway_target_allocator.py rename to src/adf_core_python/core/gateway/component/module/complex/gateway_target_allocator.py diff --git a/adf_core_python/core/gateway/component/module/complex/gateway_target_detector.py b/src/adf_core_python/core/gateway/component/module/complex/gateway_target_detector.py similarity index 100% rename from adf_core_python/core/gateway/component/module/complex/gateway_target_detector.py rename to src/adf_core_python/core/gateway/component/module/complex/gateway_target_detector.py diff --git a/adf_core_python/core/gateway/component/module/gateway_abstract_module.py b/src/adf_core_python/core/gateway/component/module/gateway_abstract_module.py similarity index 100% rename from adf_core_python/core/gateway/component/module/gateway_abstract_module.py rename to src/adf_core_python/core/gateway/component/module/gateway_abstract_module.py diff --git a/adf_core_python/core/gateway/gateway_agent.py b/src/adf_core_python/core/gateway/gateway_agent.py similarity index 100% rename from adf_core_python/core/gateway/gateway_agent.py rename to src/adf_core_python/core/gateway/gateway_agent.py diff --git a/adf_core_python/core/gateway/gateway_launcher.py b/src/adf_core_python/core/gateway/gateway_launcher.py similarity index 100% rename from adf_core_python/core/gateway/gateway_launcher.py rename to src/adf_core_python/core/gateway/gateway_launcher.py diff --git a/adf_core_python/core/gateway/gateway_module.py b/src/adf_core_python/core/gateway/gateway_module.py similarity index 100% rename from adf_core_python/core/gateway/gateway_module.py rename to src/adf_core_python/core/gateway/gateway_module.py diff --git a/adf_core_python/core/gateway/component/module/complex/__init__.py b/src/adf_core_python/core/gateway/message/__init__.py similarity index 100% rename from adf_core_python/core/gateway/component/module/complex/__init__.py rename to src/adf_core_python/core/gateway/message/__init__.py diff --git a/adf_core_python/core/gateway/message/am_agent.py b/src/adf_core_python/core/gateway/message/am_agent.py similarity index 100% rename from adf_core_python/core/gateway/message/am_agent.py rename to src/adf_core_python/core/gateway/message/am_agent.py diff --git a/adf_core_python/core/gateway/message/am_exec.py b/src/adf_core_python/core/gateway/message/am_exec.py similarity index 100% rename from adf_core_python/core/gateway/message/am_exec.py rename to src/adf_core_python/core/gateway/message/am_exec.py diff --git a/adf_core_python/core/gateway/message/am_module.py b/src/adf_core_python/core/gateway/message/am_module.py similarity index 100% rename from adf_core_python/core/gateway/message/am_module.py rename to src/adf_core_python/core/gateway/message/am_module.py diff --git a/adf_core_python/core/gateway/message/am_update.py b/src/adf_core_python/core/gateway/message/am_update.py similarity index 100% rename from adf_core_python/core/gateway/message/am_update.py rename to src/adf_core_python/core/gateway/message/am_update.py diff --git a/adf_core_python/core/gateway/message/ma_exec_response.py b/src/adf_core_python/core/gateway/message/ma_exec_response.py similarity index 100% rename from adf_core_python/core/gateway/message/ma_exec_response.py rename to src/adf_core_python/core/gateway/message/ma_exec_response.py diff --git a/adf_core_python/core/gateway/message/ma_module_response.py b/src/adf_core_python/core/gateway/message/ma_module_response.py similarity index 100% rename from adf_core_python/core/gateway/message/ma_module_response.py rename to src/adf_core_python/core/gateway/message/ma_module_response.py diff --git a/adf_core_python/core/gateway/message/moduleMessageFactory.py b/src/adf_core_python/core/gateway/message/moduleMessageFactory.py similarity index 100% rename from adf_core_python/core/gateway/message/moduleMessageFactory.py rename to src/adf_core_python/core/gateway/message/moduleMessageFactory.py diff --git a/adf_core_python/core/gateway/message/__init__.py b/src/adf_core_python/core/gateway/message/urn/__init__.py similarity index 100% rename from adf_core_python/core/gateway/message/__init__.py rename to src/adf_core_python/core/gateway/message/urn/__init__.py diff --git a/adf_core_python/core/gateway/message/urn/urn.py b/src/adf_core_python/core/gateway/message/urn/urn.py similarity index 100% rename from adf_core_python/core/gateway/message/urn/urn.py rename to src/adf_core_python/core/gateway/message/urn/urn.py diff --git a/adf_core_python/core/gateway/module_dict.py b/src/adf_core_python/core/gateway/module_dict.py similarity index 100% rename from adf_core_python/core/gateway/module_dict.py rename to src/adf_core_python/core/gateway/module_dict.py diff --git a/adf_core_python/core/gateway/message/urn/__init__.py b/src/adf_core_python/core/launcher/__init__.py similarity index 100% rename from adf_core_python/core/gateway/message/urn/__init__.py rename to src/adf_core_python/core/launcher/__init__.py diff --git a/adf_core_python/core/launcher/agent_launcher.py b/src/adf_core_python/core/launcher/agent_launcher.py similarity index 100% rename from adf_core_python/core/launcher/agent_launcher.py rename to src/adf_core_python/core/launcher/agent_launcher.py diff --git a/adf_core_python/core/launcher/config_key.py b/src/adf_core_python/core/launcher/config_key.py similarity index 100% rename from adf_core_python/core/launcher/config_key.py rename to src/adf_core_python/core/launcher/config_key.py diff --git a/adf_core_python/core/launcher/__init__.py b/src/adf_core_python/core/launcher/connect/__init__.py similarity index 100% rename from adf_core_python/core/launcher/__init__.py rename to src/adf_core_python/core/launcher/connect/__init__.py diff --git a/adf_core_python/core/launcher/connect/component_launcher.py b/src/adf_core_python/core/launcher/connect/component_launcher.py similarity index 100% rename from adf_core_python/core/launcher/connect/component_launcher.py rename to src/adf_core_python/core/launcher/connect/component_launcher.py diff --git a/adf_core_python/core/launcher/connect/connection.py b/src/adf_core_python/core/launcher/connect/connection.py similarity index 100% rename from adf_core_python/core/launcher/connect/connection.py rename to src/adf_core_python/core/launcher/connect/connection.py diff --git a/adf_core_python/core/launcher/connect/connector.py b/src/adf_core_python/core/launcher/connect/connector.py similarity index 100% rename from adf_core_python/core/launcher/connect/connector.py rename to src/adf_core_python/core/launcher/connect/connector.py diff --git a/adf_core_python/core/launcher/connect/connector_ambulance_center.py b/src/adf_core_python/core/launcher/connect/connector_ambulance_center.py similarity index 100% rename from adf_core_python/core/launcher/connect/connector_ambulance_center.py rename to src/adf_core_python/core/launcher/connect/connector_ambulance_center.py diff --git a/adf_core_python/core/launcher/connect/connector_ambulance_team.py b/src/adf_core_python/core/launcher/connect/connector_ambulance_team.py similarity index 100% rename from adf_core_python/core/launcher/connect/connector_ambulance_team.py rename to src/adf_core_python/core/launcher/connect/connector_ambulance_team.py diff --git a/adf_core_python/core/launcher/connect/connector_fire_brigade.py b/src/adf_core_python/core/launcher/connect/connector_fire_brigade.py similarity index 100% rename from adf_core_python/core/launcher/connect/connector_fire_brigade.py rename to src/adf_core_python/core/launcher/connect/connector_fire_brigade.py diff --git a/adf_core_python/core/launcher/connect/connector_fire_station.py b/src/adf_core_python/core/launcher/connect/connector_fire_station.py similarity index 100% rename from adf_core_python/core/launcher/connect/connector_fire_station.py rename to src/adf_core_python/core/launcher/connect/connector_fire_station.py diff --git a/adf_core_python/core/launcher/connect/connector_police_force.py b/src/adf_core_python/core/launcher/connect/connector_police_force.py similarity index 100% rename from adf_core_python/core/launcher/connect/connector_police_force.py rename to src/adf_core_python/core/launcher/connect/connector_police_force.py diff --git a/adf_core_python/core/launcher/connect/connector_police_office.py b/src/adf_core_python/core/launcher/connect/connector_police_office.py similarity index 100% rename from adf_core_python/core/launcher/connect/connector_police_office.py rename to src/adf_core_python/core/launcher/connect/connector_police_office.py diff --git a/adf_core_python/core/launcher/connect/error/agent_error.py b/src/adf_core_python/core/launcher/connect/error/agent_error.py similarity index 100% rename from adf_core_python/core/launcher/connect/error/agent_error.py rename to src/adf_core_python/core/launcher/connect/error/agent_error.py diff --git a/adf_core_python/core/launcher/connect/error/server_error.py b/src/adf_core_python/core/launcher/connect/error/server_error.py similarity index 100% rename from adf_core_python/core/launcher/connect/error/server_error.py rename to src/adf_core_python/core/launcher/connect/error/server_error.py diff --git a/adf_core_python/core/launcher/connect/__init__.py b/src/adf_core_python/core/logger/__init__.py similarity index 100% rename from adf_core_python/core/launcher/connect/__init__.py rename to src/adf_core_python/core/logger/__init__.py diff --git a/adf_core_python/core/logger/logger.py b/src/adf_core_python/core/logger/logger.py similarity index 100% rename from adf_core_python/core/logger/logger.py rename to src/adf_core_python/core/logger/logger.py diff --git a/adf_core_python/core/logger/__init__.py b/src/adf_core_python/implement/__init__.py similarity index 100% rename from adf_core_python/core/logger/__init__.py rename to src/adf_core_python/implement/__init__.py diff --git a/adf_core_python/implement/__init__.py b/src/adf_core_python/implement/action/__init__.py similarity index 100% rename from adf_core_python/implement/__init__.py rename to src/adf_core_python/implement/action/__init__.py diff --git a/adf_core_python/implement/action/default_extend_action_clear.py b/src/adf_core_python/implement/action/default_extend_action_clear.py similarity index 100% rename from adf_core_python/implement/action/default_extend_action_clear.py rename to src/adf_core_python/implement/action/default_extend_action_clear.py diff --git a/adf_core_python/implement/action/default_extend_action_move.py b/src/adf_core_python/implement/action/default_extend_action_move.py similarity index 100% rename from adf_core_python/implement/action/default_extend_action_move.py rename to src/adf_core_python/implement/action/default_extend_action_move.py diff --git a/adf_core_python/implement/action/default_extend_action_rescue.py b/src/adf_core_python/implement/action/default_extend_action_rescue.py similarity index 100% rename from adf_core_python/implement/action/default_extend_action_rescue.py rename to src/adf_core_python/implement/action/default_extend_action_rescue.py diff --git a/adf_core_python/implement/action/default_extend_action_transport.py b/src/adf_core_python/implement/action/default_extend_action_transport.py similarity index 100% rename from adf_core_python/implement/action/default_extend_action_transport.py rename to src/adf_core_python/implement/action/default_extend_action_transport.py diff --git a/adf_core_python/implement/centralized/default_command_executor_ambulance.py b/src/adf_core_python/implement/centralized/default_command_executor_ambulance.py similarity index 100% rename from adf_core_python/implement/centralized/default_command_executor_ambulance.py rename to src/adf_core_python/implement/centralized/default_command_executor_ambulance.py diff --git a/adf_core_python/implement/centralized/default_command_executor_fire.py b/src/adf_core_python/implement/centralized/default_command_executor_fire.py similarity index 100% rename from adf_core_python/implement/centralized/default_command_executor_fire.py rename to src/adf_core_python/implement/centralized/default_command_executor_fire.py diff --git a/adf_core_python/implement/centralized/default_command_executor_police.py b/src/adf_core_python/implement/centralized/default_command_executor_police.py similarity index 100% rename from adf_core_python/implement/centralized/default_command_executor_police.py rename to src/adf_core_python/implement/centralized/default_command_executor_police.py diff --git a/adf_core_python/implement/centralized/default_command_executor_scout.py b/src/adf_core_python/implement/centralized/default_command_executor_scout.py similarity index 100% rename from adf_core_python/implement/centralized/default_command_executor_scout.py rename to src/adf_core_python/implement/centralized/default_command_executor_scout.py diff --git a/adf_core_python/implement/centralized/default_command_executor_scout_police.py b/src/adf_core_python/implement/centralized/default_command_executor_scout_police.py similarity index 100% rename from adf_core_python/implement/centralized/default_command_executor_scout_police.py rename to src/adf_core_python/implement/centralized/default_command_executor_scout_police.py diff --git a/adf_core_python/implement/centralized/default_command_picker_ambulance.py b/src/adf_core_python/implement/centralized/default_command_picker_ambulance.py similarity index 100% rename from adf_core_python/implement/centralized/default_command_picker_ambulance.py rename to src/adf_core_python/implement/centralized/default_command_picker_ambulance.py diff --git a/adf_core_python/implement/centralized/default_command_picker_fire.py b/src/adf_core_python/implement/centralized/default_command_picker_fire.py similarity index 100% rename from adf_core_python/implement/centralized/default_command_picker_fire.py rename to src/adf_core_python/implement/centralized/default_command_picker_fire.py diff --git a/adf_core_python/implement/centralized/default_command_picker_police.py b/src/adf_core_python/implement/centralized/default_command_picker_police.py similarity index 100% rename from adf_core_python/implement/centralized/default_command_picker_police.py rename to src/adf_core_python/implement/centralized/default_command_picker_police.py diff --git a/adf_core_python/implement/default_loader.py b/src/adf_core_python/implement/default_loader.py similarity index 100% rename from adf_core_python/implement/default_loader.py rename to src/adf_core_python/implement/default_loader.py diff --git a/adf_core_python/implement/action/__init__.py b/src/adf_core_python/implement/module/__init__.py similarity index 100% rename from adf_core_python/implement/action/__init__.py rename to src/adf_core_python/implement/module/__init__.py diff --git a/adf_core_python/implement/module/__init__.py b/src/adf_core_python/implement/module/algorithm/__init__.py similarity index 100% rename from adf_core_python/implement/module/__init__.py rename to src/adf_core_python/implement/module/algorithm/__init__.py diff --git a/adf_core_python/implement/module/algorithm/a_star_path_planning.py b/src/adf_core_python/implement/module/algorithm/a_star_path_planning.py similarity index 100% rename from adf_core_python/implement/module/algorithm/a_star_path_planning.py rename to src/adf_core_python/implement/module/algorithm/a_star_path_planning.py diff --git a/adf_core_python/implement/module/algorithm/dijkstra_path_planning.py b/src/adf_core_python/implement/module/algorithm/dijkstra_path_planning.py similarity index 100% rename from adf_core_python/implement/module/algorithm/dijkstra_path_planning.py rename to src/adf_core_python/implement/module/algorithm/dijkstra_path_planning.py diff --git a/adf_core_python/implement/module/algorithm/k_means_clustering.py b/src/adf_core_python/implement/module/algorithm/k_means_clustering.py similarity index 100% rename from adf_core_python/implement/module/algorithm/k_means_clustering.py rename to src/adf_core_python/implement/module/algorithm/k_means_clustering.py diff --git a/adf_core_python/implement/module/algorithm/__init__.py b/src/adf_core_python/implement/module/communication/__init__.py similarity index 100% rename from adf_core_python/implement/module/algorithm/__init__.py rename to src/adf_core_python/implement/module/communication/__init__.py diff --git a/adf_core_python/implement/module/communication/default_channel_subscriber.py b/src/adf_core_python/implement/module/communication/default_channel_subscriber.py similarity index 100% rename from adf_core_python/implement/module/communication/default_channel_subscriber.py rename to src/adf_core_python/implement/module/communication/default_channel_subscriber.py diff --git a/adf_core_python/implement/module/communication/default_message_coordinator.py b/src/adf_core_python/implement/module/communication/default_message_coordinator.py similarity index 100% rename from adf_core_python/implement/module/communication/default_message_coordinator.py rename to src/adf_core_python/implement/module/communication/default_message_coordinator.py diff --git a/adf_core_python/implement/module/communication/__init__.py b/src/adf_core_python/implement/module/complex/__init__.py similarity index 100% rename from adf_core_python/implement/module/communication/__init__.py rename to src/adf_core_python/implement/module/complex/__init__.py diff --git a/adf_core_python/implement/module/complex/default_ambulance_target_allocator.py b/src/adf_core_python/implement/module/complex/default_ambulance_target_allocator.py similarity index 100% rename from adf_core_python/implement/module/complex/default_ambulance_target_allocator.py rename to src/adf_core_python/implement/module/complex/default_ambulance_target_allocator.py diff --git a/adf_core_python/implement/module/complex/default_fire_target_allocator.py b/src/adf_core_python/implement/module/complex/default_fire_target_allocator.py similarity index 100% rename from adf_core_python/implement/module/complex/default_fire_target_allocator.py rename to src/adf_core_python/implement/module/complex/default_fire_target_allocator.py diff --git a/adf_core_python/implement/module/complex/default_human_detector.py b/src/adf_core_python/implement/module/complex/default_human_detector.py similarity index 100% rename from adf_core_python/implement/module/complex/default_human_detector.py rename to src/adf_core_python/implement/module/complex/default_human_detector.py diff --git a/adf_core_python/implement/module/complex/default_police_target_allocator.py b/src/adf_core_python/implement/module/complex/default_police_target_allocator.py similarity index 100% rename from adf_core_python/implement/module/complex/default_police_target_allocator.py rename to src/adf_core_python/implement/module/complex/default_police_target_allocator.py diff --git a/adf_core_python/implement/module/complex/default_road_detector.py b/src/adf_core_python/implement/module/complex/default_road_detector.py similarity index 100% rename from adf_core_python/implement/module/complex/default_road_detector.py rename to src/adf_core_python/implement/module/complex/default_road_detector.py diff --git a/adf_core_python/implement/module/complex/default_search.py b/src/adf_core_python/implement/module/complex/default_search.py similarity index 100% rename from adf_core_python/implement/module/complex/default_search.py rename to src/adf_core_python/implement/module/complex/default_search.py diff --git a/adf_core_python/implement/module/complex/__init__.py b/src/adf_core_python/implement/tactics/__init__.py similarity index 100% rename from adf_core_python/implement/module/complex/__init__.py rename to src/adf_core_python/implement/tactics/__init__.py diff --git a/adf_core_python/implement/tactics/default_tactics_ambulance_center.py b/src/adf_core_python/implement/tactics/default_tactics_ambulance_center.py similarity index 100% rename from adf_core_python/implement/tactics/default_tactics_ambulance_center.py rename to src/adf_core_python/implement/tactics/default_tactics_ambulance_center.py diff --git a/adf_core_python/implement/tactics/default_tactics_ambulance_team.py b/src/adf_core_python/implement/tactics/default_tactics_ambulance_team.py similarity index 100% rename from adf_core_python/implement/tactics/default_tactics_ambulance_team.py rename to src/adf_core_python/implement/tactics/default_tactics_ambulance_team.py diff --git a/adf_core_python/implement/tactics/default_tactics_fire_brigade.py b/src/adf_core_python/implement/tactics/default_tactics_fire_brigade.py similarity index 100% rename from adf_core_python/implement/tactics/default_tactics_fire_brigade.py rename to src/adf_core_python/implement/tactics/default_tactics_fire_brigade.py diff --git a/adf_core_python/implement/tactics/default_tactics_fire_station.py b/src/adf_core_python/implement/tactics/default_tactics_fire_station.py similarity index 100% rename from adf_core_python/implement/tactics/default_tactics_fire_station.py rename to src/adf_core_python/implement/tactics/default_tactics_fire_station.py diff --git a/adf_core_python/implement/tactics/default_tactics_police_force.py b/src/adf_core_python/implement/tactics/default_tactics_police_force.py similarity index 100% rename from adf_core_python/implement/tactics/default_tactics_police_force.py rename to src/adf_core_python/implement/tactics/default_tactics_police_force.py diff --git a/adf_core_python/implement/tactics/default_tactics_police_office.py b/src/adf_core_python/implement/tactics/default_tactics_police_office.py similarity index 100% rename from adf_core_python/implement/tactics/default_tactics_police_office.py rename to src/adf_core_python/implement/tactics/default_tactics_police_office.py diff --git a/adf_core_python/launcher.py b/src/adf_core_python/launcher.py similarity index 100% rename from adf_core_python/launcher.py rename to src/adf_core_python/launcher.py From 016423596410e9c9fea97c3b01342f5fee35daf3 Mon Sep 17 00:00:00 2001 From: shima004 Date: Mon, 4 Aug 2025 15:06:13 +0900 Subject: [PATCH 04/13] feat: poetry to uv --- .github/workflows/ci.yaml | 14 +- .github/workflows/document.yaml | 6 +- .python-version | 1 + poetry.lock | 1747 ------------------------------- poetry.toml | 2 - pyproject.toml | 101 +- uv.lock | 947 +++++++++++++++++ 7 files changed, 1006 insertions(+), 1812 deletions(-) create mode 100644 .python-version delete mode 100644 poetry.lock delete mode 100644 poetry.toml create mode 100644 uv.lock diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index b10f9d2..24ebbf5 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -27,7 +27,7 @@ jobs: uses: actions/cache@v4 with: path: .venv - key: ${{ runner.os }}-venv-${{ hashFiles('**/poetry.lock') }} + key: ${{ runner.os }}-venv-${{ hashFiles('**/uv.lock') }} - name: Install dependencies if: steps.cached-virtualenv.outputs.cache-hit != 'true' @@ -35,8 +35,8 @@ jobs: python -m venv .venv source .venv/bin/activate pip install --upgrade pip - pip install poetry - poetry install + pip install uv + uv sync ruff-format: needs: setup @@ -49,7 +49,7 @@ jobs: uses: actions/cache@v4 with: path: .venv - key: ${{ runner.os }}-venv-${{ hashFiles('**/poetry.lock') }} + key: ${{ runner.os }}-venv-${{ hashFiles('**/uv.lock') }} - name: Set path run: echo ${{ github.workspace }}/.venv/bin >> $GITHUB_PATH @@ -132,12 +132,12 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-java@v4 with: - java-version: '17' - distribution: 'temurin' + java-version: "17" + distribution: "temurin" - name: Setup Gradle uses: gradle/actions/setup-gradle@v3 - name: Publish package run: cd java && ./gradlew publish env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/document.yaml b/.github/workflows/document.yaml index 986bc11..a70bca9 100644 --- a/.github/workflows/document.yaml +++ b/.github/workflows/document.yaml @@ -40,7 +40,7 @@ jobs: uses: actions/cache@v4 with: path: .venv - key: ${{ runner.os }}-venv-${{ hashFiles('**/poetry.lock') }} + key: ${{ runner.os }}-venv-${{ hashFiles('**/uv.lock') }} - name: Install dependencies if: steps.cached-virtualenv.outputs.cache-hit != 'true' @@ -48,8 +48,8 @@ jobs: python -m venv .venv source .venv/bin/activate pip install --upgrade pip - pip install poetry - poetry install + pip install uv + uv sync - name: Build documentation run: | diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..24ee5b1 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.13 diff --git a/poetry.lock b/poetry.lock deleted file mode 100644 index 371973e..0000000 --- a/poetry.lock +++ /dev/null @@ -1,1747 +0,0 @@ -# This file is automatically @generated by Poetry 2.1.2 and should not be changed by hand. - -[[package]] -name = "accessible-pygments" -version = "0.0.5" -description = "A collection of accessible pygments styles" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "accessible_pygments-0.0.5-py3-none-any.whl", hash = "sha256:88ae3211e68a1d0b011504b2ffc1691feafce124b845bd072ab6f9f66f34d4b7"}, - {file = "accessible_pygments-0.0.5.tar.gz", hash = "sha256:40918d3e6a2b619ad424cb91e556bd3bd8865443d9f22f1dcdf79e33c8046872"}, -] - -[package.dependencies] -pygments = ">=1.5" - -[package.extras] -dev = ["pillow", "pkginfo (>=1.10)", "playwright", "pre-commit", "setuptools", "twine (>=5.0)"] -tests = ["hypothesis", "pytest"] - -[[package]] -name = "alabaster" -version = "1.0.0" -description = "A light, configurable Sphinx theme" -optional = false -python-versions = ">=3.10" -groups = ["dev"] -files = [ - {file = "alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b"}, - {file = "alabaster-1.0.0.tar.gz", hash = "sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e"}, -] - -[[package]] -name = "babel" -version = "2.17.0" -description = "Internationalization utilities" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2"}, - {file = "babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d"}, -] - -[package.extras] -dev = ["backports.zoneinfo ; python_version < \"3.9\"", "freezegun (>=1.0,<2.0)", "jinja2 (>=3.0)", "pytest (>=6.0)", "pytest-cov", "pytz", "setuptools", "tzdata ; sys_platform == \"win32\""] - -[[package]] -name = "beautifulsoup4" -version = "4.13.4" -description = "Screen-scraping library" -optional = false -python-versions = ">=3.7.0" -groups = ["dev"] -files = [ - {file = "beautifulsoup4-4.13.4-py3-none-any.whl", hash = "sha256:9bbbb14bfde9d79f38b8cd5f8c7c85f4b8f2523190ebed90e950a8dea4cb1c4b"}, - {file = "beautifulsoup4-4.13.4.tar.gz", hash = "sha256:dbb3c4e1ceae6aefebdaf2423247260cd062430a410e38c66f2baa50a8437195"}, -] - -[package.dependencies] -soupsieve = ">1.2" -typing-extensions = ">=4.0.0" - -[package.extras] -cchardet = ["cchardet"] -chardet = ["chardet"] -charset-normalizer = ["charset-normalizer"] -html5lib = ["html5lib"] -lxml = ["lxml"] - -[[package]] -name = "bitarray" -version = "3.6.0" -description = "efficient arrays of booleans -- C extension" -optional = false -python-versions = "*" -groups = ["main"] -files = [ - {file = "bitarray-3.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6841c08b51417f8ffe398b2828fc0593440c99525c868f640e0302476745320b"}, - {file = "bitarray-3.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a04b7a9017b8d0341ebbe77f61b74df1cf1b714f42b671a06f4912dc93d82597"}, - {file = "bitarray-3.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:664d462a4c0783fd755fe3440f07b7e46d149859c96caacadf3f28890f19a8de"}, - {file = "bitarray-3.6.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e997d22e0d1e08c8752f61675a75d93659f7aa4dbeaee54207f8d877817b4a0c"}, - {file = "bitarray-3.6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6755cfcfa7d8966e704d580c831e39818f85e7b2b7852ad22708973176f0009e"}, - {file = "bitarray-3.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4798f6744fa2633666e17b4ea8ff70250781b52a25afdbf5ffb5e176c58848f1"}, - {file = "bitarray-3.6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:efa5834ba5e6c70b22afdca3894097e5a592d8d483c976359654ba990477799a"}, - {file = "bitarray-3.6.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d47e2bdeba4fb1986af2ba395ce51223f4d460e6e77119439e78f2b592cafade"}, - {file = "bitarray-3.6.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:2a324e3007afb5c667026f5235b35efe3c4a95f1b83cd93aa9fce67b42f08e7c"}, - {file = "bitarray-3.6.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:080a7bf55c432abdae74f25dc3dbff407418346aeae1d43e31f65e8ef114f785"}, - {file = "bitarray-3.6.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:3eb1390a8b062fe9125e5cc4c5eba990b5d383eec54f2b996e7ce73ac43150f9"}, - {file = "bitarray-3.6.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2020102a40edd094c0aa80e09203af71c533c41f76ce3237c99fd194a473ea33"}, - {file = "bitarray-3.6.0-cp310-cp310-win32.whl", hash = "sha256:01d6dc548e7fe5c66913c2274f44855b0f8474935acff7811e84fe1f4024c94f"}, - {file = "bitarray-3.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:8d759cecfa8aab4a1eb4e23b6420126b15c7743e85b33f389916bb98c4ecbb84"}, - {file = "bitarray-3.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7c20d6e6cafce5027e7092beb2ac6eec0d71045d6318b34f36e1387a8c8859a3"}, - {file = "bitarray-3.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cf36cadeb9c989f760a13058dbc455e5406ec3d2d247c705c8d4bc6dd1b0fcc6"}, - {file = "bitarray-3.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30ba4fba3de1dca653de41c879349ec6ca521d85cff6a7ca5d2fdd8f76c93781"}, - {file = "bitarray-3.6.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77d2368a06a86a18919c05a9b4b0ee9869f770e6a5f414b0fecc911870fe3974"}, - {file = "bitarray-3.6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a39be79a7c36e9a2e20376261c30deb3cdca86b50f7462ae9ff10a755c6720b9"}, - {file = "bitarray-3.6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4695fcd37478988b1d0a16d5bc0df56dcb677fd5db37f1893d993fd3ebef914b"}, - {file = "bitarray-3.6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:52328192d454ca2ddad09fbc088872b014c74b22ecdd5164717dc7e6442014fa"}, - {file = "bitarray-3.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:96117212229905da864794df9ea7bd54987c30a5dcbab3432edc3f344231adae"}, - {file = "bitarray-3.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:68f6e64d4867ee79e25c49d7f35b2b1f04a6d6f778176dcf5b759f3b17a02b2b"}, - {file = "bitarray-3.6.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:29ed022189a7997de46cb9bd4e2e49d6163d4f8d78dea72ac5a0e0293b856810"}, - {file = "bitarray-3.6.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e71c9dba78671d38a549e3b2d52514f50e199f9d7e18ed9b0180adeef0d04130"}, - {file = "bitarray-3.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ddb319f869d497ef2d3d56319360b61284a9a1d8b3de3bc936748698acfda6be"}, - {file = "bitarray-3.6.0-cp311-cp311-win32.whl", hash = "sha256:25060e7162e44242a449ed1a14a4e94b5aef340812754c443459f19c7954be91"}, - {file = "bitarray-3.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:f2d951002b11962b26afb31f758c18ad39771f287b100fa5adb1d09a47eaaf5b"}, - {file = "bitarray-3.6.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b9616ea14917d06736339cf36bb9eaf4eb52110a74136b0dc5eff94e92417d22"}, - {file = "bitarray-3.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7e2e1ff784c2cdfd863bad31985851427f2d2796e445cec85080c7510cba4315"}, - {file = "bitarray-3.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:911b4a16dce370657e5b8d8b6ba0fbb50dd5e2b24c4416f4b9e664503d3f0502"}, - {file = "bitarray-3.6.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0b47843f2f288fa746dead4394591a3432a358aaad48240283fa230d6e74b0e7"}, - {file = "bitarray-3.6.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8f95daf0ce2b24815ddf62667229ba5dfc0cfee43eb43b2549766170d0f24ae9"}, - {file = "bitarray-3.6.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c15b9e37bbca59657e4dcc63ad068c821a4676def15f04742c406748a0a11b9c"}, - {file = "bitarray-3.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9d247fcc33c90f2758f4162693250341e3f38cd094f64390076ef33ad0887f9"}, - {file = "bitarray-3.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:84bb57010a1ab76cf880424a2e0bce8dd26989849d2122ff073aa11bfc271c27"}, - {file = "bitarray-3.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:27d13c7b886afc5d2fc49d6e92f9c96b1f0a14dc7b5502520c29f3da7550d401"}, - {file = "bitarray-3.6.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1c4e75bbf9ade3d2cdf1b607a8b353b17d9b3cf54e88b2a5a773f50ae6f1bfbc"}, - {file = "bitarray-3.6.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:975a118aa019d745f1398613b27fd8789f60a8cea057a00cdc1abedee123ffe6"}, - {file = "bitarray-3.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9ed4a2852b3de7a64884afcc6936db771707943249a060aec8e551c16361d478"}, - {file = "bitarray-3.6.0-cp312-cp312-win32.whl", hash = "sha256:5dd9edcab8979a50c2c4dec6d5b66789fb6f630bb52ab90a4548111075a75e48"}, - {file = "bitarray-3.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:552a93be286ca485914777461b384761519db313e0a7f3012dca424c9610a4d5"}, - {file = "bitarray-3.6.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3f96f57cea35ba19fd23a20b38fa0dfa3d87d582507129b8c8e314aa298f59b"}, - {file = "bitarray-3.6.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:81e84054b22babcd6c5cc1eac0de2bfc1054ecdf742720cbfb36efbe89ec6c30"}, - {file = "bitarray-3.6.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca643295bf5441dd38dadf7571ca4b63961820eedbffbe46ceba0893bf226203"}, - {file = "bitarray-3.6.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:139963494fc3dd5caee5e38c0a03783ef50be118565e94b1dbb0210770f0b32d"}, - {file = "bitarray-3.6.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:243825f56b58bef28bfc602992a8c6d09bbc625628c195498d6020120d632a09"}, - {file = "bitarray-3.6.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:583b46b3ba44121de5e87e95ae379932dc5fd2e37ebdf2c11a6d7975891425c1"}, - {file = "bitarray-3.6.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f0be27d06732e2833b672a8fcc32fa195bdb22161eb88f8890de15e30264a01"}, - {file = "bitarray-3.6.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:507e567aee4806576e20752f22533e8b7ec61e7e75062a7ce9222a0675aa0da6"}, - {file = "bitarray-3.6.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:22188943a29072b684cd7c99e0b2cfc0af317cea3366c583d820507e6d1f2ed4"}, - {file = "bitarray-3.6.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f92462ea3888c99439f58f7561ecd5dd4cf8b8b1b259ccf5376667b8c46ee747"}, - {file = "bitarray-3.6.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:3800f3c8c9780f281cf590543fd4b3278fea6988202273a260ecc58136895efb"}, - {file = "bitarray-3.6.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a50a66fa34dd7f9dcdbc7602a1b7bf6f9ab030b4f43e892324193423d9ede180"}, - {file = "bitarray-3.6.0-cp313-cp313-win32.whl", hash = "sha256:afa24e5750c9b89ad5a7efef037efe49f4e339f20a94bf678c422c0c71e1207a"}, - {file = "bitarray-3.6.0-cp313-cp313-win_amd64.whl", hash = "sha256:e4c5e7edf1e7bcbde3b52058f171a411e2a24a081b3e951d685dfea4c3c383d5"}, - {file = "bitarray-3.6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:fefd18b29f3b84a0cdea1d86340219d9871c3b0673a38e722a73a2c39591eaa7"}, - {file = "bitarray-3.6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:679856547f0b27b98811b73756bdf53769c23b045a6f95177cae634daabf1ddf"}, - {file = "bitarray-3.6.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:51947a00ae9924584fb14c0c1b1f4c1fd916d9abd6f47582f318ab9c9cb9f3d0"}, - {file = "bitarray-3.6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0956322bf4d5e2293e57600aa929c241edf1e209e94e12483bf58c5c691432db"}, - {file = "bitarray-3.6.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3b521e117ab991d6b3b830656f464b354a42dbea2ca16a0e7d93d573f7ab7ff"}, - {file = "bitarray-3.6.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27eeee915258b105a21a4b0f8aebc5f77bb4dc4fb4063a09dd329fa1fdcbd234"}, - {file = "bitarray-3.6.0-cp36-cp36m-musllinux_1_2_aarch64.whl", hash = "sha256:f738051052abc95dc17f9a4c92044294a263fb7f762efdb13e528d419005c0e4"}, - {file = "bitarray-3.6.0-cp36-cp36m-musllinux_1_2_i686.whl", hash = "sha256:1971050b447023288a2b694a03b400bd5163829cd67b10f19e757fe87cd1161e"}, - {file = "bitarray-3.6.0-cp36-cp36m-musllinux_1_2_ppc64le.whl", hash = "sha256:a290a417608f50137bec731d1f22ff3efebac72845530807a8433b2db9358c95"}, - {file = "bitarray-3.6.0-cp36-cp36m-musllinux_1_2_s390x.whl", hash = "sha256:8ef3f0977c21190f949d5cfd71ded09de87d330c6d98bd5ecb5bb1135d666d0d"}, - {file = "bitarray-3.6.0-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:357e07c827bad01f98d0bd0dfdc722f483febeed39140fd75ffd016a451b60b9"}, - {file = "bitarray-3.6.0-cp36-cp36m-win32.whl", hash = "sha256:bdd6412c1f38da7565126b174f4e644f362e317ef0560fac1fb9d0c70900ff4d"}, - {file = "bitarray-3.6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:a1b3c4ca3bec8e0ad9d32ce62444c5f3913588124a922629aa7d39357b2adf3f"}, - {file = "bitarray-3.6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:531e6dfec8058fcf5d69e863b61e6b28e3749b615a4dcc0ab8ad36307c4017fc"}, - {file = "bitarray-3.6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a6f9e897907757e9c2d722ae6c203d48a04826a14e1495e33935c8583c163a9"}, - {file = "bitarray-3.6.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c9f36055a89b9517db66eb8e80137126bf629c767ceeade4d004e40bc8bcd99"}, - {file = "bitarray-3.6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d6f3a94abd8b44b2bf346ca81ab2ff41ab9146c53905eedf5178b19d9fe53bf"}, - {file = "bitarray-3.6.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79db23eda81627132327ed292bd813a9af64399b98aaac3d42ad8deeed24cd5e"}, - {file = "bitarray-3.6.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8d6c9bc14bacdfbfd51fed85f0576973eaaa7b30d81ef93264f8e22b86a9c9f7"}, - {file = "bitarray-3.6.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:60408ec9c0bd76f1fa00d28034429a0316246d31069b982a86aec8d5c99e910a"}, - {file = "bitarray-3.6.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:870ed23361e2918ab1ffc23fe0ab293abf3c372a68ee7387456d13da3e213008"}, - {file = "bitarray-3.6.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:c677849947d523a082be6e0b5c9137f443a54e951a1711ef003ec52910c41ece"}, - {file = "bitarray-3.6.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:a5ce1bdee102f7e60c075274df10b892d9ff5183ad6f5f515973eda8903dfe4c"}, - {file = "bitarray-3.6.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:a33f7c5acf44961f29018b13f0b5f5e1589ac0cfdf75a97c9774cf7ec84d09e0"}, - {file = "bitarray-3.6.0-cp37-cp37m-win32.whl", hash = "sha256:16d0edab54bb9d214319418f65bd15cfc4210ec41a16c3dd0b71e626c803212d"}, - {file = "bitarray-3.6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:f76784355060999c36fa807b59faecb38f5769ae58283d00270835773f95e35b"}, - {file = "bitarray-3.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cc060bc17b9de27874997d612e37d52f72092f9b59d1e04284a90ed8113cadca"}, - {file = "bitarray-3.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bfc417e58f277e949ed662d9cd050ddbb00c0dea8a828abaccc93dc357b7a6d1"}, - {file = "bitarray-3.6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:129165b68a3e0c2a633ed0d8557cf5ade24a0b37ca97d7805fa6fc5fb73c19d5"}, - {file = "bitarray-3.6.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50d702149747852923be60cae125285eca8d189d4c7d8832c0c958d4071a0f78"}, - {file = "bitarray-3.6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ccf4a73e07bfbd790443d6b3c1f1447ffda23cc9391e40c035d9b7d3514b57b8"}, - {file = "bitarray-3.6.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f7d2dbe628f3db935622a5b80a5c4d95665cdefc4904372aa3c4d786289477f"}, - {file = "bitarray-3.6.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5da4939e241301f5e1d18118695e8d2c300be90431b66bd43a00376acec45e1e"}, - {file = "bitarray-3.6.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:9930853d451086c4c084d83a87294bdb0c5bc0fa4105a26c487ac09ea62e565b"}, - {file = "bitarray-3.6.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:e0e4fdeae6c0a9d886749780ec5dcf469e98f27b312efa93008d03eaa2426fd5"}, - {file = "bitarray-3.6.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:79ab1c5f26f23e51d4a44c4397c8a3bf56c306c125dfab6b3eebdfa13d1dca6f"}, - {file = "bitarray-3.6.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:b9a03767c937b621ee267507bc394df97fb2f8f61130f39f2033f3c6c191f124"}, - {file = "bitarray-3.6.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:54bd71f14a5fa9bae73ef92f2e2be894dc36c7a6d1c4962e5969bd8a9aa39325"}, - {file = "bitarray-3.6.0-cp38-cp38-win32.whl", hash = "sha256:7e0851a985a7b10f634188117c825ef99d63402555cca5bc32c7bfc5adaf0d6f"}, - {file = "bitarray-3.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:00628196dd3592972a5183194ab1475dadf9ef2a4cf3fd8c7c184a94934012e8"}, - {file = "bitarray-3.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:69d2d507c1174330c71c834b5d65e66181ad7b42b0d88b5b31804ee9b4f5dae7"}, - {file = "bitarray-3.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:727f7a969416f02ef5c1256541e06f0836fb615022699fa8e2591e85296c5570"}, - {file = "bitarray-3.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42622c42c159ea4535bba7e1e3c97f1fec79505bc6873ae657dc0a8f861c60de"}, - {file = "bitarray-3.6.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7f8b12424f8fdf29d1c0749c628bd1530cecfc77374935d096cccc0e4eada232"}, - {file = "bitarray-3.6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:963cbcf296943f7017470d0b705e63e908f32b4f7dbe43f72c22f6fe1bd9ef66"}, - {file = "bitarray-3.6.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e304f94c0353f6ae5711533b5793b3a45b17aa2c5b07e656649b0af4e0939b5"}, - {file = "bitarray-3.6.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2c533c828d0007fac27cf45e5c1a711e5914dd469db5fe6be5f4e606bf2d7f63"}, - {file = "bitarray-3.6.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:220d4b8649ef54ac98e5e0e3dd92230247f67270d1524a8b31aa9859007affb0"}, - {file = "bitarray-3.6.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:407920e9318d94cc6c9611aaa5b5e5963a09f1cbfa17b16b66edea453b3754f4"}, - {file = "bitarray-3.6.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:056fe779f01a867d572e071c0944ac2f3bf58d8bced326040f0bd060af33a209"}, - {file = "bitarray-3.6.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ca87f639094c72268e17bc7f57c1225cc38f9e191a489a0134762e3fec402c1a"}, - {file = "bitarray-3.6.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b5ad8261f47c2a72d0f676bc40f752db8cfdcab911e970753343836e41d5a9a7"}, - {file = "bitarray-3.6.0-cp39-cp39-win32.whl", hash = "sha256:a773199dc42b5d02fcd46c8add552da2c4725ce2caa069527c7e27b5b6089e85"}, - {file = "bitarray-3.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:157313a124287cbc8a11b55a75def0dd59e68badbc82c2dc2d204dc852742874"}, - {file = "bitarray-3.6.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a763dd33d6e27c9b4db3f8089a5fa39179a8a3cf48ce702b24a857d7c621333c"}, - {file = "bitarray-3.6.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8cf44b012e7493127ce7ca6e469138ac96b3295a117877d5469aabe7c8728d87"}, - {file = "bitarray-3.6.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e297fd2e58afe17e33dd80c231c3a9d850279a2a8625aed1d39f9be9534809e"}, - {file = "bitarray-3.6.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11fc8bc65f964c7278deb1b7a69379dab3ecc90095f252deb17365637ebb274d"}, - {file = "bitarray-3.6.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa3c925502bd0b957a96a5619134bcdc0382ef73cffd40bad218ced3586bcf8d"}, - {file = "bitarray-3.6.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9f7796959c9c036a115d34696563f75d4a2912d3b97c15c15f2a36bdd5496ce9"}, - {file = "bitarray-3.6.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b02cc1cac9099c0ec72da09593e7fadb1b6cf88a101acc8153592c700d732d80"}, - {file = "bitarray-3.6.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26691454a6770628882b68fe74e9f84ca2a51512edd49cbb025b14df5a9dd85a"}, - {file = "bitarray-3.6.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a5b0d277087a5bf261a607fc6ff4aaffcf80b300cd19b7a1e9754a4649f5fd4"}, - {file = "bitarray-3.6.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:af670708e145b048ead87375b899229443f2d0b4af2d1450d7701c74cd932b03"}, - {file = "bitarray-3.6.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:aeb6db2f4ab54ac21a3851d05130a2aa78a6f6a5f14003f9ae3114fb8b210850"}, - {file = "bitarray-3.6.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:99d16862e802e7c50c3b6cdd1bf041b6142335c9c2b426631f731257adfe5a15"}, - {file = "bitarray-3.6.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:66d8b7a89fac6042f7df9ea97d97ed0f5e404281110a882e3babd909161f85b6"}, - {file = "bitarray-3.6.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62f71b268f14ee6cc3045b95441bfe0518cef1d0b2ffbc6f3e9758f786ff5a03"}, - {file = "bitarray-3.6.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72760411d60d8d76979a20ed3f15586d824db04668b581b86e61158c2b616db0"}, - {file = "bitarray-3.6.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbc5029c61f9ebb2d4c247f13584a0ef0e8e49abb13e56460310821aca3ffcaf"}, - {file = "bitarray-3.6.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:0ac446f557eb28e3f7c65372608810ff073840627e9037e22ed10bd081793a34"}, - {file = "bitarray-3.6.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b9ae0008cff25e154ef1e3975a1705d344e844ffdeb34c25b007fd48c876e95d"}, - {file = "bitarray-3.6.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:db78cc5c03b446a43413165aa873e2f408e9fd5ddb45533e7bd3b638bace867c"}, - {file = "bitarray-3.6.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cfbdccddaa0ff07789e9e180db127906c676e479e05c04830cd458945de3511"}, - {file = "bitarray-3.6.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:222cb27ff05bc0aec72498d075dba1facec49a76a7da45740690cebbe3e81e43"}, - {file = "bitarray-3.6.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b58a672ec448fb36839a5fc7bf2b2f60df9a97b872d8bd6ca1a28da6126f5c7"}, - {file = "bitarray-3.6.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b37c9ea942395de029be270f0eca8c141eb14e8455941495cd3b6f95bbe465f4"}, - {file = "bitarray-3.6.0.tar.gz", hash = "sha256:20febc849a1f858e6a57a7d47b323fe9e727c579ddd526d317ad8831748a66a8"}, -] - -[[package]] -name = "certifi" -version = "2025.8.3" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.7" -groups = ["dev"] -files = [ - {file = "certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5"}, - {file = "certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407"}, -] - -[[package]] -name = "charset-normalizer" -version = "3.4.2" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7" -groups = ["dev"] -files = [ - {file = "charset_normalizer-3.4.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7c48ed483eb946e6c04ccbe02c6b4d1d48e51944b6db70f697e089c193404941"}, - {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2d318c11350e10662026ad0eb71bb51c7812fc8590825304ae0bdd4ac283acd"}, - {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9cbfacf36cb0ec2897ce0ebc5d08ca44213af24265bd56eca54bee7923c48fd6"}, - {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18dd2e350387c87dabe711b86f83c9c78af772c748904d372ade190b5c7c9d4d"}, - {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8075c35cd58273fee266c58c0c9b670947c19df5fb98e7b66710e04ad4e9ff86"}, - {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5bf4545e3b962767e5c06fe1738f951f77d27967cb2caa64c28be7c4563e162c"}, - {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7a6ab32f7210554a96cd9e33abe3ddd86732beeafc7a28e9955cdf22ffadbab0"}, - {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b33de11b92e9f75a2b545d6e9b6f37e398d86c3e9e9653c4864eb7e89c5773ef"}, - {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8755483f3c00d6c9a77f490c17e6ab0c8729e39e6390328e42521ef175380ae6"}, - {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:68a328e5f55ec37c57f19ebb1fdc56a248db2e3e9ad769919a58672958e8f366"}, - {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:21b2899062867b0e1fde9b724f8aecb1af14f2778d69aacd1a5a1853a597a5db"}, - {file = "charset_normalizer-3.4.2-cp310-cp310-win32.whl", hash = "sha256:e8082b26888e2f8b36a042a58307d5b917ef2b1cacab921ad3323ef91901c71a"}, - {file = "charset_normalizer-3.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:f69a27e45c43520f5487f27627059b64aaf160415589230992cec34c5e18a509"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:be1e352acbe3c78727a16a455126d9ff83ea2dfdcbc83148d2982305a04714c2"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa88ca0b1932e93f2d961bf3addbb2db902198dca337d88c89e1559e066e7645"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d524ba3f1581b35c03cb42beebab4a13e6cdad7b36246bd22541fa585a56cccd"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28a1005facc94196e1fb3e82a3d442a9d9110b8434fc1ded7a24a2983c9888d8"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdb20a30fe1175ecabed17cbf7812f7b804b8a315a25f24678bcdf120a90077f"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f5d9ed7f254402c9e7d35d2f5972c9bbea9040e99cd2861bd77dc68263277c7"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:efd387a49825780ff861998cd959767800d54f8308936b21025326de4b5a42b9"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f0aa37f3c979cf2546b73e8222bbfa3dc07a641585340179d768068e3455e544"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e70e990b2137b29dc5564715de1e12701815dacc1d056308e2b17e9095372a82"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0c8c57f84ccfc871a48a47321cfa49ae1df56cd1d965a09abe84066f6853b9c0"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6b66f92b17849b85cad91259efc341dce9c1af48e2173bf38a85c6329f1033e5"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-win32.whl", hash = "sha256:daac4765328a919a805fa5e2720f3e94767abd632ae410a9062dff5412bae65a"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:e53efc7c7cee4c1e70661e2e112ca46a575f90ed9ae3fef200f2a25e954f4b28"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0c29de6a1a95f24b9a1aa7aefd27d2487263f00dfd55a77719b530788f75cff7"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cddf7bd982eaa998934a91f69d182aec997c6c468898efe6679af88283b498d3"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcbe676a55d7445b22c10967bceaaf0ee69407fbe0ece4d032b6eb8d4565982a"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d41c4d287cfc69060fa91cae9683eacffad989f1a10811995fa309df656ec214"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e594135de17ab3866138f496755f302b72157d115086d100c3f19370839dd3a"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf713fe9a71ef6fd5adf7a79670135081cd4431c2943864757f0fa3a65b1fafd"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a370b3e078e418187da8c3674eddb9d983ec09445c99a3a263c2011993522981"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a955b438e62efdf7e0b7b52a64dc5c3396e2634baa62471768a64bc2adb73d5c"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7222ffd5e4de8e57e03ce2cef95a4c43c98fcb72ad86909abdfc2c17d227fc1b"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:bee093bf902e1d8fc0ac143c88902c3dfc8941f7ea1d6a8dd2bcb786d33db03d"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb8adb91d11846ee08bec4c8236c8549ac721c245678282dcb06b221aab59f"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-win32.whl", hash = "sha256:db4c7bf0e07fc3b7d89ac2a5880a6a8062056801b83ff56d8464b70f65482b6c"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:5a9979887252a82fefd3d3ed2a8e3b937a7a809f65dcb1e068b090e165bbe99e"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:926ca93accd5d36ccdabd803392ddc3e03e6d4cd1cf17deff3b989ab8e9dbcf0"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eba9904b0f38a143592d9fc0e19e2df0fa2e41c3c3745554761c5f6447eedabf"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3fddb7e2c84ac87ac3a947cb4e66d143ca5863ef48e4a5ecb83bd48619e4634e"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98f862da73774290f251b9df8d11161b6cf25b599a66baf087c1ffe340e9bfd1"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c9379d65defcab82d07b2a9dfbfc2e95bc8fe0ebb1b176a3190230a3ef0e07c"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e635b87f01ebc977342e2697d05b56632f5f879a4f15955dfe8cef2448b51691"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1c95a1e2902a8b722868587c0e1184ad5c55631de5afc0eb96bc4b0d738092c0"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ef8de666d6179b009dce7bcb2ad4c4a779f113f12caf8dc77f0162c29d20490b"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:32fc0341d72e0f73f80acb0a2c94216bd704f4f0bce10aedea38f30502b271ff"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:289200a18fa698949d2b39c671c2cc7a24d44096784e76614899a7ccf2574b7b"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a476b06fbcf359ad25d34a057b7219281286ae2477cc5ff5e3f70a246971148"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-win32.whl", hash = "sha256:aaeeb6a479c7667fbe1099af9617c83aaca22182d6cf8c53966491a0f1b7ffb7"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:aa6af9e7d59f9c12b33ae4e9450619cf2488e2bbe9b44030905877f0b2324980"}, - {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cad5f45b3146325bb38d6855642f6fd609c3f7cad4dbaf75549bf3b904d3184"}, - {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2680962a4848b3c4f155dc2ee64505a9c57186d0d56b43123b17ca3de18f0fa"}, - {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:36b31da18b8890a76ec181c3cf44326bf2c48e36d393ca1b72b3f484113ea344"}, - {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4074c5a429281bf056ddd4c5d3b740ebca4d43ffffe2ef4bf4d2d05114299da"}, - {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9e36a97bee9b86ef9a1cf7bb96747eb7a15c2f22bdb5b516434b00f2a599f02"}, - {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:1b1bde144d98e446b056ef98e59c256e9294f6b74d7af6846bf5ffdafd687a7d"}, - {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:915f3849a011c1f593ab99092f3cecfcb4d65d8feb4a64cf1bf2d22074dc0ec4"}, - {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:fb707f3e15060adf5b7ada797624a6c6e0138e2a26baa089df64c68ee98e040f"}, - {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:25a23ea5c7edc53e0f29bae2c44fcb5a1aa10591aae107f2a2b2583a9c5cbc64"}, - {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:770cab594ecf99ae64c236bc9ee3439c3f46be49796e265ce0cc8bc17b10294f"}, - {file = "charset_normalizer-3.4.2-cp37-cp37m-win32.whl", hash = "sha256:6a0289e4589e8bdfef02a80478f1dfcb14f0ab696b5a00e1f4b8a14a307a3c58"}, - {file = "charset_normalizer-3.4.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6fc1f5b51fa4cecaa18f2bd7a003f3dd039dd615cd69a2afd6d3b19aed6775f2"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:76af085e67e56c8816c3ccf256ebd136def2ed9654525348cfa744b6802b69eb"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e45ba65510e2647721e35323d6ef54c7974959f6081b58d4ef5d87c60c84919a"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:046595208aae0120559a67693ecc65dd75d46f7bf687f159127046628178dc45"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75d10d37a47afee94919c4fab4c22b9bc2a8bf7d4f46f87363bcf0573f3ff4f5"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6333b3aa5a12c26b2a4d4e7335a28f1475e0e5e17d69d55141ee3cab736f66d1"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8323a9b031aa0393768b87f04b4164a40037fb2a3c11ac06a03ffecd3618027"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:24498ba8ed6c2e0b56d4acbf83f2d989720a93b41d712ebd4f4979660db4417b"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:844da2b5728b5ce0e32d863af26f32b5ce61bc4273a9c720a9f3aa9df73b1455"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:65c981bdbd3f57670af8b59777cbfae75364b483fa8a9f420f08094531d54a01"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:3c21d4fca343c805a52c0c78edc01e3477f6dd1ad7c47653241cf2a206d4fc58"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:dc7039885fa1baf9be153a0626e337aa7ec8bf96b0128605fb0d77788ddc1681"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-win32.whl", hash = "sha256:8272b73e1c5603666618805fe821edba66892e2870058c94c53147602eab29c7"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:70f7172939fdf8790425ba31915bfbe8335030f05b9913d7ae00a87d4395620a"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:005fa3432484527f9732ebd315da8da8001593e2cf46a3d817669f062c3d9ed4"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e92fca20c46e9f5e1bb485887d074918b13543b1c2a1185e69bb8d17ab6236a7"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50bf98d5e563b83cc29471fa114366e6806bc06bc7a25fd59641e41445327836"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:721c76e84fe669be19c5791da68232ca2e05ba5185575086e384352e2c309597"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82d8fd25b7f4675d0c47cf95b594d4e7b158aca33b76aa63d07186e13c0e0ab7"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3daeac64d5b371dea99714f08ffc2c208522ec6b06fbc7866a450dd446f5c0f"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dccab8d5fa1ef9bfba0590ecf4d46df048d18ffe3eec01eeb73a42e0d9e7a8ba"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:aaf27faa992bfee0264dc1f03f4c75e9fcdda66a519db6b957a3f826e285cf12"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:eb30abc20df9ab0814b5a2524f23d75dcf83cde762c161917a2b4b7b55b1e518"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:c72fbbe68c6f32f251bdc08b8611c7b3060612236e960ef848e0a517ddbe76c5"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:982bb1e8b4ffda883b3d0a521e23abcd6fd17418f6d2c4118d257a10199c0ce3"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-win32.whl", hash = "sha256:43e0933a0eff183ee85833f341ec567c0980dae57c464d8a508e1b2ceb336471"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:d11b54acf878eef558599658b0ffca78138c8c3655cf4f3a4a673c437e67732e"}, - {file = "charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0"}, - {file = "charset_normalizer-3.4.2.tar.gz", hash = "sha256:5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63"}, -] - -[[package]] -name = "click" -version = "8.2.1" -description = "Composable command line interface toolkit" -optional = false -python-versions = ">=3.10" -groups = ["main", "dev"] -files = [ - {file = "click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b"}, - {file = "click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -groups = ["main", "dev"] -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] -markers = {main = "platform_system == \"Windows\""} - -[[package]] -name = "docutils" -version = "0.21.2" -description = "Docutils -- Python Documentation Utilities" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2"}, - {file = "docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f"}, -] - -[[package]] -name = "idna" -version = "3.10" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.6" -groups = ["dev"] -files = [ - {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, - {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, -] - -[package.extras] -all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] - -[[package]] -name = "imagesize" -version = "1.4.1" -description = "Getting image size from png/jpeg/jpeg2000/gif file" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -groups = ["dev"] -files = [ - {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, - {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, -] - -[[package]] -name = "iniconfig" -version = "2.1.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"}, - {file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"}, -] - -[[package]] -name = "jinja2" -version = "3.1.6" -description = "A very fast and expressive template engine." -optional = false -python-versions = ">=3.7" -groups = ["main", "dev"] -files = [ - {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"}, - {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"}, -] - -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - -[[package]] -name = "joblib" -version = "1.5.1" -description = "Lightweight pipelining with Python functions" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "joblib-1.5.1-py3-none-any.whl", hash = "sha256:4719a31f054c7d766948dcd83e9613686b27114f190f717cec7eaa2084f8a74a"}, - {file = "joblib-1.5.1.tar.gz", hash = "sha256:f4f86e351f39fe3d0d32a9f2c3d8af1ee4cec285aafcb27003dda5205576b444"}, -] - -[[package]] -name = "markdown-it-py" -version = "3.0.0" -description = "Python port of markdown-it. Markdown parsing, done right!" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, - {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, -] - -[package.dependencies] -mdurl = ">=0.1,<1.0" - -[package.extras] -benchmarking = ["psutil", "pytest", "pytest-benchmark"] -code-style = ["pre-commit (>=3.0,<4.0)"] -compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] -linkify = ["linkify-it-py (>=1,<3)"] -plugins = ["mdit-py-plugins"] -profiling = ["gprof2dot"] -rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] -testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] - -[[package]] -name = "markupsafe" -version = "3.0.2" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.9" -groups = ["main", "dev"] -files = [ - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, - {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, -] - -[[package]] -name = "mdit-py-plugins" -version = "0.4.2" -description = "Collection of plugins for markdown-it-py" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "mdit_py_plugins-0.4.2-py3-none-any.whl", hash = "sha256:0c673c3f889399a33b95e88d2f0d111b4447bdfea7f237dab2d488f459835636"}, - {file = "mdit_py_plugins-0.4.2.tar.gz", hash = "sha256:5f2cd1fdb606ddf152d37ec30e46101a60512bc0e5fa1a7002c36647b09e26b5"}, -] - -[package.dependencies] -markdown-it-py = ">=1.0.0,<4.0.0" - -[package.extras] -code-style = ["pre-commit"] -rtd = ["myst-parser", "sphinx-book-theme"] -testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] - -[[package]] -name = "mdurl" -version = "0.1.2" -description = "Markdown URL utilities" -optional = false -python-versions = ">=3.7" -groups = ["dev"] -files = [ - {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, - {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, -] - -[[package]] -name = "mslex" -version = "1.3.0" -description = "shlex for windows" -optional = false -python-versions = ">=3.5" -groups = ["dev"] -markers = "sys_platform == \"win32\"" -files = [ - {file = "mslex-1.3.0-py3-none-any.whl", hash = "sha256:c7074b347201b3466fc077c5692fbce9b5f62a63a51f537a53fbbd02eff2eea4"}, - {file = "mslex-1.3.0.tar.gz", hash = "sha256:641c887d1d3db610eee2af37a8e5abda3f70b3006cdfd2d0d29dc0d1ae28a85d"}, -] - -[[package]] -name = "mypy" -version = "1.17.1" -description = "Optional static typing for Python" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "mypy-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3fbe6d5555bf608c47203baa3e72dbc6ec9965b3d7c318aa9a4ca76f465bd972"}, - {file = "mypy-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:80ef5c058b7bce08c83cac668158cb7edea692e458d21098c7d3bce35a5d43e7"}, - {file = "mypy-1.17.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4a580f8a70c69e4a75587bd925d298434057fe2a428faaf927ffe6e4b9a98df"}, - {file = "mypy-1.17.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dd86bb649299f09d987a2eebb4d52d10603224500792e1bee18303bbcc1ce390"}, - {file = "mypy-1.17.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a76906f26bd8d51ea9504966a9c25419f2e668f012e0bdf3da4ea1526c534d94"}, - {file = "mypy-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:e79311f2d904ccb59787477b7bd5d26f3347789c06fcd7656fa500875290264b"}, - {file = "mypy-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ad37544be07c5d7fba814eb370e006df58fed8ad1ef33ed1649cb1889ba6ff58"}, - {file = "mypy-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:064e2ff508e5464b4bd807a7c1625bc5047c5022b85c70f030680e18f37273a5"}, - {file = "mypy-1.17.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70401bbabd2fa1aa7c43bb358f54037baf0586f41e83b0ae67dd0534fc64edfd"}, - {file = "mypy-1.17.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e92bdc656b7757c438660f775f872a669b8ff374edc4d18277d86b63edba6b8b"}, - {file = "mypy-1.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c1fdf4abb29ed1cb091cf432979e162c208a5ac676ce35010373ff29247bcad5"}, - {file = "mypy-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:ff2933428516ab63f961644bc49bc4cbe42bbffb2cd3b71cc7277c07d16b1a8b"}, - {file = "mypy-1.17.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:69e83ea6553a3ba79c08c6e15dbd9bfa912ec1e493bf75489ef93beb65209aeb"}, - {file = "mypy-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1b16708a66d38abb1e6b5702f5c2c87e133289da36f6a1d15f6a5221085c6403"}, - {file = "mypy-1.17.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:89e972c0035e9e05823907ad5398c5a73b9f47a002b22359b177d40bdaee7056"}, - {file = "mypy-1.17.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:03b6d0ed2b188e35ee6d5c36b5580cffd6da23319991c49ab5556c023ccf1341"}, - {file = "mypy-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c837b896b37cd103570d776bda106eabb8737aa6dd4f248451aecf53030cdbeb"}, - {file = "mypy-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:665afab0963a4b39dff7c1fa563cc8b11ecff7910206db4b2e64dd1ba25aed19"}, - {file = "mypy-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93378d3203a5c0800c6b6d850ad2f19f7a3cdf1a3701d3416dbf128805c6a6a7"}, - {file = "mypy-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:15d54056f7fe7a826d897789f53dd6377ec2ea8ba6f776dc83c2902b899fee81"}, - {file = "mypy-1.17.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:209a58fed9987eccc20f2ca94afe7257a8f46eb5df1fb69958650973230f91e6"}, - {file = "mypy-1.17.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:099b9a5da47de9e2cb5165e581f158e854d9e19d2e96b6698c0d64de911dd849"}, - {file = "mypy-1.17.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa6ffadfbe6994d724c5a1bb6123a7d27dd68fc9c059561cd33b664a79578e14"}, - {file = "mypy-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:9a2b7d9180aed171f033c9f2fc6c204c1245cf60b0cb61cf2e7acc24eea78e0a"}, - {file = "mypy-1.17.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:15a83369400454c41ed3a118e0cc58bd8123921a602f385cb6d6ea5df050c733"}, - {file = "mypy-1.17.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:55b918670f692fc9fba55c3298d8a3beae295c5cded0a55dccdc5bbead814acd"}, - {file = "mypy-1.17.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:62761474061feef6f720149d7ba876122007ddc64adff5ba6f374fda35a018a0"}, - {file = "mypy-1.17.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c49562d3d908fd49ed0938e5423daed8d407774a479b595b143a3d7f87cdae6a"}, - {file = "mypy-1.17.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:397fba5d7616a5bc60b45c7ed204717eaddc38f826e3645402c426057ead9a91"}, - {file = "mypy-1.17.1-cp314-cp314-win_amd64.whl", hash = "sha256:9d6b20b97d373f41617bd0708fd46aa656059af57f2ef72aa8c7d6a2b73b74ed"}, - {file = "mypy-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5d1092694f166a7e56c805caaf794e0585cabdbf1df36911c414e4e9abb62ae9"}, - {file = "mypy-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:79d44f9bfb004941ebb0abe8eff6504223a9c1ac51ef967d1263c6572bbebc99"}, - {file = "mypy-1.17.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b01586eed696ec905e61bd2568f48740f7ac4a45b3a468e6423a03d3788a51a8"}, - {file = "mypy-1.17.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43808d9476c36b927fbcd0b0255ce75efe1b68a080154a38ae68a7e62de8f0f8"}, - {file = "mypy-1.17.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:feb8cc32d319edd5859da2cc084493b3e2ce5e49a946377663cc90f6c15fb259"}, - {file = "mypy-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d7598cf74c3e16539d4e2f0b8d8c318e00041553d83d4861f87c7a72e95ac24d"}, - {file = "mypy-1.17.1-py3-none-any.whl", hash = "sha256:a9f52c0351c21fe24c21d8c0eb1f62967b262d6729393397b6f443c3b773c3b9"}, - {file = "mypy-1.17.1.tar.gz", hash = "sha256:25e01ec741ab5bb3eec8ba9cdb0f769230368a22c959c4937360efb89b7e9f01"}, -] - -[package.dependencies] -mypy_extensions = ">=1.0.0" -pathspec = ">=0.9.0" -typing_extensions = ">=4.6.0" - -[package.extras] -dmypy = ["psutil (>=4.0)"] -faster-cache = ["orjson"] -install-types = ["pip"] -mypyc = ["setuptools (>=50)"] -reports = ["lxml"] - -[[package]] -name = "mypy-extensions" -version = "1.1.0" -description = "Type system extensions for programs checked with the mypy type checker." -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"}, - {file = "mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558"}, -] - -[[package]] -name = "myst-parser" -version = "4.0.1" -description = "An extended [CommonMark](https://spec.commonmark.org/) compliant parser," -optional = false -python-versions = ">=3.10" -groups = ["dev"] -files = [ - {file = "myst_parser-4.0.1-py3-none-any.whl", hash = "sha256:9134e88959ec3b5780aedf8a99680ea242869d012e8821db3126d427edc9c95d"}, - {file = "myst_parser-4.0.1.tar.gz", hash = "sha256:5cfea715e4f3574138aecbf7d54132296bfd72bb614d31168f48c477a830a7c4"}, -] - -[package.dependencies] -docutils = ">=0.19,<0.22" -jinja2 = "*" -markdown-it-py = ">=3.0,<4.0" -mdit-py-plugins = ">=0.4.1,<1.0" -pyyaml = "*" -sphinx = ">=7,<9" - -[package.extras] -code-style = ["pre-commit (>=4.0,<5.0)"] -linkify = ["linkify-it-py (>=2.0,<3.0)"] -rtd = ["ipython", "sphinx (>=7)", "sphinx-autodoc2 (>=0.5.0,<0.6.0)", "sphinx-book-theme (>=1.1,<2.0)", "sphinx-copybutton", "sphinx-design", "sphinx-pyscript", "sphinx-tippy (>=0.4.3)", "sphinx-togglebutton", "sphinxext-opengraph (>=0.9.0,<0.10.0)", "sphinxext-rediraffe (>=0.2.7,<0.3.0)"] -testing = ["beautifulsoup4", "coverage[toml]", "defusedxml", "pygments (<2.19)", "pytest (>=8,<9)", "pytest-cov", "pytest-param-files (>=0.6.0,<0.7.0)", "pytest-regressions", "sphinx-pytest"] -testing-docutils = ["pygments", "pytest (>=8,<9)", "pytest-param-files (>=0.6.0,<0.7.0)"] - -[[package]] -name = "numpy" -version = "2.3.2" -description = "Fundamental package for array computing in Python" -optional = false -python-versions = ">=3.11" -groups = ["main"] -files = [ - {file = "numpy-2.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:852ae5bed3478b92f093e30f785c98e0cb62fa0a939ed057c31716e18a7a22b9"}, - {file = "numpy-2.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7a0e27186e781a69959d0230dd9909b5e26024f8da10683bd6344baea1885168"}, - {file = "numpy-2.3.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:f0a1a8476ad77a228e41619af2fa9505cf69df928e9aaa165746584ea17fed2b"}, - {file = "numpy-2.3.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:cbc95b3813920145032412f7e33d12080f11dc776262df1712e1638207dde9e8"}, - {file = "numpy-2.3.2-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f75018be4980a7324edc5930fe39aa391d5734531b1926968605416ff58c332d"}, - {file = "numpy-2.3.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20b8200721840f5621b7bd03f8dcd78de33ec522fc40dc2641aa09537df010c3"}, - {file = "numpy-2.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f91e5c028504660d606340a084db4b216567ded1056ea2b4be4f9d10b67197f"}, - {file = "numpy-2.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:fb1752a3bb9a3ad2d6b090b88a9a0ae1cd6f004ef95f75825e2f382c183b2097"}, - {file = "numpy-2.3.2-cp311-cp311-win32.whl", hash = "sha256:4ae6863868aaee2f57503c7a5052b3a2807cf7a3914475e637a0ecd366ced220"}, - {file = "numpy-2.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:240259d6564f1c65424bcd10f435145a7644a65a6811cfc3201c4a429ba79170"}, - {file = "numpy-2.3.2-cp311-cp311-win_arm64.whl", hash = "sha256:4209f874d45f921bde2cff1ffcd8a3695f545ad2ffbef6d3d3c6768162efab89"}, - {file = "numpy-2.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bc3186bea41fae9d8e90c2b4fb5f0a1f5a690682da79b92574d63f56b529080b"}, - {file = "numpy-2.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f4f0215edb189048a3c03bd5b19345bdfa7b45a7a6f72ae5945d2a28272727f"}, - {file = "numpy-2.3.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:8b1224a734cd509f70816455c3cffe13a4f599b1bf7130f913ba0e2c0b2006c0"}, - {file = "numpy-2.3.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:3dcf02866b977a38ba3ec10215220609ab9667378a9e2150615673f3ffd6c73b"}, - {file = "numpy-2.3.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:572d5512df5470f50ada8d1972c5f1082d9a0b7aa5944db8084077570cf98370"}, - {file = "numpy-2.3.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8145dd6d10df13c559d1e4314df29695613575183fa2e2d11fac4c208c8a1f73"}, - {file = "numpy-2.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:103ea7063fa624af04a791c39f97070bf93b96d7af7eb23530cd087dc8dbe9dc"}, - {file = "numpy-2.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fc927d7f289d14f5e037be917539620603294454130b6de200091e23d27dc9be"}, - {file = "numpy-2.3.2-cp312-cp312-win32.whl", hash = "sha256:d95f59afe7f808c103be692175008bab926b59309ade3e6d25009e9a171f7036"}, - {file = "numpy-2.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:9e196ade2400c0c737d93465327d1ae7c06c7cb8a1756121ebf54b06ca183c7f"}, - {file = "numpy-2.3.2-cp312-cp312-win_arm64.whl", hash = "sha256:ee807923782faaf60d0d7331f5e86da7d5e3079e28b291973c545476c2b00d07"}, - {file = "numpy-2.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c8d9727f5316a256425892b043736d63e89ed15bbfe6556c5ff4d9d4448ff3b3"}, - {file = "numpy-2.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:efc81393f25f14d11c9d161e46e6ee348637c0a1e8a54bf9dedc472a3fae993b"}, - {file = "numpy-2.3.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:dd937f088a2df683cbb79dda9a772b62a3e5a8a7e76690612c2737f38c6ef1b6"}, - {file = "numpy-2.3.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:11e58218c0c46c80509186e460d79fbdc9ca1eb8d8aee39d8f2dc768eb781089"}, - {file = "numpy-2.3.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5ad4ebcb683a1f99f4f392cc522ee20a18b2bb12a2c1c42c3d48d5a1adc9d3d2"}, - {file = "numpy-2.3.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:938065908d1d869c7d75d8ec45f735a034771c6ea07088867f713d1cd3bbbe4f"}, - {file = "numpy-2.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:66459dccc65d8ec98cc7df61307b64bf9e08101f9598755d42d8ae65d9a7a6ee"}, - {file = "numpy-2.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a7af9ed2aa9ec5950daf05bb11abc4076a108bd3c7db9aa7251d5f107079b6a6"}, - {file = "numpy-2.3.2-cp313-cp313-win32.whl", hash = "sha256:906a30249315f9c8e17b085cc5f87d3f369b35fedd0051d4a84686967bdbbd0b"}, - {file = "numpy-2.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:c63d95dc9d67b676e9108fe0d2182987ccb0f11933c1e8959f42fa0da8d4fa56"}, - {file = "numpy-2.3.2-cp313-cp313-win_arm64.whl", hash = "sha256:b05a89f2fb84d21235f93de47129dd4f11c16f64c87c33f5e284e6a3a54e43f2"}, - {file = "numpy-2.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4e6ecfeddfa83b02318f4d84acf15fbdbf9ded18e46989a15a8b6995dfbf85ab"}, - {file = "numpy-2.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:508b0eada3eded10a3b55725b40806a4b855961040180028f52580c4729916a2"}, - {file = "numpy-2.3.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:754d6755d9a7588bdc6ac47dc4ee97867271b17cee39cb87aef079574366db0a"}, - {file = "numpy-2.3.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:a9f66e7d2b2d7712410d3bc5684149040ef5f19856f20277cd17ea83e5006286"}, - {file = "numpy-2.3.2-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de6ea4e5a65d5a90c7d286ddff2b87f3f4ad61faa3db8dabe936b34c2275b6f8"}, - {file = "numpy-2.3.2-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3ef07ec8cbc8fc9e369c8dcd52019510c12da4de81367d8b20bc692aa07573a"}, - {file = "numpy-2.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:27c9f90e7481275c7800dc9c24b7cc40ace3fdb970ae4d21eaff983a32f70c91"}, - {file = "numpy-2.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:07b62978075b67eee4065b166d000d457c82a1efe726cce608b9db9dd66a73a5"}, - {file = "numpy-2.3.2-cp313-cp313t-win32.whl", hash = "sha256:c771cfac34a4f2c0de8e8c97312d07d64fd8f8ed45bc9f5726a7e947270152b5"}, - {file = "numpy-2.3.2-cp313-cp313t-win_amd64.whl", hash = "sha256:72dbebb2dcc8305c431b2836bcc66af967df91be793d63a24e3d9b741374c450"}, - {file = "numpy-2.3.2-cp313-cp313t-win_arm64.whl", hash = "sha256:72c6df2267e926a6d5286b0a6d556ebe49eae261062059317837fda12ddf0c1a"}, - {file = "numpy-2.3.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:448a66d052d0cf14ce9865d159bfc403282c9bc7bb2a31b03cc18b651eca8b1a"}, - {file = "numpy-2.3.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:546aaf78e81b4081b2eba1d105c3b34064783027a06b3ab20b6eba21fb64132b"}, - {file = "numpy-2.3.2-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:87c930d52f45df092f7578889711a0768094debf73cfcde105e2d66954358125"}, - {file = "numpy-2.3.2-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:8dc082ea901a62edb8f59713c6a7e28a85daddcb67454c839de57656478f5b19"}, - {file = "numpy-2.3.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:af58de8745f7fa9ca1c0c7c943616c6fe28e75d0c81f5c295810e3c83b5be92f"}, - {file = "numpy-2.3.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed5527c4cf10f16c6d0b6bee1f89958bccb0ad2522c8cadc2efd318bcd545f5"}, - {file = "numpy-2.3.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:095737ed986e00393ec18ec0b21b47c22889ae4b0cd2d5e88342e08b01141f58"}, - {file = "numpy-2.3.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5e40e80299607f597e1a8a247ff8d71d79c5b52baa11cc1cce30aa92d2da6e0"}, - {file = "numpy-2.3.2-cp314-cp314-win32.whl", hash = "sha256:7d6e390423cc1f76e1b8108c9b6889d20a7a1f59d9a60cac4a050fa734d6c1e2"}, - {file = "numpy-2.3.2-cp314-cp314-win_amd64.whl", hash = "sha256:b9d0878b21e3918d76d2209c924ebb272340da1fb51abc00f986c258cd5e957b"}, - {file = "numpy-2.3.2-cp314-cp314-win_arm64.whl", hash = "sha256:2738534837c6a1d0c39340a190177d7d66fdf432894f469728da901f8f6dc910"}, - {file = "numpy-2.3.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:4d002ecf7c9b53240be3bb69d80f86ddbd34078bae04d87be81c1f58466f264e"}, - {file = "numpy-2.3.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:293b2192c6bcce487dbc6326de5853787f870aeb6c43f8f9c6496db5b1781e45"}, - {file = "numpy-2.3.2-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:0a4f2021a6da53a0d580d6ef5db29947025ae8b35b3250141805ea9a32bbe86b"}, - {file = "numpy-2.3.2-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:9c144440db4bf3bb6372d2c3e49834cc0ff7bb4c24975ab33e01199e645416f2"}, - {file = "numpy-2.3.2-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f92d6c2a8535dc4fe4419562294ff957f83a16ebdec66df0805e473ffaad8bd0"}, - {file = "numpy-2.3.2-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cefc2219baa48e468e3db7e706305fcd0c095534a192a08f31e98d83a7d45fb0"}, - {file = "numpy-2.3.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:76c3e9501ceb50b2ff3824c3589d5d1ab4ac857b0ee3f8f49629d0de55ecf7c2"}, - {file = "numpy-2.3.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:122bf5ed9a0221b3419672493878ba4967121514b1d7d4656a7580cd11dddcbf"}, - {file = "numpy-2.3.2-cp314-cp314t-win32.whl", hash = "sha256:6f1ae3dcb840edccc45af496f312528c15b1f79ac318169d094e85e4bb35fdf1"}, - {file = "numpy-2.3.2-cp314-cp314t-win_amd64.whl", hash = "sha256:087ffc25890d89a43536f75c5fe8770922008758e8eeeef61733957041ed2f9b"}, - {file = "numpy-2.3.2-cp314-cp314t-win_arm64.whl", hash = "sha256:092aeb3449833ea9c0bf0089d70c29ae480685dd2377ec9cdbbb620257f84631"}, - {file = "numpy-2.3.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:14a91ebac98813a49bc6aa1a0dfc09513dcec1d97eaf31ca21a87221a1cdcb15"}, - {file = "numpy-2.3.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:71669b5daae692189540cffc4c439468d35a3f84f0c88b078ecd94337f6cb0ec"}, - {file = "numpy-2.3.2-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:69779198d9caee6e547adb933941ed7520f896fd9656834c300bdf4dd8642712"}, - {file = "numpy-2.3.2-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:2c3271cc4097beb5a60f010bcc1cc204b300bb3eafb4399376418a83a1c6373c"}, - {file = "numpy-2.3.2-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8446acd11fe3dc1830568c941d44449fd5cb83068e5c70bd5a470d323d448296"}, - {file = "numpy-2.3.2-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aa098a5ab53fa407fded5870865c6275a5cd4101cfdef8d6fafc48286a96e981"}, - {file = "numpy-2.3.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:6936aff90dda378c09bea075af0d9c675fe3a977a9d2402f95a87f440f59f619"}, - {file = "numpy-2.3.2.tar.gz", hash = "sha256:e0486a11ec30cdecb53f184d496d1c6a20786c81e55e41640270130056f8ee48"}, -] - -[[package]] -name = "packaging" -version = "25.0" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, - {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, -] - -[[package]] -name = "pathspec" -version = "0.12.1" -description = "Utility library for gitignore style pattern matching of file paths." -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, - {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, -] - -[[package]] -name = "pluggy" -version = "1.6.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"}, - {file = "pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["coverage", "pytest", "pytest-benchmark"] - -[[package]] -name = "protobuf" -version = "6.31.1" -description = "" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "protobuf-6.31.1-cp310-abi3-win32.whl", hash = "sha256:7fa17d5a29c2e04b7d90e5e32388b8bfd0e7107cd8e616feef7ed3fa6bdab5c9"}, - {file = "protobuf-6.31.1-cp310-abi3-win_amd64.whl", hash = "sha256:426f59d2964864a1a366254fa703b8632dcec0790d8862d30034d8245e1cd447"}, - {file = "protobuf-6.31.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:6f1227473dc43d44ed644425268eb7c2e488ae245d51c6866d19fe158e207402"}, - {file = "protobuf-6.31.1-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:a40fc12b84c154884d7d4c4ebd675d5b3b5283e155f324049ae396b95ddebc39"}, - {file = "protobuf-6.31.1-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:4ee898bf66f7a8b0bd21bce523814e6fbd8c6add948045ce958b73af7e8878c6"}, - {file = "protobuf-6.31.1-cp39-cp39-win32.whl", hash = "sha256:0414e3aa5a5f3ff423828e1e6a6e907d6c65c1d5b7e6e975793d5590bdeecc16"}, - {file = "protobuf-6.31.1-cp39-cp39-win_amd64.whl", hash = "sha256:8764cf4587791e7564051b35524b72844f845ad0bb011704c3736cce762d8fe9"}, - {file = "protobuf-6.31.1-py3-none-any.whl", hash = "sha256:720a6c7e6b77288b85063569baae8536671b39f15cc22037ec7045658d80489e"}, - {file = "protobuf-6.31.1.tar.gz", hash = "sha256:d8cac4c982f0b957a4dc73a80e2ea24fab08e679c0de9deb835f4a12d69aca9a"}, -] - -[[package]] -name = "psutil" -version = "6.1.1" -description = "Cross-platform lib for process and system monitoring in Python." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" -groups = ["dev"] -files = [ - {file = "psutil-6.1.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:9ccc4316f24409159897799b83004cb1e24f9819b0dcf9c0b68bdcb6cefee6a8"}, - {file = "psutil-6.1.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ca9609c77ea3b8481ab005da74ed894035936223422dc591d6772b147421f777"}, - {file = "psutil-6.1.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:8df0178ba8a9e5bc84fed9cfa61d54601b371fbec5c8eebad27575f1e105c0d4"}, - {file = "psutil-6.1.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:1924e659d6c19c647e763e78670a05dbb7feaf44a0e9c94bf9e14dfc6ba50468"}, - {file = "psutil-6.1.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:018aeae2af92d943fdf1da6b58665124897cfc94faa2ca92098838f83e1b1bca"}, - {file = "psutil-6.1.1-cp27-none-win32.whl", hash = "sha256:6d4281f5bbca041e2292be3380ec56a9413b790579b8e593b1784499d0005dac"}, - {file = "psutil-6.1.1-cp27-none-win_amd64.whl", hash = "sha256:c777eb75bb33c47377c9af68f30e9f11bc78e0f07fbf907be4a5d70b2fe5f030"}, - {file = "psutil-6.1.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:fc0ed7fe2231a444fc219b9c42d0376e0a9a1a72f16c5cfa0f68d19f1a0663e8"}, - {file = "psutil-6.1.1-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0bdd4eab935276290ad3cb718e9809412895ca6b5b334f5a9111ee6d9aff9377"}, - {file = "psutil-6.1.1-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6e06c20c05fe95a3d7302d74e7097756d4ba1247975ad6905441ae1b5b66003"}, - {file = "psutil-6.1.1-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97f7cb9921fbec4904f522d972f0c0e1f4fabbdd4e0287813b21215074a0f160"}, - {file = "psutil-6.1.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33431e84fee02bc84ea36d9e2c4a6d395d479c9dd9bba2376c1f6ee8f3a4e0b3"}, - {file = "psutil-6.1.1-cp36-cp36m-win32.whl", hash = "sha256:384636b1a64b47814437d1173be1427a7c83681b17a450bfc309a1953e329603"}, - {file = "psutil-6.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:8be07491f6ebe1a693f17d4f11e69d0dc1811fa082736500f649f79df7735303"}, - {file = "psutil-6.1.1-cp37-abi3-win32.whl", hash = "sha256:eaa912e0b11848c4d9279a93d7e2783df352b082f40111e078388701fd479e53"}, - {file = "psutil-6.1.1-cp37-abi3-win_amd64.whl", hash = "sha256:f35cfccb065fff93529d2afb4a2e89e363fe63ca1e4a5da22b603a85833c2649"}, - {file = "psutil-6.1.1.tar.gz", hash = "sha256:cf8496728c18f2d0b45198f06895be52f36611711746b7f30c464b422b50e2f5"}, -] - -[package.extras] -dev = ["abi3audit", "black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "vulture", "wheel"] -test = ["pytest", "pytest-xdist", "setuptools"] - -[[package]] -name = "pydata-sphinx-theme" -version = "0.15.4" -description = "Bootstrap-based Sphinx theme from the PyData community" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "pydata_sphinx_theme-0.15.4-py3-none-any.whl", hash = "sha256:2136ad0e9500d0949f96167e63f3e298620040aea8f9c74621959eda5d4cf8e6"}, - {file = "pydata_sphinx_theme-0.15.4.tar.gz", hash = "sha256:7762ec0ac59df3acecf49fd2f889e1b4565dbce8b88b2e29ee06fdd90645a06d"}, -] - -[package.dependencies] -accessible-pygments = "*" -Babel = "*" -beautifulsoup4 = "*" -docutils = "!=0.17.0" -packaging = "*" -pygments = ">=2.7" -sphinx = ">=5" -typing-extensions = "*" - -[package.extras] -a11y = ["pytest-playwright"] -dev = ["pandoc", "pre-commit", "pydata-sphinx-theme[doc,test]", "pyyaml", "sphinx-theme-builder[cli]", "tox"] -doc = ["ablog (>=0.11.8)", "colorama", "graphviz", "ipykernel", "ipyleaflet", "ipywidgets", "jupyter_sphinx", "jupyterlite-sphinx", "linkify-it-py", "matplotlib", "myst-parser", "nbsphinx", "numpy", "numpydoc", "pandas", "plotly", "rich", "sphinx-autoapi (>=3.0.0)", "sphinx-copybutton", "sphinx-design", "sphinx-favicon (>=1.0.1)", "sphinx-sitemap", "sphinx-togglebutton", "sphinxcontrib-youtube (>=1.4.1)", "sphinxext-rediraffe", "xarray"] -i18n = ["Babel", "jinja2"] -test = ["pytest", "pytest-cov", "pytest-regressions", "sphinx[test]"] - -[[package]] -name = "pygments" -version = "2.19.2" -description = "Pygments is a syntax highlighting package written in Python." -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"}, - {file = "pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887"}, -] - -[package.extras] -windows-terminal = ["colorama (>=0.4.6)"] - -[[package]] -name = "pytest" -version = "8.4.1" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7"}, - {file = "pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c"}, -] - -[package.dependencies] -colorama = {version = ">=0.4", markers = "sys_platform == \"win32\""} -iniconfig = ">=1" -packaging = ">=20" -pluggy = ">=1.5,<2" -pygments = ">=2.7.2" - -[package.extras] -dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "pyyaml" -version = "6.0.2" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.8" -groups = ["main", "dev"] -files = [ - {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, - {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, - {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, - {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, - {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, - {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, - {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, - {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, - {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, - {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, - {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, - {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, - {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, - {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, - {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, - {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, - {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, -] - -[[package]] -name = "rcrscore" -version = "0.1.0" -description = "Add your description here" -optional = false -python-versions = ">=3.13" -groups = ["main"] -files = [] -develop = false - -[package.dependencies] -protobuf = ">=6.31.1" -rtree = ">=1.4.0" - -[package.source] -type = "git" -url = "https://github.com/adf-python/rcrs-core-python" -reference = "improve" -resolved_reference = "288c666003039b77c09e91d0067f61ad2b125ce4" - -[[package]] -name = "requests" -version = "2.32.4" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c"}, - {file = "requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset_normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "roman-numerals-py" -version = "3.1.0" -description = "Manipulate well-formed Roman numerals" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "roman_numerals_py-3.1.0-py3-none-any.whl", hash = "sha256:9da2ad2fb670bcf24e81070ceb3be72f6c11c440d73bd579fbeca1e9f330954c"}, - {file = "roman_numerals_py-3.1.0.tar.gz", hash = "sha256:be4bf804f083a4ce001b5eb7e3c0862479d10f94c936f6c4e5f250aa5ff5bd2d"}, -] - -[package.extras] -lint = ["mypy (==1.15.0)", "pyright (==1.1.394)", "ruff (==0.9.7)"] -test = ["pytest (>=8)"] - -[[package]] -name = "rtree" -version = "1.4.0" -description = "R-Tree spatial index for Python GIS" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "rtree-1.4.0-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:4d1bebc418101480aabf41767e772dd2155d3b27b1376cccbd93e4509485e091"}, - {file = "rtree-1.4.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:997f8c38d5dffa3949ea8adb4c8b291ea5cd4ef5ee69455d642dd171baf9991d"}, - {file = "rtree-1.4.0-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0133d9c54ab3ffe874ba6d411dbe0254765c5e68d92da5b91362c370f16fd997"}, - {file = "rtree-1.4.0-py3-none-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:d3b7bf1fe6463139377995ebe22a01a7005d134707f43672a3c09305e12f5f43"}, - {file = "rtree-1.4.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:27e4a6d617d63dcb82fcd4c2856134b8a3741bd1af3b1a0d98e886054f394da5"}, - {file = "rtree-1.4.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5258e826064eab82439760201e9421ce6d4340789d6d080c1b49367ddd03f61f"}, - {file = "rtree-1.4.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:20d5b3f9cf8bbbcc9fec42ab837c603c5dd86103ef29134300c8da2495c1248b"}, - {file = "rtree-1.4.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a67bee1233370a4c72c0969a96d2a1df1ba404ddd9f146849c53ab420eab361b"}, - {file = "rtree-1.4.0-py3-none-win_amd64.whl", hash = "sha256:ba83efc7b7563905b1bfdfc14490c4bfb59e92e5e6156bdeb6ec5df5117252f4"}, - {file = "rtree-1.4.0.tar.gz", hash = "sha256:9d97c7c5dcf25f6c0599c76d9933368c6a8d7238f2c1d00e76f1a69369ca82a0"}, -] - -[[package]] -name = "ruff" -version = "0.4.10" -description = "An extremely fast Python linter and code formatter, written in Rust." -optional = false -python-versions = ">=3.7" -groups = ["dev"] -files = [ - {file = "ruff-0.4.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:5c2c4d0859305ac5a16310eec40e4e9a9dec5dcdfbe92697acd99624e8638dac"}, - {file = "ruff-0.4.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:a79489607d1495685cdd911a323a35871abfb7a95d4f98fc6f85e799227ac46e"}, - {file = "ruff-0.4.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1dd1681dfa90a41b8376a61af05cc4dc5ff32c8f14f5fe20dba9ff5deb80cd6"}, - {file = "ruff-0.4.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c75c53bb79d71310dc79fb69eb4902fba804a81f374bc86a9b117a8d077a1784"}, - {file = "ruff-0.4.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18238c80ee3d9100d3535d8eb15a59c4a0753b45cc55f8bf38f38d6a597b9739"}, - {file = "ruff-0.4.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d8f71885bce242da344989cae08e263de29752f094233f932d4f5cfb4ef36a81"}, - {file = "ruff-0.4.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:330421543bd3222cdfec481e8ff3460e8702ed1e58b494cf9d9e4bf90db52b9d"}, - {file = "ruff-0.4.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9e9b6fb3a37b772628415b00c4fc892f97954275394ed611056a4b8a2631365e"}, - {file = "ruff-0.4.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f54c481b39a762d48f64d97351048e842861c6662d63ec599f67d515cb417f6"}, - {file = "ruff-0.4.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:67fe086b433b965c22de0b4259ddfe6fa541c95bf418499bedb9ad5fb8d1c631"}, - {file = "ruff-0.4.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:acfaaab59543382085f9eb51f8e87bac26bf96b164839955f244d07125a982ef"}, - {file = "ruff-0.4.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:3cea07079962b2941244191569cf3a05541477286f5cafea638cd3aa94b56815"}, - {file = "ruff-0.4.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:338a64ef0748f8c3a80d7f05785930f7965d71ca260904a9321d13be24b79695"}, - {file = "ruff-0.4.10-py3-none-win32.whl", hash = "sha256:ffe3cd2f89cb54561c62e5fa20e8f182c0a444934bf430515a4b422f1ab7b7ca"}, - {file = "ruff-0.4.10-py3-none-win_amd64.whl", hash = "sha256:67f67cef43c55ffc8cc59e8e0b97e9e60b4837c8f21e8ab5ffd5d66e196e25f7"}, - {file = "ruff-0.4.10-py3-none-win_arm64.whl", hash = "sha256:dd1fcee327c20addac7916ca4e2653fbbf2e8388d8a6477ce5b4e986b68ae6c0"}, - {file = "ruff-0.4.10.tar.gz", hash = "sha256:3aa4f2bc388a30d346c56524f7cacca85945ba124945fe489952aadb6b5cd804"}, -] - -[[package]] -name = "scikit-learn" -version = "1.7.1" -description = "A set of python modules for machine learning and data mining" -optional = false -python-versions = ">=3.10" -groups = ["main"] -files = [ - {file = "scikit_learn-1.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:406204dd4004f0517f0b23cf4b28c6245cbd51ab1b6b78153bc784def214946d"}, - {file = "scikit_learn-1.7.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:16af2e44164f05d04337fd1fc3ae7c4ea61fd9b0d527e22665346336920fe0e1"}, - {file = "scikit_learn-1.7.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2f2e78e56a40c7587dea9a28dc4a49500fa2ead366869418c66f0fd75b80885c"}, - {file = "scikit_learn-1.7.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b62b76ad408a821475b43b7bb90a9b1c9a4d8d125d505c2df0539f06d6e631b1"}, - {file = "scikit_learn-1.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:9963b065677a4ce295e8ccdee80a1dd62b37249e667095039adcd5bce6e90deb"}, - {file = "scikit_learn-1.7.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:90c8494ea23e24c0fb371afc474618c1019dc152ce4a10e4607e62196113851b"}, - {file = "scikit_learn-1.7.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:bb870c0daf3bf3be145ec51df8ac84720d9972170786601039f024bf6d61a518"}, - {file = "scikit_learn-1.7.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:40daccd1b5623f39e8943ab39735cadf0bdce80e67cdca2adcb5426e987320a8"}, - {file = "scikit_learn-1.7.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:30d1f413cfc0aa5a99132a554f1d80517563c34a9d3e7c118fde2d273c6fe0f7"}, - {file = "scikit_learn-1.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:c711d652829a1805a95d7fe96654604a8f16eab5a9e9ad87b3e60173415cb650"}, - {file = "scikit_learn-1.7.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3cee419b49b5bbae8796ecd690f97aa412ef1674410c23fc3257c6b8b85b8087"}, - {file = "scikit_learn-1.7.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:2fd8b8d35817b0d9ebf0b576f7d5ffbbabdb55536b0655a8aaae629d7ffd2e1f"}, - {file = "scikit_learn-1.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:588410fa19a96a69763202f1d6b7b91d5d7a5d73be36e189bc6396bfb355bd87"}, - {file = "scikit_learn-1.7.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e3142f0abe1ad1d1c31a2ae987621e41f6b578144a911ff4ac94781a583adad7"}, - {file = "scikit_learn-1.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:3ddd9092c1bd469acab337d87930067c87eac6bd544f8d5027430983f1e1ae88"}, - {file = "scikit_learn-1.7.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b7839687fa46d02e01035ad775982f2470be2668e13ddd151f0f55a5bf123bae"}, - {file = "scikit_learn-1.7.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:a10f276639195a96c86aa572ee0698ad64ee939a7b042060b98bd1930c261d10"}, - {file = "scikit_learn-1.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:13679981fdaebc10cc4c13c43344416a86fcbc61449cb3e6517e1df9d12c8309"}, - {file = "scikit_learn-1.7.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4f1262883c6a63f067a980a8cdd2d2e7f2513dddcef6a9eaada6416a7a7cbe43"}, - {file = "scikit_learn-1.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:ca6d31fb10e04d50bfd2b50d66744729dbb512d4efd0223b864e2fdbfc4cee11"}, - {file = "scikit_learn-1.7.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:781674d096303cfe3d351ae6963ff7c958db61cde3421cd490e3a5a58f2a94ae"}, - {file = "scikit_learn-1.7.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:10679f7f125fe7ecd5fad37dd1aa2daae7e3ad8df7f3eefa08901b8254b3e12c"}, - {file = "scikit_learn-1.7.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1f812729e38c8cb37f760dce71a9b83ccfb04f59b3dca7c6079dcdc60544fa9e"}, - {file = "scikit_learn-1.7.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:88e1a20131cf741b84b89567e1717f27a2ced228e0f29103426102bc2e3b8ef7"}, - {file = "scikit_learn-1.7.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b1bd1d919210b6a10b7554b717c9000b5485aa95a1d0f177ae0d7ee8ec750da5"}, - {file = "scikit_learn-1.7.1.tar.gz", hash = "sha256:24b3f1e976a4665aa74ee0fcaac2b8fccc6ae77c8e07ab25da3ba6d3292b9802"}, -] - -[package.dependencies] -joblib = ">=1.2.0" -numpy = ">=1.22.0" -scipy = ">=1.8.0" -threadpoolctl = ">=3.1.0" - -[package.extras] -benchmark = ["matplotlib (>=3.5.0)", "memory_profiler (>=0.57.0)", "pandas (>=1.4.0)"] -build = ["cython (>=3.0.10)", "meson-python (>=0.17.1)", "numpy (>=1.22.0)", "scipy (>=1.8.0)"] -docs = ["Pillow (>=8.4.0)", "matplotlib (>=3.5.0)", "memory_profiler (>=0.57.0)", "numpydoc (>=1.2.0)", "pandas (>=1.4.0)", "plotly (>=5.14.0)", "polars (>=0.20.30)", "pooch (>=1.6.0)", "pydata-sphinx-theme (>=0.15.3)", "scikit-image (>=0.19.0)", "seaborn (>=0.9.0)", "sphinx (>=7.3.7)", "sphinx-copybutton (>=0.5.2)", "sphinx-design (>=0.5.0)", "sphinx-design (>=0.6.0)", "sphinx-gallery (>=0.17.1)", "sphinx-prompt (>=1.4.0)", "sphinx-remove-toctrees (>=1.0.0.post1)", "sphinxcontrib-sass (>=0.3.4)", "sphinxext-opengraph (>=0.9.1)", "towncrier (>=24.8.0)"] -examples = ["matplotlib (>=3.5.0)", "pandas (>=1.4.0)", "plotly (>=5.14.0)", "pooch (>=1.6.0)", "scikit-image (>=0.19.0)", "seaborn (>=0.9.0)"] -install = ["joblib (>=1.2.0)", "numpy (>=1.22.0)", "scipy (>=1.8.0)", "threadpoolctl (>=3.1.0)"] -maintenance = ["conda-lock (==3.0.1)"] -tests = ["matplotlib (>=3.5.0)", "mypy (>=1.15)", "numpydoc (>=1.2.0)", "pandas (>=1.4.0)", "polars (>=0.20.30)", "pooch (>=1.6.0)", "pyamg (>=4.2.1)", "pyarrow (>=12.0.0)", "pytest (>=7.1.2)", "pytest-cov (>=2.9.0)", "ruff (>=0.11.7)", "scikit-image (>=0.19.0)"] - -[[package]] -name = "scipy" -version = "1.16.1" -description = "Fundamental algorithms for scientific computing in Python" -optional = false -python-versions = ">=3.11" -groups = ["main"] -files = [ - {file = "scipy-1.16.1-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:c033fa32bab91dc98ca59d0cf23bb876454e2bb02cbe592d5023138778f70030"}, - {file = "scipy-1.16.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:6e5c2f74e5df33479b5cd4e97a9104c511518fbd979aa9b8f6aec18b2e9ecae7"}, - {file = "scipy-1.16.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:0a55ffe0ba0f59666e90951971a884d1ff6f4ec3275a48f472cfb64175570f77"}, - {file = "scipy-1.16.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:f8a5d6cd147acecc2603fbd382fed6c46f474cccfcf69ea32582e033fb54dcfe"}, - {file = "scipy-1.16.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cb18899127278058bcc09e7b9966d41a5a43740b5bb8dcba401bd983f82e885b"}, - {file = "scipy-1.16.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:adccd93a2fa937a27aae826d33e3bfa5edf9aa672376a4852d23a7cd67a2e5b7"}, - {file = "scipy-1.16.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:18aca1646a29ee9a0625a1be5637fa798d4d81fdf426481f06d69af828f16958"}, - {file = "scipy-1.16.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d85495cef541729a70cdddbbf3e6b903421bc1af3e8e3a9a72a06751f33b7c39"}, - {file = "scipy-1.16.1-cp311-cp311-win_amd64.whl", hash = "sha256:226652fca853008119c03a8ce71ffe1b3f6d2844cc1686e8f9806edafae68596"}, - {file = "scipy-1.16.1-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:81b433bbeaf35728dad619afc002db9b189e45eebe2cd676effe1fb93fef2b9c"}, - {file = "scipy-1.16.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:886cc81fdb4c6903a3bb0464047c25a6d1016fef77bb97949817d0c0d79f9e04"}, - {file = "scipy-1.16.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:15240c3aac087a522b4eaedb09f0ad061753c5eebf1ea430859e5bf8640d5919"}, - {file = "scipy-1.16.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:65f81a25805f3659b48126b5053d9e823d3215e4a63730b5e1671852a1705921"}, - {file = "scipy-1.16.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6c62eea7f607f122069b9bad3f99489ddca1a5173bef8a0c75555d7488b6f725"}, - {file = "scipy-1.16.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f965bbf3235b01c776115ab18f092a95aa74c271a52577bcb0563e85738fd618"}, - {file = "scipy-1.16.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f006e323874ffd0b0b816d8c6a8e7f9a73d55ab3b8c3f72b752b226d0e3ac83d"}, - {file = "scipy-1.16.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e8fd15fc5085ab4cca74cb91fe0a4263b1f32e4420761ddae531ad60934c2119"}, - {file = "scipy-1.16.1-cp312-cp312-win_amd64.whl", hash = "sha256:f7b8013c6c066609577d910d1a2a077021727af07b6fab0ee22c2f901f22352a"}, - {file = "scipy-1.16.1-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:5451606823a5e73dfa621a89948096c6528e2896e40b39248295d3a0138d594f"}, - {file = "scipy-1.16.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:89728678c5ca5abd610aee148c199ac1afb16e19844401ca97d43dc548a354eb"}, - {file = "scipy-1.16.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e756d688cb03fd07de0fffad475649b03cb89bee696c98ce508b17c11a03f95c"}, - {file = "scipy-1.16.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5aa2687b9935da3ed89c5dbed5234576589dd28d0bf7cd237501ccfbdf1ad608"}, - {file = "scipy-1.16.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0851f6a1e537fe9399f35986897e395a1aa61c574b178c0d456be5b1a0f5ca1f"}, - {file = "scipy-1.16.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fedc2cbd1baed37474b1924c331b97bdff611d762c196fac1a9b71e67b813b1b"}, - {file = "scipy-1.16.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2ef500e72f9623a6735769e4b93e9dcb158d40752cdbb077f305487e3e2d1f45"}, - {file = "scipy-1.16.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:978d8311674b05a8f7ff2ea6c6bce5d8b45a0cb09d4c5793e0318f448613ea65"}, - {file = "scipy-1.16.1-cp313-cp313-win_amd64.whl", hash = "sha256:81929ed0fa7a5713fcdd8b2e6f73697d3b4c4816d090dd34ff937c20fa90e8ab"}, - {file = "scipy-1.16.1-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:bcc12db731858abda693cecdb3bdc9e6d4bd200213f49d224fe22df82687bdd6"}, - {file = "scipy-1.16.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:744d977daa4becb9fc59135e75c069f8d301a87d64f88f1e602a9ecf51e77b27"}, - {file = "scipy-1.16.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:dc54f76ac18073bcecffb98d93f03ed6b81a92ef91b5d3b135dcc81d55a724c7"}, - {file = "scipy-1.16.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:367d567ee9fc1e9e2047d31f39d9d6a7a04e0710c86e701e053f237d14a9b4f6"}, - {file = "scipy-1.16.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4cf5785e44e19dcd32a0e4807555e1e9a9b8d475c6afff3d21c3c543a6aa84f4"}, - {file = "scipy-1.16.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3d0b80fb26d3e13a794c71d4b837e2a589d839fd574a6bbb4ee1288c213ad4a3"}, - {file = "scipy-1.16.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8503517c44c18d1030d666cb70aaac1cc8913608816e06742498833b128488b7"}, - {file = "scipy-1.16.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:30cc4bb81c41831ecfd6dc450baf48ffd80ef5aed0f5cf3ea775740e80f16ecc"}, - {file = "scipy-1.16.1-cp313-cp313t-win_amd64.whl", hash = "sha256:c24fa02f7ed23ae514460a22c57eca8f530dbfa50b1cfdbf4f37c05b5309cc39"}, - {file = "scipy-1.16.1-cp314-cp314-macosx_10_14_x86_64.whl", hash = "sha256:796a5a9ad36fa3a782375db8f4241ab02a091308eb079746bc0f874c9b998318"}, - {file = "scipy-1.16.1-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:3ea0733a2ff73fd6fdc5fecca54ee9b459f4d74f00b99aced7d9a3adb43fb1cc"}, - {file = "scipy-1.16.1-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:85764fb15a2ad994e708258bb4ed8290d1305c62a4e1ef07c414356a24fcfbf8"}, - {file = "scipy-1.16.1-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:ca66d980469cb623b1759bdd6e9fd97d4e33a9fad5b33771ced24d0cb24df67e"}, - {file = "scipy-1.16.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e7cc1ffcc230f568549fc56670bcf3df1884c30bd652c5da8138199c8c76dae0"}, - {file = "scipy-1.16.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3ddfb1e8d0b540cb4ee9c53fc3dea3186f97711248fb94b4142a1b27178d8b4b"}, - {file = "scipy-1.16.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4dc0e7be79e95d8ba3435d193e0d8ce372f47f774cffd882f88ea4e1e1ddc731"}, - {file = "scipy-1.16.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f23634f9e5adb51b2a77766dac217063e764337fbc816aa8ad9aaebcd4397fd3"}, - {file = "scipy-1.16.1-cp314-cp314-win_amd64.whl", hash = "sha256:57d75524cb1c5a374958a2eae3d84e1929bb971204cc9d52213fb8589183fc19"}, - {file = "scipy-1.16.1-cp314-cp314t-macosx_10_14_x86_64.whl", hash = "sha256:d8da7c3dd67bcd93f15618938f43ed0995982eb38973023d46d4646c4283ad65"}, - {file = "scipy-1.16.1-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:cc1d2f2fd48ba1e0620554fe5bc44d3e8f5d4185c8c109c7fbdf5af2792cfad2"}, - {file = "scipy-1.16.1-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:21a611ced9275cb861bacadbada0b8c0623bc00b05b09eb97f23b370fc2ae56d"}, - {file = "scipy-1.16.1-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:8dfbb25dffc4c3dd9371d8ab456ca81beeaf6f9e1c2119f179392f0dc1ab7695"}, - {file = "scipy-1.16.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f0ebb7204f063fad87fc0a0e4ff4a2ff40b2a226e4ba1b7e34bf4b79bf97cd86"}, - {file = "scipy-1.16.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f1b9e5962656f2734c2b285a8745358ecb4e4efbadd00208c80a389227ec61ff"}, - {file = "scipy-1.16.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e1a106f8c023d57a2a903e771228bf5c5b27b5d692088f457acacd3b54511e4"}, - {file = "scipy-1.16.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:709559a1db68a9abc3b2c8672c4badf1614f3b440b3ab326d86a5c0491eafae3"}, - {file = "scipy-1.16.1-cp314-cp314t-win_amd64.whl", hash = "sha256:c0c804d60492a0aad7f5b2bb1862f4548b990049e27e828391ff2bf6f7199998"}, - {file = "scipy-1.16.1.tar.gz", hash = "sha256:44c76f9e8b6e8e488a586190ab38016e4ed2f8a038af7cd3defa903c0a2238b3"}, -] - -[package.dependencies] -numpy = ">=1.25.2,<2.6" - -[package.extras] -dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy (==1.10.0)", "pycodestyle", "pydevtool", "rich-click", "ruff (>=0.0.292)", "types-psutil", "typing_extensions"] -doc = ["intersphinx_registry", "jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.19.1)", "jupytext", "linkify-it-py", "matplotlib (>=3.5)", "myst-nb (>=1.2.0)", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0,<8.2.0)", "sphinx-copybutton", "sphinx-design (>=0.4.0)"] -test = ["Cython", "array-api-strict (>=2.3.1)", "asv", "gmpy2", "hypothesis (>=6.30)", "meson", "mpmath", "ninja ; sys_platform != \"emscripten\"", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] - -[[package]] -name = "setuptools" -version = "80.9.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922"}, - {file = "setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\"", "ruff (>=0.8.0) ; sys_platform != \"cygwin\""] -core = ["importlib_metadata (>=6) ; python_version < \"3.10\"", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1) ; python_version < \"3.11\"", "wheel (>=0.43.0)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf ; sys_platform != \"cygwin\"", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib_metadata (>=7.0.2) ; python_version < \"3.10\"", "jaraco.develop (>=7.21) ; sys_platform != \"cygwin\"", "mypy (==1.14.*)", "pytest-mypy"] - -[[package]] -name = "shapely" -version = "2.1.1" -description = "Manipulation and analysis of geometric objects" -optional = false -python-versions = ">=3.10" -groups = ["main"] -files = [ - {file = "shapely-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d8ccc872a632acb7bdcb69e5e78df27213f7efd195882668ffba5405497337c6"}, - {file = "shapely-2.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f24f2ecda1e6c091da64bcbef8dd121380948074875bd1b247b3d17e99407099"}, - {file = "shapely-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45112a5be0b745b49e50f8829ce490eb67fefb0cea8d4f8ac5764bfedaa83d2d"}, - {file = "shapely-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c10ce6f11904d65e9bbb3e41e774903c944e20b3f0b282559885302f52f224a"}, - {file = "shapely-2.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:61168010dfe4e45f956ffbbaf080c88afce199ea81eb1f0ac43230065df320bd"}, - {file = "shapely-2.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cacf067cdff741cd5c56a21c52f54ece4e4dad9d311130493a791997da4a886b"}, - {file = "shapely-2.1.1-cp310-cp310-win32.whl", hash = "sha256:23b8772c3b815e7790fb2eab75a0b3951f435bc0fce7bb146cb064f17d35ab4f"}, - {file = "shapely-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:2c7b2b6143abf4fa77851cef8ef690e03feade9a0d48acd6dc41d9e0e78d7ca6"}, - {file = "shapely-2.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:587a1aa72bc858fab9b8c20427b5f6027b7cbc92743b8e2c73b9de55aa71c7a7"}, - {file = "shapely-2.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9fa5c53b0791a4b998f9ad84aad456c988600757a96b0a05e14bba10cebaaaea"}, - {file = "shapely-2.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aabecd038841ab5310d23495253f01c2a82a3aedae5ab9ca489be214aa458aa7"}, - {file = "shapely-2.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:586f6aee1edec04e16227517a866df3e9a2e43c1f635efc32978bb3dc9c63753"}, - {file = "shapely-2.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b9878b9e37ad26c72aada8de0c9cfe418d9e2ff36992a1693b7f65a075b28647"}, - {file = "shapely-2.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d9a531c48f289ba355e37b134e98e28c557ff13965d4653a5228d0f42a09aed0"}, - {file = "shapely-2.1.1-cp311-cp311-win32.whl", hash = "sha256:4866de2673a971820c75c0167b1f1cd8fb76f2d641101c23d3ca021ad0449bab"}, - {file = "shapely-2.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:20a9d79958b3d6c70d8a886b250047ea32ff40489d7abb47d01498c704557a93"}, - {file = "shapely-2.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2827365b58bf98efb60affc94a8e01c56dd1995a80aabe4b701465d86dcbba43"}, - {file = "shapely-2.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a9c551f7fa7f1e917af2347fe983f21f212863f1d04f08eece01e9c275903fad"}, - {file = "shapely-2.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78dec4d4fbe7b1db8dc36de3031767e7ece5911fb7782bc9e95c5cdec58fb1e9"}, - {file = "shapely-2.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:872d3c0a7b8b37da0e23d80496ec5973c4692920b90de9f502b5beb994bbaaef"}, - {file = "shapely-2.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2e2b9125ebfbc28ecf5353511de62f75a8515ae9470521c9a693e4bb9fbe0cf1"}, - {file = "shapely-2.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4b96cea171b3d7f6786976a0520f178c42792897653ecca0c5422fb1e6946e6d"}, - {file = "shapely-2.1.1-cp312-cp312-win32.whl", hash = "sha256:39dca52201e02996df02e447f729da97cfb6ff41a03cb50f5547f19d02905af8"}, - {file = "shapely-2.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:13d643256f81d55a50013eff6321142781cf777eb6a9e207c2c9e6315ba6044a"}, - {file = "shapely-2.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3004a644d9e89e26c20286d5fdc10f41b1744c48ce910bd1867fdff963fe6c48"}, - {file = "shapely-2.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1415146fa12d80a47d13cfad5310b3c8b9c2aa8c14a0c845c9d3d75e77cb54f6"}, - {file = "shapely-2.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21fcab88b7520820ec16d09d6bea68652ca13993c84dffc6129dc3607c95594c"}, - {file = "shapely-2.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5ce6a5cc52c974b291237a96c08c5592e50f066871704fb5b12be2639d9026a"}, - {file = "shapely-2.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:04e4c12a45a1d70aeb266618d8cf81a2de9c4df511b63e105b90bfdfb52146de"}, - {file = "shapely-2.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6ca74d851ca5264aae16c2b47e96735579686cb69fa93c4078070a0ec845b8d8"}, - {file = "shapely-2.1.1-cp313-cp313-win32.whl", hash = "sha256:fd9130501bf42ffb7e0695b9ea17a27ae8ce68d50b56b6941c7f9b3d3453bc52"}, - {file = "shapely-2.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:ab8d878687b438a2f4c138ed1a80941c6ab0029e0f4c785ecfe114413b498a97"}, - {file = "shapely-2.1.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0c062384316a47f776305ed2fa22182717508ffdeb4a56d0ff4087a77b2a0f6d"}, - {file = "shapely-2.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4ecf6c196b896e8f1360cc219ed4eee1c1e5f5883e505d449f263bd053fb8c05"}, - {file = "shapely-2.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb00070b4c4860f6743c600285109c273cca5241e970ad56bb87bef0be1ea3a0"}, - {file = "shapely-2.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d14a9afa5fa980fbe7bf63706fdfb8ff588f638f145a1d9dbc18374b5b7de913"}, - {file = "shapely-2.1.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b640e390dabde790e3fb947198b466e63223e0a9ccd787da5f07bcb14756c28d"}, - {file = "shapely-2.1.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:69e08bf9697c1b73ec6aa70437db922bafcea7baca131c90c26d59491a9760f9"}, - {file = "shapely-2.1.1-cp313-cp313t-win32.whl", hash = "sha256:ef2d09d5a964cc90c2c18b03566cf918a61c248596998a0301d5b632beadb9db"}, - {file = "shapely-2.1.1-cp313-cp313t-win_amd64.whl", hash = "sha256:8cb8f17c377260452e9d7720eeaf59082c5f8ea48cf104524d953e5d36d4bdb7"}, - {file = "shapely-2.1.1.tar.gz", hash = "sha256:500621967f2ffe9642454808009044c21e5b35db89ce69f8a2042c2ffd0e2772"}, -] - -[package.dependencies] -numpy = ">=1.21" - -[package.extras] -docs = ["matplotlib", "numpydoc (==1.1.*)", "sphinx", "sphinx-book-theme", "sphinx-remove-toctrees"] -test = ["pytest", "pytest-cov", "scipy-doctest"] - -[[package]] -name = "snowballstemmer" -version = "3.0.1" -description = "This package provides 32 stemmers for 30 languages generated from Snowball algorithms." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*" -groups = ["dev"] -files = [ - {file = "snowballstemmer-3.0.1-py3-none-any.whl", hash = "sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064"}, - {file = "snowballstemmer-3.0.1.tar.gz", hash = "sha256:6d5eeeec8e9f84d4d56b847692bacf79bc2c8e90c7f80ca4444ff8b6f2e52895"}, -] - -[[package]] -name = "soupsieve" -version = "2.7" -description = "A modern CSS selector implementation for Beautiful Soup." -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "soupsieve-2.7-py3-none-any.whl", hash = "sha256:6e60cc5c1ffaf1cebcc12e8188320b72071e922c2e897f737cadce79ad5d30c4"}, - {file = "soupsieve-2.7.tar.gz", hash = "sha256:ad282f9b6926286d2ead4750552c8a6142bc4c783fd66b0293547c8fe6ae126a"}, -] - -[[package]] -name = "sphinx" -version = "8.2.3" -description = "Python documentation generator" -optional = false -python-versions = ">=3.11" -groups = ["dev"] -files = [ - {file = "sphinx-8.2.3-py3-none-any.whl", hash = "sha256:4405915165f13521d875a8c29c8970800a0141c14cc5416a38feca4ea5d9b9c3"}, - {file = "sphinx-8.2.3.tar.gz", hash = "sha256:398ad29dee7f63a75888314e9424d40f52ce5a6a87ae88e7071e80af296ec348"}, -] - -[package.dependencies] -alabaster = ">=0.7.14" -babel = ">=2.13" -colorama = {version = ">=0.4.6", markers = "sys_platform == \"win32\""} -docutils = ">=0.20,<0.22" -imagesize = ">=1.3" -Jinja2 = ">=3.1" -packaging = ">=23.0" -Pygments = ">=2.17" -requests = ">=2.30.0" -roman-numerals-py = ">=1.0.0" -snowballstemmer = ">=2.2" -sphinxcontrib-applehelp = ">=1.0.7" -sphinxcontrib-devhelp = ">=1.0.6" -sphinxcontrib-htmlhelp = ">=2.0.6" -sphinxcontrib-jsmath = ">=1.0.1" -sphinxcontrib-qthelp = ">=1.0.6" -sphinxcontrib-serializinghtml = ">=1.1.9" - -[package.extras] -docs = ["sphinxcontrib-websupport"] -lint = ["betterproto (==2.0.0b6)", "mypy (==1.15.0)", "pypi-attestations (==0.0.21)", "pyright (==1.1.395)", "pytest (>=8.0)", "ruff (==0.9.9)", "sphinx-lint (>=0.9)", "types-Pillow (==10.2.0.20240822)", "types-Pygments (==2.19.0.20250219)", "types-colorama (==0.4.15.20240311)", "types-defusedxml (==0.7.0.20240218)", "types-docutils (==0.21.0.20241128)", "types-requests (==2.32.0.20241016)", "types-urllib3 (==1.26.25.14)"] -test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=8.0)", "pytest-xdist[psutil] (>=3.4)", "setuptools (>=70.0)", "typing_extensions (>=4.9)"] - -[[package]] -name = "sphinx-book-theme" -version = "1.1.4" -description = "A clean book theme for scientific explanations and documentation with Sphinx" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "sphinx_book_theme-1.1.4-py3-none-any.whl", hash = "sha256:843b3f5c8684640f4a2d01abd298beb66452d1b2394cd9ef5be5ebd5640ea0e1"}, - {file = "sphinx_book_theme-1.1.4.tar.gz", hash = "sha256:73efe28af871d0a89bd05856d300e61edce0d5b2fbb7984e84454be0fedfe9ed"}, -] - -[package.dependencies] -pydata-sphinx-theme = "0.15.4" -sphinx = ">=6.1" - -[package.extras] -code-style = ["pre-commit"] -doc = ["ablog", "folium", "ipywidgets", "matplotlib", "myst-nb", "nbclient", "numpy", "numpydoc", "pandas", "plotly", "sphinx-copybutton", "sphinx-design", "sphinx-examples", "sphinx-tabs", "sphinx-thebe", "sphinx-togglebutton", "sphinxcontrib-bibtex", "sphinxcontrib-youtube", "sphinxext-opengraph"] -test = ["beautifulsoup4", "coverage", "defusedxml", "myst-nb", "pytest", "pytest-cov", "pytest-regressions", "sphinx_thebe"] - -[[package]] -name = "sphinx-copybutton" -version = "0.5.2" -description = "Add a copy button to each of your code cells." -optional = false -python-versions = ">=3.7" -groups = ["dev"] -files = [ - {file = "sphinx-copybutton-0.5.2.tar.gz", hash = "sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd"}, - {file = "sphinx_copybutton-0.5.2-py3-none-any.whl", hash = "sha256:fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e"}, -] - -[package.dependencies] -sphinx = ">=1.8" - -[package.extras] -code-style = ["pre-commit (==2.12.1)"] -rtd = ["ipython", "myst-nb", "sphinx", "sphinx-book-theme", "sphinx-examples"] - -[[package]] -name = "sphinx-intl" -version = "2.3.2" -description = "Sphinx utility that make it easy to translate and to apply translation." -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "sphinx_intl-2.3.2-py3-none-any.whl", hash = "sha256:f0082f9383066bab8406129a2ed531d21c38706d08467bf5ca3714e8914bb2be"}, - {file = "sphinx_intl-2.3.2.tar.gz", hash = "sha256:04b0d8ea04d111a7ba278b17b7b3fe9625c58b6f8ffb78bb8a1dd1288d88c1c7"}, -] - -[package.dependencies] -babel = ">=2.9.0" -click = ">=8.0.0" -sphinx = "*" - -[package.extras] -test = ["pytest (>=8.3.5)"] - -[[package]] -name = "sphinx-rtd-theme" -version = "3.0.2" -description = "Read the Docs theme for Sphinx" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "sphinx_rtd_theme-3.0.2-py2.py3-none-any.whl", hash = "sha256:422ccc750c3a3a311de4ae327e82affdaf59eb695ba4936538552f3b00f4ee13"}, - {file = "sphinx_rtd_theme-3.0.2.tar.gz", hash = "sha256:b7457bc25dda723b20b086a670b9953c859eab60a2a03ee8eb2bb23e176e5f85"}, -] - -[package.dependencies] -docutils = ">0.18,<0.22" -sphinx = ">=6,<9" -sphinxcontrib-jquery = ">=4,<5" - -[package.extras] -dev = ["bump2version", "transifex-client", "twine", "wheel"] - -[[package]] -name = "sphinx-togglebutton" -version = "0.3.2" -description = "Toggle page content and collapse admonitions in Sphinx." -optional = false -python-versions = "*" -groups = ["dev"] -files = [ - {file = "sphinx-togglebutton-0.3.2.tar.gz", hash = "sha256:ab0c8b366427b01e4c89802d5d078472c427fa6e9d12d521c34fa0442559dc7a"}, - {file = "sphinx_togglebutton-0.3.2-py3-none-any.whl", hash = "sha256:9647ba7874b7d1e2d43413d8497153a85edc6ac95a3fea9a75ef9c1e08aaae2b"}, -] - -[package.dependencies] -docutils = "*" -setuptools = "*" -sphinx = "*" -wheel = "*" - -[package.extras] -sphinx = ["matplotlib", "myst-nb", "numpy", "sphinx-book-theme", "sphinx-design", "sphinx-examples"] - -[[package]] -name = "sphinxcontrib-applehelp" -version = "2.0.0" -description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5"}, - {file = "sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1"}, -] - -[package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] -standalone = ["Sphinx (>=5)"] -test = ["pytest"] - -[[package]] -name = "sphinxcontrib-devhelp" -version = "2.0.0" -description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2"}, - {file = "sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad"}, -] - -[package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] -standalone = ["Sphinx (>=5)"] -test = ["pytest"] - -[[package]] -name = "sphinxcontrib-htmlhelp" -version = "2.1.0" -description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8"}, - {file = "sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9"}, -] - -[package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] -standalone = ["Sphinx (>=5)"] -test = ["html5lib", "pytest"] - -[[package]] -name = "sphinxcontrib-jquery" -version = "4.1" -description = "Extension to include jQuery on newer Sphinx releases" -optional = false -python-versions = ">=2.7" -groups = ["dev"] -files = [ - {file = "sphinxcontrib-jquery-4.1.tar.gz", hash = "sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a"}, - {file = "sphinxcontrib_jquery-4.1-py2.py3-none-any.whl", hash = "sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae"}, -] - -[package.dependencies] -Sphinx = ">=1.8" - -[[package]] -name = "sphinxcontrib-jsmath" -version = "1.0.1" -description = "A sphinx extension which renders display math in HTML via JavaScript" -optional = false -python-versions = ">=3.5" -groups = ["dev"] -files = [ - {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, - {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, -] - -[package.extras] -test = ["flake8", "mypy", "pytest"] - -[[package]] -name = "sphinxcontrib-mermaid" -version = "1.0.0" -description = "Mermaid diagrams in yours Sphinx powered docs" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "sphinxcontrib_mermaid-1.0.0-py3-none-any.whl", hash = "sha256:60b72710ea02087f212028feb09711225fbc2e343a10d34822fe787510e1caa3"}, - {file = "sphinxcontrib_mermaid-1.0.0.tar.gz", hash = "sha256:2e8ab67d3e1e2816663f9347d026a8dee4a858acdd4ad32dd1c808893db88146"}, -] - -[package.dependencies] -pyyaml = "*" -sphinx = "*" - -[package.extras] -test = ["defusedxml", "myst-parser", "pytest", "ruff", "sphinx"] - -[[package]] -name = "sphinxcontrib-qthelp" -version = "2.0.0" -description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb"}, - {file = "sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab"}, -] - -[package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] -standalone = ["Sphinx (>=5)"] -test = ["defusedxml (>=0.7.1)", "pytest"] - -[[package]] -name = "sphinxcontrib-serializinghtml" -version = "2.0.0" -description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331"}, - {file = "sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d"}, -] - -[package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] -standalone = ["Sphinx (>=5)"] -test = ["pytest"] - -[[package]] -name = "structlog" -version = "24.4.0" -description = "Structured Logging for Python" -optional = false -python-versions = ">=3.8" -groups = ["main"] -files = [ - {file = "structlog-24.4.0-py3-none-any.whl", hash = "sha256:597f61e80a91cc0749a9fd2a098ed76715a1c8a01f73e336b746504d1aad7610"}, - {file = "structlog-24.4.0.tar.gz", hash = "sha256:b27bfecede327a6d2da5fbc96bd859f114ecc398a6389d664f62085ee7ae6fc4"}, -] - -[package.extras] -dev = ["freezegun (>=0.2.8)", "mypy (>=1.4)", "pretend", "pytest (>=6.0)", "pytest-asyncio (>=0.17)", "rich", "simplejson", "twisted"] -docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-mermaid", "sphinxext-opengraph", "twisted"] -tests = ["freezegun (>=0.2.8)", "pretend", "pytest (>=6.0)", "pytest-asyncio (>=0.17)", "simplejson"] -typing = ["mypy (>=1.4)", "rich", "twisted"] - -[[package]] -name = "taskipy" -version = "1.14.1" -description = "tasks runner for python projects" -optional = false -python-versions = "<4.0,>=3.6" -groups = ["dev"] -files = [ - {file = "taskipy-1.14.1-py3-none-any.whl", hash = "sha256:6e361520f29a0fd2159848e953599f9c75b1d0b047461e4965069caeb94908f1"}, - {file = "taskipy-1.14.1.tar.gz", hash = "sha256:410fbcf89692dfd4b9f39c2b49e1750b0a7b81affd0e2d7ea8c35f9d6a4774ed"}, -] - -[package.dependencies] -colorama = ">=0.4.4,<0.5.0" -mslex = {version = ">=1.1.0,<2.0.0", markers = "sys_platform == \"win32\""} -psutil = ">=5.7.2,<7" -tomli = {version = ">=2.0.1,<3.0.0", markers = "python_version >= \"3.7\" and python_version < \"4.0\""} - -[[package]] -name = "threadpoolctl" -version = "3.6.0" -description = "threadpoolctl" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "threadpoolctl-3.6.0-py3-none-any.whl", hash = "sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb"}, - {file = "threadpoolctl-3.6.0.tar.gz", hash = "sha256:8ab8b4aa3491d812b623328249fab5302a68d2d71745c8a4c719a2fcaba9f44e"}, -] - -[[package]] -name = "tomli" -version = "2.2.1" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, - {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, - {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, - {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, - {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, - {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, - {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, - {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, - {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, - {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, - {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, - {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, - {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, - {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, -] - -[[package]] -name = "types-protobuf" -version = "4.25.0.20240417" -description = "Typing stubs for protobuf" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "types-protobuf-4.25.0.20240417.tar.gz", hash = "sha256:c34eff17b9b3a0adb6830622f0f302484e4c089f533a46e3f147568313544352"}, - {file = "types_protobuf-4.25.0.20240417-py3-none-any.whl", hash = "sha256:e9b613227c2127e3d4881d75d93c93b4d6fd97b5f6a099a0b654a05351c8685d"}, -] - -[[package]] -name = "types-pyyaml" -version = "6.0.12.20250516" -description = "Typing stubs for PyYAML" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "types_pyyaml-6.0.12.20250516-py3-none-any.whl", hash = "sha256:8478208feaeb53a34cb5d970c56a7cd76b72659442e733e268a94dc72b2d0530"}, - {file = "types_pyyaml-6.0.12.20250516.tar.gz", hash = "sha256:9f21a70216fc0fa1b216a8176db5f9e0af6eb35d2f2932acb87689d03a5bf6ba"}, -] - -[[package]] -name = "typing-extensions" -version = "4.14.1" -description = "Backported and Experimental Type Hints for Python 3.9+" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76"}, - {file = "typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36"}, -] - -[[package]] -name = "urllib3" -version = "2.5.0" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc"}, - {file = "urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "wheel" -version = "0.45.1" -description = "A built-package format for Python" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "wheel-0.45.1-py3-none-any.whl", hash = "sha256:708e7481cc80179af0e556bbf0cc00b8444c7321e2700b8d8580231d13017248"}, - {file = "wheel-0.45.1.tar.gz", hash = "sha256:661e1abd9198507b1409a20c02106d9670b2576e916d58f520316666abca6729"}, -] - -[package.extras] -test = ["pytest (>=6.0.0)", "setuptools (>=65)"] - -[metadata] -lock-version = "2.1" -python-versions = "^3.13" -content-hash = "0f25d8ec7e7a27c7ea9006b97135f44ede3114ec3a9a6f19702345464d0d7b51" diff --git a/poetry.toml b/poetry.toml deleted file mode 100644 index ab1033b..0000000 --- a/poetry.toml +++ /dev/null @@ -1,2 +0,0 @@ -[virtualenvs] -in-project = true diff --git a/pyproject.toml b/pyproject.toml index 080aba5..0e429bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,55 +1,47 @@ -[tool.poetry] +[project] name = "adf_core_python" -version = "0.1.5" +version = "0.2.0" description = "Agent Development Framework for Python" +readme = "README.md" authors = [ - "Haruki Uehara ", - "Yuki Shimada ", + { name = "Haruki Uehara", email = "k19016kk@maslab.aitech.ac.jp"}, + { name = "Yuki Shimada", email = "shimapaca@maslab.aitech.ac.jp" } +] +requires-python = ">=3.13" +dependencies = [ + "bitarray>=3.6.0", + "click>=8.2.1", + "jinja2>=3.1.6", + "protobuf>=6.31.1", + "pyyaml>=6.0.2", + "rcrscore", + "rtree>=1.4.0", + "scikit-learn>=1.7.1", + "shapely>=2.1.1", + "structlog>=25.4.0", + "types-pyyaml>=6.0.12.20250516", ] -readme = "README.md" -package-mode = true - -[tool.poetry.dependencies] -python = "^3.13" -rcrscore = { git = "https://github.com/adf-python/rcrs-core-python", branch = "improve" } -pyyaml = "^6.0.2" -types-pyyaml = "^6.0.12.20240808" -scikit-learn = "^1.5.2" -structlog = "^24.4.0" -bitarray = "^3.0.0" -shapely = "^2.0.6" -click = "^8.1.7" -jinja2 = "3.1.6" - - -[tool.poetry.group.dev.dependencies] -taskipy = "^1.12.2" -pytest = "^8.3.2" -mypy = "^1.9.0" -types-protobuf = "^4.25.0.20240410" -ruff = "^0.4.4" -sphinx = "^8.1.3" -myst-parser = "^4.0.0" -sphinx-book-theme = "^1.1.3" -sphinx-copybutton = "^0.5.2" -sphinxcontrib-mermaid = "^1.0.0" -sphinx-togglebutton = "^0.3.2" -sphinx-intl = "^2.3.1" -sphinx-rtd-theme = "^3.0.2" [build-system] -requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" - -[tool.poetry.scripts] -adf-core-python = "adf_core_python.cli.cli:cli" +requires = ["uv_build>=0.8.2,<0.9.0"] +build-backend = "uv_build" + +[dependency-groups] +dev = [ + "mypy>=1.17.1", + "myst-parser>=4.0.1", + "pytest>=8.4.1", + "ruff>=0.12.5", + "sphinx>=8.2.3", + "sphinx-book-theme>=1.1.4", + "sphinx-copybutton>=0.5.2", + "sphinx-intl>=2.3.2", + "sphinx-rtd-theme>=3.0.2", + "sphinx-togglebutton>=0.3.2", + "sphinxcontrib-mermaid>=1.0.0", + "types-protobuf>=6.30.2.20250703", +] -[tool.taskipy.tasks] -format = "ruff format ." -lint = "ruff check ." -typecheck = "mypy ." -test = "pytest" -precommit = "task format && task lint && task typecheck && task test" [tool.ruff] # Exclude a variety of commonly ignored directories. @@ -82,11 +74,12 @@ exclude = [ "venv", "pb2", "docs", + "proto", ] # Same as Black. line-length = 88 -indent-width = 4 +indent-width = 2 # Assume Python 3.12 target-version = "py312" @@ -134,10 +127,12 @@ docstring-code-line-length = "dynamic" [tool.mypy] ignore_missing_imports = true -show_error_context = true # エラー時のメッセージを詳細表示 -show_column_numbers = true # エラー発生箇所の行数/列数を表示 -disallow_untyped_defs = true # 関数定義の引数/戻り値に型アノテーション必須 -no_implicit_optional = true # デフォルト引数に None を取る場合型アノテーションに Optional 必須 -check_untyped_defs = true # 型注釈がない関数やメソッドに対して型チェックを行う -warn_redundant_casts = true # 冗長なキャストに警告 -exclude = ["docs/*"] +show_error_context = true +show_column_numbers = true +disallow_untyped_defs = true +no_implicit_optional = true +check_untyped_defs = true +warn_redundant_casts = true + +[tool.uv.sources] +rcrscore = { git = "https://github.com/adf-python/rcrs-core-python" , tag = "v0.2.0" } diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..8d71127 --- /dev/null +++ b/uv.lock @@ -0,0 +1,947 @@ +version = 1 +revision = 2 +requires-python = ">=3.13" + +[[package]] +name = "accessible-pygments" +version = "0.0.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bc/c1/bbac6a50d02774f91572938964c582fff4270eee73ab822a4aeea4d8b11b/accessible_pygments-0.0.5.tar.gz", hash = "sha256:40918d3e6a2b619ad424cb91e556bd3bd8865443d9f22f1dcdf79e33c8046872", size = 1377899, upload-time = "2024-05-10T11:23:10.216Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8d/3f/95338030883d8c8b91223b4e21744b04d11b161a3ef117295d8241f50ab4/accessible_pygments-0.0.5-py3-none-any.whl", hash = "sha256:88ae3211e68a1d0b011504b2ffc1691feafce124b845bd072ab6f9f66f34d4b7", size = 1395903, upload-time = "2024-05-10T11:23:08.421Z" }, +] + +[[package]] +name = "adf-core-python" +version = "0.2.0" +source = { editable = "." } +dependencies = [ + { name = "bitarray" }, + { name = "click" }, + { name = "jinja2" }, + { name = "protobuf" }, + { name = "pyyaml" }, + { name = "rcrscore" }, + { name = "rtree" }, + { name = "scikit-learn" }, + { name = "shapely" }, + { name = "structlog" }, + { name = "types-pyyaml" }, +] + +[package.dev-dependencies] +dev = [ + { name = "mypy" }, + { name = "myst-parser" }, + { name = "pytest" }, + { name = "ruff" }, + { name = "sphinx" }, + { name = "sphinx-book-theme" }, + { name = "sphinx-copybutton" }, + { name = "sphinx-intl" }, + { name = "sphinx-rtd-theme" }, + { name = "sphinx-togglebutton" }, + { name = "sphinxcontrib-mermaid" }, + { name = "types-protobuf" }, +] + +[package.metadata] +requires-dist = [ + { name = "bitarray", specifier = ">=3.6.0" }, + { name = "click", specifier = ">=8.2.1" }, + { name = "jinja2", specifier = ">=3.1.6" }, + { name = "protobuf", specifier = ">=6.31.1" }, + { name = "pyyaml", specifier = ">=6.0.2" }, + { name = "rcrscore", git = "https://github.com/adf-python/rcrs-core-python?tag=v0.2.0" }, + { name = "rtree", specifier = ">=1.4.0" }, + { name = "scikit-learn", specifier = ">=1.7.1" }, + { name = "shapely", specifier = ">=2.1.1" }, + { name = "structlog", specifier = ">=25.4.0" }, + { name = "types-pyyaml", specifier = ">=6.0.12.20250516" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "mypy", specifier = ">=1.17.1" }, + { name = "myst-parser", specifier = ">=4.0.1" }, + { name = "pytest", specifier = ">=8.4.1" }, + { name = "ruff", specifier = ">=0.12.5" }, + { name = "sphinx", specifier = ">=8.2.3" }, + { name = "sphinx-book-theme", specifier = ">=1.1.4" }, + { name = "sphinx-copybutton", specifier = ">=0.5.2" }, + { name = "sphinx-intl", specifier = ">=2.3.2" }, + { name = "sphinx-rtd-theme", specifier = ">=3.0.2" }, + { name = "sphinx-togglebutton", specifier = ">=0.3.2" }, + { name = "sphinxcontrib-mermaid", specifier = ">=1.0.0" }, + { name = "types-protobuf", specifier = ">=6.30.2.20250703" }, +] + +[[package]] +name = "alabaster" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/f8/d9c74d0daf3f742840fd818d69cfae176fa332022fd44e3469487d5a9420/alabaster-1.0.0.tar.gz", hash = "sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e", size = 24210, upload-time = "2024-07-26T18:15:03.762Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b", size = 13929, upload-time = "2024-07-26T18:15:02.05Z" }, +] + +[[package]] +name = "babel" +version = "2.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/6b/d52e42361e1aa00709585ecc30b3f9684b3ab62530771402248b1b1d6240/babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d", size = 9951852, upload-time = "2025-02-01T15:17:41.026Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2", size = 10182537, upload-time = "2025-02-01T15:17:37.39Z" }, +] + +[[package]] +name = "beautifulsoup4" +version = "4.13.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "soupsieve" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d8/e4/0c4c39e18fd76d6a628d4dd8da40543d136ce2d1752bd6eeeab0791f4d6b/beautifulsoup4-4.13.4.tar.gz", hash = "sha256:dbb3c4e1ceae6aefebdaf2423247260cd062430a410e38c66f2baa50a8437195", size = 621067, upload-time = "2025-04-15T17:05:13.836Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/50/cd/30110dc0ffcf3b131156077b90e9f60ed75711223f306da4db08eff8403b/beautifulsoup4-4.13.4-py3-none-any.whl", hash = "sha256:9bbbb14bfde9d79f38b8cd5f8c7c85f4b8f2523190ebed90e950a8dea4cb1c4b", size = 187285, upload-time = "2025-04-15T17:05:12.221Z" }, +] + +[[package]] +name = "bitarray" +version = "3.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e5/ee/3b2fcbac3a4192e5d079aaa1850dff2f9ac625861c4c644819c2b34292ec/bitarray-3.6.0.tar.gz", hash = "sha256:20febc849a1f858e6a57a7d47b323fe9e727c579ddd526d317ad8831748a66a8", size = 147946, upload-time = "2025-07-29T18:03:56.681Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/2c/21066c7a97b2c88037b0fc04480fa13b0031c30c6f70452dc9c84fb2b087/bitarray-3.6.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3f96f57cea35ba19fd23a20b38fa0dfa3d87d582507129b8c8e314aa298f59b", size = 144156, upload-time = "2025-07-29T18:01:35.58Z" }, + { url = "https://files.pythonhosted.org/packages/34/a5/9cc42ea0c440ac1c2a65375688ac5891da12b3820f4a32440791d25ed668/bitarray-3.6.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:81e84054b22babcd6c5cc1eac0de2bfc1054ecdf742720cbfb36efbe89ec6c30", size = 140916, upload-time = "2025-07-29T18:01:36.67Z" }, + { url = "https://files.pythonhosted.org/packages/d7/66/709d259d855528213b1099facddb08d6108cb0074cf88dc357cdd07bacff/bitarray-3.6.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca643295bf5441dd38dadf7571ca4b63961820eedbffbe46ceba0893bf226203", size = 324713, upload-time = "2025-07-29T18:01:37.925Z" }, + { url = "https://files.pythonhosted.org/packages/6c/67/831e366ea4f0d52d622482b8475f87040cbc210d8f5f383935a4cc6363fe/bitarray-3.6.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:139963494fc3dd5caee5e38c0a03783ef50be118565e94b1dbb0210770f0b32d", size = 341300, upload-time = "2025-07-29T18:01:39.56Z" }, + { url = "https://files.pythonhosted.org/packages/66/c9/197375b63ca768ac8b1e624f27dc0eccdd451f94c6b9bf8950500d8da134/bitarray-3.6.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:243825f56b58bef28bfc602992a8c6d09bbc625628c195498d6020120d632a09", size = 333724, upload-time = "2025-07-29T18:01:40.861Z" }, + { url = "https://files.pythonhosted.org/packages/e1/23/96c882d798b8bc9d5354ad1fba18ad3ad4f3c0a661a296c8e51ca2941e0f/bitarray-3.6.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:583b46b3ba44121de5e87e95ae379932dc5fd2e37ebdf2c11a6d7975891425c1", size = 327276, upload-time = "2025-07-29T18:01:42.039Z" }, + { url = "https://files.pythonhosted.org/packages/20/8e/51751fe0e6f9fe7980b0467b471ba9ab8d1713a2a6576980d18143511656/bitarray-3.6.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f0be27d06732e2833b672a8fcc32fa195bdb22161eb88f8890de15e30264a01", size = 314903, upload-time = "2025-07-29T18:01:43.302Z" }, + { url = "https://files.pythonhosted.org/packages/49/7a/e4db9876e6e8bb261e64a384d3adb4372f13099b356e559cec85d022b897/bitarray-3.6.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:507e567aee4806576e20752f22533e8b7ec61e7e75062a7ce9222a0675aa0da6", size = 322551, upload-time = "2025-07-29T18:01:44.548Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5a/9460070e6cb671067cc2e115a82da6fc9ef0958542b98b07a5ed4a05a97b/bitarray-3.6.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:22188943a29072b684cd7c99e0b2cfc0af317cea3366c583d820507e6d1f2ed4", size = 316128, upload-time = "2025-07-29T18:01:45.789Z" }, + { url = "https://files.pythonhosted.org/packages/34/6f/f5d78c8e908750b9c3d5839eca2af5f6e99d6c7fe8a0498ef79a1af90bd8/bitarray-3.6.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f92462ea3888c99439f58f7561ecd5dd4cf8b8b1b259ccf5376667b8c46ee747", size = 339337, upload-time = "2025-07-29T18:01:47.684Z" }, + { url = "https://files.pythonhosted.org/packages/0d/d3/f740b601eae4e28e22d8560877fe9881f1b7a96fcb23b186e8580d328929/bitarray-3.6.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:3800f3c8c9780f281cf590543fd4b3278fea6988202273a260ecc58136895efb", size = 338607, upload-time = "2025-07-29T18:01:49.328Z" }, + { url = "https://files.pythonhosted.org/packages/4e/81/b9451089eea0ef66996852d2694b0f5afc0a76b1bc45c9a4f8204ae8674d/bitarray-3.6.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a50a66fa34dd7f9dcdbc7602a1b7bf6f9ab030b4f43e892324193423d9ede180", size = 324788, upload-time = "2025-07-29T18:01:51.454Z" }, + { url = "https://files.pythonhosted.org/packages/82/e8/80620fc60ad34bff647881a4f25c15b992c524e0f7af9c7c6c573b03556e/bitarray-3.6.0-cp313-cp313-win32.whl", hash = "sha256:afa24e5750c9b89ad5a7efef037efe49f4e339f20a94bf678c422c0c71e1207a", size = 137841, upload-time = "2025-07-29T18:01:52.95Z" }, + { url = "https://files.pythonhosted.org/packages/3b/ee/303be88b847da29a067babc690e231d7838520dc1af57d14dad5a7ca095c/bitarray-3.6.0-cp313-cp313-win_amd64.whl", hash = "sha256:e4c5e7edf1e7bcbde3b52058f171a411e2a24a081b3e951d685dfea4c3c383d5", size = 144820, upload-time = "2025-07-29T18:01:54.137Z" }, +] + +[[package]] +name = "certifi" +version = "2025.8.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/dc/67/960ebe6bf230a96cda2e0abcf73af550ec4f090005363542f0765df162e0/certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407", size = 162386, upload-time = "2025-08-03T03:07:47.08Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/48/1549795ba7742c948d2ad169c1c8cdbae65bc450d6cd753d124b17c8cd32/certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5", size = 161216, upload-time = "2025-08-03T03:07:45.777Z" }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e4/33/89c2ced2b67d1c2a61c19c6751aa8902d46ce3dacb23600a283619f5a12d/charset_normalizer-3.4.2.tar.gz", hash = "sha256:5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63", size = 126367, upload-time = "2025-05-02T08:34:42.01Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ea/12/a93df3366ed32db1d907d7593a94f1fe6293903e3e92967bebd6950ed12c/charset_normalizer-3.4.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:926ca93accd5d36ccdabd803392ddc3e03e6d4cd1cf17deff3b989ab8e9dbcf0", size = 199622, upload-time = "2025-05-02T08:32:56.363Z" }, + { url = "https://files.pythonhosted.org/packages/04/93/bf204e6f344c39d9937d3c13c8cd5bbfc266472e51fc8c07cb7f64fcd2de/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eba9904b0f38a143592d9fc0e19e2df0fa2e41c3c3745554761c5f6447eedabf", size = 143435, upload-time = "2025-05-02T08:32:58.551Z" }, + { url = "https://files.pythonhosted.org/packages/22/2a/ea8a2095b0bafa6c5b5a55ffdc2f924455233ee7b91c69b7edfcc9e02284/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3fddb7e2c84ac87ac3a947cb4e66d143ca5863ef48e4a5ecb83bd48619e4634e", size = 153653, upload-time = "2025-05-02T08:33:00.342Z" }, + { url = "https://files.pythonhosted.org/packages/b6/57/1b090ff183d13cef485dfbe272e2fe57622a76694061353c59da52c9a659/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98f862da73774290f251b9df8d11161b6cf25b599a66baf087c1ffe340e9bfd1", size = 146231, upload-time = "2025-05-02T08:33:02.081Z" }, + { url = "https://files.pythonhosted.org/packages/e2/28/ffc026b26f441fc67bd21ab7f03b313ab3fe46714a14b516f931abe1a2d8/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c9379d65defcab82d07b2a9dfbfc2e95bc8fe0ebb1b176a3190230a3ef0e07c", size = 148243, upload-time = "2025-05-02T08:33:04.063Z" }, + { url = "https://files.pythonhosted.org/packages/c0/0f/9abe9bd191629c33e69e47c6ef45ef99773320e9ad8e9cb08b8ab4a8d4cb/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e635b87f01ebc977342e2697d05b56632f5f879a4f15955dfe8cef2448b51691", size = 150442, upload-time = "2025-05-02T08:33:06.418Z" }, + { url = "https://files.pythonhosted.org/packages/67/7c/a123bbcedca91d5916c056407f89a7f5e8fdfce12ba825d7d6b9954a1a3c/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1c95a1e2902a8b722868587c0e1184ad5c55631de5afc0eb96bc4b0d738092c0", size = 145147, upload-time = "2025-05-02T08:33:08.183Z" }, + { url = "https://files.pythonhosted.org/packages/ec/fe/1ac556fa4899d967b83e9893788e86b6af4d83e4726511eaaad035e36595/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ef8de666d6179b009dce7bcb2ad4c4a779f113f12caf8dc77f0162c29d20490b", size = 153057, upload-time = "2025-05-02T08:33:09.986Z" }, + { url = "https://files.pythonhosted.org/packages/2b/ff/acfc0b0a70b19e3e54febdd5301a98b72fa07635e56f24f60502e954c461/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:32fc0341d72e0f73f80acb0a2c94216bd704f4f0bce10aedea38f30502b271ff", size = 156454, upload-time = "2025-05-02T08:33:11.814Z" }, + { url = "https://files.pythonhosted.org/packages/92/08/95b458ce9c740d0645feb0e96cea1f5ec946ea9c580a94adfe0b617f3573/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:289200a18fa698949d2b39c671c2cc7a24d44096784e76614899a7ccf2574b7b", size = 154174, upload-time = "2025-05-02T08:33:13.707Z" }, + { url = "https://files.pythonhosted.org/packages/78/be/8392efc43487ac051eee6c36d5fbd63032d78f7728cb37aebcc98191f1ff/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a476b06fbcf359ad25d34a057b7219281286ae2477cc5ff5e3f70a246971148", size = 149166, upload-time = "2025-05-02T08:33:15.458Z" }, + { url = "https://files.pythonhosted.org/packages/44/96/392abd49b094d30b91d9fbda6a69519e95802250b777841cf3bda8fe136c/charset_normalizer-3.4.2-cp313-cp313-win32.whl", hash = "sha256:aaeeb6a479c7667fbe1099af9617c83aaca22182d6cf8c53966491a0f1b7ffb7", size = 98064, upload-time = "2025-05-02T08:33:17.06Z" }, + { url = "https://files.pythonhosted.org/packages/e9/b0/0200da600134e001d91851ddc797809e2fe0ea72de90e09bec5a2fbdaccb/charset_normalizer-3.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:aa6af9e7d59f9c12b33ae4e9450619cf2488e2bbe9b44030905877f0b2324980", size = 105641, upload-time = "2025-05-02T08:33:18.753Z" }, + { url = "https://files.pythonhosted.org/packages/20/94/c5790835a017658cbfabd07f3bfb549140c3ac458cfc196323996b10095a/charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0", size = 52626, upload-time = "2025-05-02T08:34:40.053Z" }, +] + +[[package]] +name = "click" +version = "8.2.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/60/6c/8ca2efa64cf75a977a0d7fac081354553ebe483345c734fb6b6515d96bbc/click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202", size = 286342, upload-time = "2025-05-20T23:19:49.832Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/32/10bb5764d90a8eee674e9dc6f4db6a0ab47c8c4d0d83c27f7c39ac415a4d/click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b", size = 102215, upload-time = "2025-05-20T23:19:47.796Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "docutils" +version = "0.21.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/ed/aefcc8cd0ba62a0560c3c18c33925362d46c6075480bfa4df87b28e169a9/docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", size = 2204444, upload-time = "2024-04-23T18:57:18.24Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2", size = 587408, upload-time = "2024-04-23T18:57:14.835Z" }, +] + +[[package]] +name = "idna" +version = "3.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, +] + +[[package]] +name = "imagesize" +version = "1.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/84/62473fb57d61e31fef6e36d64a179c8781605429fd927b5dd608c997be31/imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a", size = 1280026, upload-time = "2022-07-01T12:21:05.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b", size = 8769, upload-time = "2022-07-01T12:21:02.467Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + +[[package]] +name = "joblib" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/dc/fe/0f5a938c54105553436dbff7a61dc4fed4b1b2c98852f8833beaf4d5968f/joblib-1.5.1.tar.gz", hash = "sha256:f4f86e351f39fe3d0d32a9f2c3d8af1ee4cec285aafcb27003dda5205576b444", size = 330475, upload-time = "2025-05-23T12:04:37.097Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7d/4f/1195bbac8e0c2acc5f740661631d8d750dc38d4a32b23ee5df3cde6f4e0d/joblib-1.5.1-py3-none-any.whl", hash = "sha256:4719a31f054c7d766948dcd83e9613686b27114f190f717cec7eaa2084f8a74a", size = 307746, upload-time = "2025-05-23T12:04:35.124Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload-time = "2023-06-03T06:41:14.443Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528, upload-time = "2023-06-03T06:41:11.019Z" }, +] + +[[package]] +name = "markupsafe" +version = "3.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload-time = "2024-10-18T15:21:54.129Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274, upload-time = "2024-10-18T15:21:24.577Z" }, + { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352, upload-time = "2024-10-18T15:21:25.382Z" }, + { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122, upload-time = "2024-10-18T15:21:26.199Z" }, + { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085, upload-time = "2024-10-18T15:21:27.029Z" }, + { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978, upload-time = "2024-10-18T15:21:27.846Z" }, + { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208, upload-time = "2024-10-18T15:21:28.744Z" }, + { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357, upload-time = "2024-10-18T15:21:29.545Z" }, + { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344, upload-time = "2024-10-18T15:21:30.366Z" }, + { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101, upload-time = "2024-10-18T15:21:31.207Z" }, + { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603, upload-time = "2024-10-18T15:21:32.032Z" }, + { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510, upload-time = "2024-10-18T15:21:33.625Z" }, + { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486, upload-time = "2024-10-18T15:21:34.611Z" }, + { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480, upload-time = "2024-10-18T15:21:35.398Z" }, + { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914, upload-time = "2024-10-18T15:21:36.231Z" }, + { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796, upload-time = "2024-10-18T15:21:37.073Z" }, + { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473, upload-time = "2024-10-18T15:21:37.932Z" }, + { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114, upload-time = "2024-10-18T15:21:39.799Z" }, + { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098, upload-time = "2024-10-18T15:21:40.813Z" }, + { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208, upload-time = "2024-10-18T15:21:41.814Z" }, + { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739, upload-time = "2024-10-18T15:21:42.784Z" }, +] + +[[package]] +name = "mdit-py-plugins" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/03/a2ecab526543b152300717cf232bb4bb8605b6edb946c845016fa9c9c9fd/mdit_py_plugins-0.4.2.tar.gz", hash = "sha256:5f2cd1fdb606ddf152d37ec30e46101a60512bc0e5fa1a7002c36647b09e26b5", size = 43542, upload-time = "2024-09-09T20:27:49.564Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/f7/7782a043553ee469c1ff49cfa1cdace2d6bf99a1f333cf38676b3ddf30da/mdit_py_plugins-0.4.2-py3-none-any.whl", hash = "sha256:0c673c3f889399a33b95e88d2f0d111b4447bdfea7f237dab2d488f459835636", size = 55316, upload-time = "2024-09-09T20:27:48.397Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "mypy" +version = "1.17.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mypy-extensions" }, + { name = "pathspec" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8e/22/ea637422dedf0bf36f3ef238eab4e455e2a0dcc3082b5cc067615347ab8e/mypy-1.17.1.tar.gz", hash = "sha256:25e01ec741ab5bb3eec8ba9cdb0f769230368a22c959c4937360efb89b7e9f01", size = 3352570, upload-time = "2025-07-31T07:54:19.204Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5b/82/aec2fc9b9b149f372850291827537a508d6c4d3664b1750a324b91f71355/mypy-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93378d3203a5c0800c6b6d850ad2f19f7a3cdf1a3701d3416dbf128805c6a6a7", size = 11075338, upload-time = "2025-07-31T07:53:38.873Z" }, + { url = "https://files.pythonhosted.org/packages/07/ac/ee93fbde9d2242657128af8c86f5d917cd2887584cf948a8e3663d0cd737/mypy-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:15d54056f7fe7a826d897789f53dd6377ec2ea8ba6f776dc83c2902b899fee81", size = 10113066, upload-time = "2025-07-31T07:54:14.707Z" }, + { url = "https://files.pythonhosted.org/packages/5a/68/946a1e0be93f17f7caa56c45844ec691ca153ee8b62f21eddda336a2d203/mypy-1.17.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:209a58fed9987eccc20f2ca94afe7257a8f46eb5df1fb69958650973230f91e6", size = 11875473, upload-time = "2025-07-31T07:53:14.504Z" }, + { url = "https://files.pythonhosted.org/packages/9f/0f/478b4dce1cb4f43cf0f0d00fba3030b21ca04a01b74d1cd272a528cf446f/mypy-1.17.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:099b9a5da47de9e2cb5165e581f158e854d9e19d2e96b6698c0d64de911dd849", size = 12744296, upload-time = "2025-07-31T07:53:03.896Z" }, + { url = "https://files.pythonhosted.org/packages/ca/70/afa5850176379d1b303f992a828de95fc14487429a7139a4e0bdd17a8279/mypy-1.17.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa6ffadfbe6994d724c5a1bb6123a7d27dd68fc9c059561cd33b664a79578e14", size = 12914657, upload-time = "2025-07-31T07:54:08.576Z" }, + { url = "https://files.pythonhosted.org/packages/53/f9/4a83e1c856a3d9c8f6edaa4749a4864ee98486e9b9dbfbc93842891029c2/mypy-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:9a2b7d9180aed171f033c9f2fc6c204c1245cf60b0cb61cf2e7acc24eea78e0a", size = 9593320, upload-time = "2025-07-31T07:53:01.341Z" }, + { url = "https://files.pythonhosted.org/packages/38/56/79c2fac86da57c7d8c48622a05873eaab40b905096c33597462713f5af90/mypy-1.17.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:15a83369400454c41ed3a118e0cc58bd8123921a602f385cb6d6ea5df050c733", size = 11040037, upload-time = "2025-07-31T07:54:10.942Z" }, + { url = "https://files.pythonhosted.org/packages/4d/c3/adabe6ff53638e3cad19e3547268482408323b1e68bf082c9119000cd049/mypy-1.17.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:55b918670f692fc9fba55c3298d8a3beae295c5cded0a55dccdc5bbead814acd", size = 10131550, upload-time = "2025-07-31T07:53:41.307Z" }, + { url = "https://files.pythonhosted.org/packages/b8/c5/2e234c22c3bdeb23a7817af57a58865a39753bde52c74e2c661ee0cfc640/mypy-1.17.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:62761474061feef6f720149d7ba876122007ddc64adff5ba6f374fda35a018a0", size = 11872963, upload-time = "2025-07-31T07:53:16.878Z" }, + { url = "https://files.pythonhosted.org/packages/ab/26/c13c130f35ca8caa5f2ceab68a247775648fdcd6c9a18f158825f2bc2410/mypy-1.17.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c49562d3d908fd49ed0938e5423daed8d407774a479b595b143a3d7f87cdae6a", size = 12710189, upload-time = "2025-07-31T07:54:01.962Z" }, + { url = "https://files.pythonhosted.org/packages/82/df/c7d79d09f6de8383fe800521d066d877e54d30b4fb94281c262be2df84ef/mypy-1.17.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:397fba5d7616a5bc60b45c7ed204717eaddc38f826e3645402c426057ead9a91", size = 12900322, upload-time = "2025-07-31T07:53:10.551Z" }, + { url = "https://files.pythonhosted.org/packages/b8/98/3d5a48978b4f708c55ae832619addc66d677f6dc59f3ebad71bae8285ca6/mypy-1.17.1-cp314-cp314-win_amd64.whl", hash = "sha256:9d6b20b97d373f41617bd0708fd46aa656059af57f2ef72aa8c7d6a2b73b74ed", size = 9751879, upload-time = "2025-07-31T07:52:56.683Z" }, + { url = "https://files.pythonhosted.org/packages/1d/f3/8fcd2af0f5b806f6cf463efaffd3c9548a28f84220493ecd38d127b6b66d/mypy-1.17.1-py3-none-any.whl", hash = "sha256:a9f52c0351c21fe24c21d8c0eb1f62967b262d6729393397b6f443c3b773c3b9", size = 2283411, upload-time = "2025-07-31T07:53:24.664Z" }, +] + +[[package]] +name = "mypy-extensions" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, +] + +[[package]] +name = "myst-parser" +version = "4.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils" }, + { name = "jinja2" }, + { name = "markdown-it-py" }, + { name = "mdit-py-plugins" }, + { name = "pyyaml" }, + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/a5/9626ba4f73555b3735ad86247a8077d4603aa8628537687c839ab08bfe44/myst_parser-4.0.1.tar.gz", hash = "sha256:5cfea715e4f3574138aecbf7d54132296bfd72bb614d31168f48c477a830a7c4", size = 93985, upload-time = "2025-02-12T10:53:03.833Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/df/76d0321c3797b54b60fef9ec3bd6f4cfd124b9e422182156a1dd418722cf/myst_parser-4.0.1-py3-none-any.whl", hash = "sha256:9134e88959ec3b5780aedf8a99680ea242869d012e8821db3126d427edc9c95d", size = 84579, upload-time = "2025-02-12T10:53:02.078Z" }, +] + +[[package]] +name = "numpy" +version = "2.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/37/7d/3fec4199c5ffb892bed55cff901e4f39a58c81df9c44c280499e92cad264/numpy-2.3.2.tar.gz", hash = "sha256:e0486a11ec30cdecb53f184d496d1c6a20786c81e55e41640270130056f8ee48", size = 20489306, upload-time = "2025-07-24T21:32:07.553Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1c/c0/c6bb172c916b00700ed3bf71cb56175fd1f7dbecebf8353545d0b5519f6c/numpy-2.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c8d9727f5316a256425892b043736d63e89ed15bbfe6556c5ff4d9d4448ff3b3", size = 20949074, upload-time = "2025-07-24T20:43:07.813Z" }, + { url = "https://files.pythonhosted.org/packages/20/4e/c116466d22acaf4573e58421c956c6076dc526e24a6be0903219775d862e/numpy-2.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:efc81393f25f14d11c9d161e46e6ee348637c0a1e8a54bf9dedc472a3fae993b", size = 14177311, upload-time = "2025-07-24T20:43:29.335Z" }, + { url = "https://files.pythonhosted.org/packages/78/45/d4698c182895af189c463fc91d70805d455a227261d950e4e0f1310c2550/numpy-2.3.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:dd937f088a2df683cbb79dda9a772b62a3e5a8a7e76690612c2737f38c6ef1b6", size = 5106022, upload-time = "2025-07-24T20:43:37.999Z" }, + { url = "https://files.pythonhosted.org/packages/9f/76/3e6880fef4420179309dba72a8c11f6166c431cf6dee54c577af8906f914/numpy-2.3.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:11e58218c0c46c80509186e460d79fbdc9ca1eb8d8aee39d8f2dc768eb781089", size = 6640135, upload-time = "2025-07-24T20:43:49.28Z" }, + { url = "https://files.pythonhosted.org/packages/34/fa/87ff7f25b3c4ce9085a62554460b7db686fef1e0207e8977795c7b7d7ba1/numpy-2.3.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5ad4ebcb683a1f99f4f392cc522ee20a18b2bb12a2c1c42c3d48d5a1adc9d3d2", size = 14278147, upload-time = "2025-07-24T20:44:10.328Z" }, + { url = "https://files.pythonhosted.org/packages/1d/0f/571b2c7a3833ae419fe69ff7b479a78d313581785203cc70a8db90121b9a/numpy-2.3.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:938065908d1d869c7d75d8ec45f735a034771c6ea07088867f713d1cd3bbbe4f", size = 16635989, upload-time = "2025-07-24T20:44:34.88Z" }, + { url = "https://files.pythonhosted.org/packages/24/5a/84ae8dca9c9a4c592fe11340b36a86ffa9fd3e40513198daf8a97839345c/numpy-2.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:66459dccc65d8ec98cc7df61307b64bf9e08101f9598755d42d8ae65d9a7a6ee", size = 16053052, upload-time = "2025-07-24T20:44:58.872Z" }, + { url = "https://files.pythonhosted.org/packages/57/7c/e5725d99a9133b9813fcf148d3f858df98511686e853169dbaf63aec6097/numpy-2.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a7af9ed2aa9ec5950daf05bb11abc4076a108bd3c7db9aa7251d5f107079b6a6", size = 18577955, upload-time = "2025-07-24T20:45:26.714Z" }, + { url = "https://files.pythonhosted.org/packages/ae/11/7c546fcf42145f29b71e4d6f429e96d8d68e5a7ba1830b2e68d7418f0bbd/numpy-2.3.2-cp313-cp313-win32.whl", hash = "sha256:906a30249315f9c8e17b085cc5f87d3f369b35fedd0051d4a84686967bdbbd0b", size = 6311843, upload-time = "2025-07-24T20:49:24.444Z" }, + { url = "https://files.pythonhosted.org/packages/aa/6f/a428fd1cb7ed39b4280d057720fed5121b0d7754fd2a9768640160f5517b/numpy-2.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:c63d95dc9d67b676e9108fe0d2182987ccb0f11933c1e8959f42fa0da8d4fa56", size = 12782876, upload-time = "2025-07-24T20:49:43.227Z" }, + { url = "https://files.pythonhosted.org/packages/65/85/4ea455c9040a12595fb6c43f2c217257c7b52dd0ba332c6a6c1d28b289fe/numpy-2.3.2-cp313-cp313-win_arm64.whl", hash = "sha256:b05a89f2fb84d21235f93de47129dd4f11c16f64c87c33f5e284e6a3a54e43f2", size = 10192786, upload-time = "2025-07-24T20:49:59.443Z" }, + { url = "https://files.pythonhosted.org/packages/80/23/8278f40282d10c3f258ec3ff1b103d4994bcad78b0cba9208317f6bb73da/numpy-2.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4e6ecfeddfa83b02318f4d84acf15fbdbf9ded18e46989a15a8b6995dfbf85ab", size = 21047395, upload-time = "2025-07-24T20:45:58.821Z" }, + { url = "https://files.pythonhosted.org/packages/1f/2d/624f2ce4a5df52628b4ccd16a4f9437b37c35f4f8a50d00e962aae6efd7a/numpy-2.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:508b0eada3eded10a3b55725b40806a4b855961040180028f52580c4729916a2", size = 14300374, upload-time = "2025-07-24T20:46:20.207Z" }, + { url = "https://files.pythonhosted.org/packages/f6/62/ff1e512cdbb829b80a6bd08318a58698867bca0ca2499d101b4af063ee97/numpy-2.3.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:754d6755d9a7588bdc6ac47dc4ee97867271b17cee39cb87aef079574366db0a", size = 5228864, upload-time = "2025-07-24T20:46:30.58Z" }, + { url = "https://files.pythonhosted.org/packages/7d/8e/74bc18078fff03192d4032cfa99d5a5ca937807136d6f5790ce07ca53515/numpy-2.3.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:a9f66e7d2b2d7712410d3bc5684149040ef5f19856f20277cd17ea83e5006286", size = 6737533, upload-time = "2025-07-24T20:46:46.111Z" }, + { url = "https://files.pythonhosted.org/packages/19/ea/0731efe2c9073ccca5698ef6a8c3667c4cf4eea53fcdcd0b50140aba03bc/numpy-2.3.2-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de6ea4e5a65d5a90c7d286ddff2b87f3f4ad61faa3db8dabe936b34c2275b6f8", size = 14352007, upload-time = "2025-07-24T20:47:07.1Z" }, + { url = "https://files.pythonhosted.org/packages/cf/90/36be0865f16dfed20f4bc7f75235b963d5939707d4b591f086777412ff7b/numpy-2.3.2-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3ef07ec8cbc8fc9e369c8dcd52019510c12da4de81367d8b20bc692aa07573a", size = 16701914, upload-time = "2025-07-24T20:47:32.459Z" }, + { url = "https://files.pythonhosted.org/packages/94/30/06cd055e24cb6c38e5989a9e747042b4e723535758e6153f11afea88c01b/numpy-2.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:27c9f90e7481275c7800dc9c24b7cc40ace3fdb970ae4d21eaff983a32f70c91", size = 16132708, upload-time = "2025-07-24T20:47:58.129Z" }, + { url = "https://files.pythonhosted.org/packages/9a/14/ecede608ea73e58267fd7cb78f42341b3b37ba576e778a1a06baffbe585c/numpy-2.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:07b62978075b67eee4065b166d000d457c82a1efe726cce608b9db9dd66a73a5", size = 18651678, upload-time = "2025-07-24T20:48:25.402Z" }, + { url = "https://files.pythonhosted.org/packages/40/f3/2fe6066b8d07c3685509bc24d56386534c008b462a488b7f503ba82b8923/numpy-2.3.2-cp313-cp313t-win32.whl", hash = "sha256:c771cfac34a4f2c0de8e8c97312d07d64fd8f8ed45bc9f5726a7e947270152b5", size = 6441832, upload-time = "2025-07-24T20:48:37.181Z" }, + { url = "https://files.pythonhosted.org/packages/0b/ba/0937d66d05204d8f28630c9c60bc3eda68824abde4cf756c4d6aad03b0c6/numpy-2.3.2-cp313-cp313t-win_amd64.whl", hash = "sha256:72dbebb2dcc8305c431b2836bcc66af967df91be793d63a24e3d9b741374c450", size = 12927049, upload-time = "2025-07-24T20:48:56.24Z" }, + { url = "https://files.pythonhosted.org/packages/e9/ed/13542dd59c104d5e654dfa2ac282c199ba64846a74c2c4bcdbc3a0f75df1/numpy-2.3.2-cp313-cp313t-win_arm64.whl", hash = "sha256:72c6df2267e926a6d5286b0a6d556ebe49eae261062059317837fda12ddf0c1a", size = 10262935, upload-time = "2025-07-24T20:49:13.136Z" }, + { url = "https://files.pythonhosted.org/packages/c9/7c/7659048aaf498f7611b783e000c7268fcc4dcf0ce21cd10aad7b2e8f9591/numpy-2.3.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:448a66d052d0cf14ce9865d159bfc403282c9bc7bb2a31b03cc18b651eca8b1a", size = 20950906, upload-time = "2025-07-24T20:50:30.346Z" }, + { url = "https://files.pythonhosted.org/packages/80/db/984bea9d4ddf7112a04cfdfb22b1050af5757864cfffe8e09e44b7f11a10/numpy-2.3.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:546aaf78e81b4081b2eba1d105c3b34064783027a06b3ab20b6eba21fb64132b", size = 14185607, upload-time = "2025-07-24T20:50:51.923Z" }, + { url = "https://files.pythonhosted.org/packages/e4/76/b3d6f414f4eca568f469ac112a3b510938d892bc5a6c190cb883af080b77/numpy-2.3.2-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:87c930d52f45df092f7578889711a0768094debf73cfcde105e2d66954358125", size = 5114110, upload-time = "2025-07-24T20:51:01.041Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d2/6f5e6826abd6bca52392ed88fe44a4b52aacb60567ac3bc86c67834c3a56/numpy-2.3.2-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:8dc082ea901a62edb8f59713c6a7e28a85daddcb67454c839de57656478f5b19", size = 6642050, upload-time = "2025-07-24T20:51:11.64Z" }, + { url = "https://files.pythonhosted.org/packages/c4/43/f12b2ade99199e39c73ad182f103f9d9791f48d885c600c8e05927865baf/numpy-2.3.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:af58de8745f7fa9ca1c0c7c943616c6fe28e75d0c81f5c295810e3c83b5be92f", size = 14296292, upload-time = "2025-07-24T20:51:33.488Z" }, + { url = "https://files.pythonhosted.org/packages/5d/f9/77c07d94bf110a916b17210fac38680ed8734c236bfed9982fd8524a7b47/numpy-2.3.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed5527c4cf10f16c6d0b6bee1f89958bccb0ad2522c8cadc2efd318bcd545f5", size = 16638913, upload-time = "2025-07-24T20:51:58.517Z" }, + { url = "https://files.pythonhosted.org/packages/9b/d1/9d9f2c8ea399cc05cfff8a7437453bd4e7d894373a93cdc46361bbb49a7d/numpy-2.3.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:095737ed986e00393ec18ec0b21b47c22889ae4b0cd2d5e88342e08b01141f58", size = 16071180, upload-time = "2025-07-24T20:52:22.827Z" }, + { url = "https://files.pythonhosted.org/packages/4c/41/82e2c68aff2a0c9bf315e47d61951099fed65d8cb2c8d9dc388cb87e947e/numpy-2.3.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5e40e80299607f597e1a8a247ff8d71d79c5b52baa11cc1cce30aa92d2da6e0", size = 18576809, upload-time = "2025-07-24T20:52:51.015Z" }, + { url = "https://files.pythonhosted.org/packages/14/14/4b4fd3efb0837ed252d0f583c5c35a75121038a8c4e065f2c259be06d2d8/numpy-2.3.2-cp314-cp314-win32.whl", hash = "sha256:7d6e390423cc1f76e1b8108c9b6889d20a7a1f59d9a60cac4a050fa734d6c1e2", size = 6366410, upload-time = "2025-07-24T20:56:44.949Z" }, + { url = "https://files.pythonhosted.org/packages/11/9e/b4c24a6b8467b61aced5c8dc7dcfce23621baa2e17f661edb2444a418040/numpy-2.3.2-cp314-cp314-win_amd64.whl", hash = "sha256:b9d0878b21e3918d76d2209c924ebb272340da1fb51abc00f986c258cd5e957b", size = 12918821, upload-time = "2025-07-24T20:57:06.479Z" }, + { url = "https://files.pythonhosted.org/packages/0e/0f/0dc44007c70b1007c1cef86b06986a3812dd7106d8f946c09cfa75782556/numpy-2.3.2-cp314-cp314-win_arm64.whl", hash = "sha256:2738534837c6a1d0c39340a190177d7d66fdf432894f469728da901f8f6dc910", size = 10477303, upload-time = "2025-07-24T20:57:22.879Z" }, + { url = "https://files.pythonhosted.org/packages/8b/3e/075752b79140b78ddfc9c0a1634d234cfdbc6f9bbbfa6b7504e445ad7d19/numpy-2.3.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:4d002ecf7c9b53240be3bb69d80f86ddbd34078bae04d87be81c1f58466f264e", size = 21047524, upload-time = "2025-07-24T20:53:22.086Z" }, + { url = "https://files.pythonhosted.org/packages/fe/6d/60e8247564a72426570d0e0ea1151b95ce5bd2f1597bb878a18d32aec855/numpy-2.3.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:293b2192c6bcce487dbc6326de5853787f870aeb6c43f8f9c6496db5b1781e45", size = 14300519, upload-time = "2025-07-24T20:53:44.053Z" }, + { url = "https://files.pythonhosted.org/packages/4d/73/d8326c442cd428d47a067070c3ac6cc3b651a6e53613a1668342a12d4479/numpy-2.3.2-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:0a4f2021a6da53a0d580d6ef5db29947025ae8b35b3250141805ea9a32bbe86b", size = 5228972, upload-time = "2025-07-24T20:53:53.81Z" }, + { url = "https://files.pythonhosted.org/packages/34/2e/e71b2d6dad075271e7079db776196829019b90ce3ece5c69639e4f6fdc44/numpy-2.3.2-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:9c144440db4bf3bb6372d2c3e49834cc0ff7bb4c24975ab33e01199e645416f2", size = 6737439, upload-time = "2025-07-24T20:54:04.742Z" }, + { url = "https://files.pythonhosted.org/packages/15/b0/d004bcd56c2c5e0500ffc65385eb6d569ffd3363cb5e593ae742749b2daa/numpy-2.3.2-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f92d6c2a8535dc4fe4419562294ff957f83a16ebdec66df0805e473ffaad8bd0", size = 14352479, upload-time = "2025-07-24T20:54:25.819Z" }, + { url = "https://files.pythonhosted.org/packages/11/e3/285142fcff8721e0c99b51686426165059874c150ea9ab898e12a492e291/numpy-2.3.2-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cefc2219baa48e468e3db7e706305fcd0c095534a192a08f31e98d83a7d45fb0", size = 16702805, upload-time = "2025-07-24T20:54:50.814Z" }, + { url = "https://files.pythonhosted.org/packages/33/c3/33b56b0e47e604af2c7cd065edca892d180f5899599b76830652875249a3/numpy-2.3.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:76c3e9501ceb50b2ff3824c3589d5d1ab4ac857b0ee3f8f49629d0de55ecf7c2", size = 16133830, upload-time = "2025-07-24T20:55:17.306Z" }, + { url = "https://files.pythonhosted.org/packages/6e/ae/7b1476a1f4d6a48bc669b8deb09939c56dd2a439db1ab03017844374fb67/numpy-2.3.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:122bf5ed9a0221b3419672493878ba4967121514b1d7d4656a7580cd11dddcbf", size = 18652665, upload-time = "2025-07-24T20:55:46.665Z" }, + { url = "https://files.pythonhosted.org/packages/14/ba/5b5c9978c4bb161034148ade2de9db44ec316fab89ce8c400db0e0c81f86/numpy-2.3.2-cp314-cp314t-win32.whl", hash = "sha256:6f1ae3dcb840edccc45af496f312528c15b1f79ac318169d094e85e4bb35fdf1", size = 6514777, upload-time = "2025-07-24T20:55:57.66Z" }, + { url = "https://files.pythonhosted.org/packages/eb/46/3dbaf0ae7c17cdc46b9f662c56da2054887b8d9e737c1476f335c83d33db/numpy-2.3.2-cp314-cp314t-win_amd64.whl", hash = "sha256:087ffc25890d89a43536f75c5fe8770922008758e8eeeef61733957041ed2f9b", size = 13111856, upload-time = "2025-07-24T20:56:17.318Z" }, + { url = "https://files.pythonhosted.org/packages/c1/9e/1652778bce745a67b5fe05adde60ed362d38eb17d919a540e813d30f6874/numpy-2.3.2-cp314-cp314t-win_arm64.whl", hash = "sha256:092aeb3449833ea9c0bf0089d70c29ae480685dd2377ec9cdbbb620257f84631", size = 10544226, upload-time = "2025-07-24T20:56:34.509Z" }, +] + +[[package]] +name = "packaging" +version = "25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, +] + +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "protobuf" +version = "6.31.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/52/f3/b9655a711b32c19720253f6f06326faf90580834e2e83f840472d752bc8b/protobuf-6.31.1.tar.gz", hash = "sha256:d8cac4c982f0b957a4dc73a80e2ea24fab08e679c0de9deb835f4a12d69aca9a", size = 441797, upload-time = "2025-05-28T19:25:54.947Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f3/6f/6ab8e4bf962fd5570d3deaa2d5c38f0a363f57b4501047b5ebeb83ab1125/protobuf-6.31.1-cp310-abi3-win32.whl", hash = "sha256:7fa17d5a29c2e04b7d90e5e32388b8bfd0e7107cd8e616feef7ed3fa6bdab5c9", size = 423603, upload-time = "2025-05-28T19:25:41.198Z" }, + { url = "https://files.pythonhosted.org/packages/44/3a/b15c4347dd4bf3a1b0ee882f384623e2063bb5cf9fa9d57990a4f7df2fb6/protobuf-6.31.1-cp310-abi3-win_amd64.whl", hash = "sha256:426f59d2964864a1a366254fa703b8632dcec0790d8862d30034d8245e1cd447", size = 435283, upload-time = "2025-05-28T19:25:44.275Z" }, + { url = "https://files.pythonhosted.org/packages/6a/c9/b9689a2a250264a84e66c46d8862ba788ee7a641cdca39bccf64f59284b7/protobuf-6.31.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:6f1227473dc43d44ed644425268eb7c2e488ae245d51c6866d19fe158e207402", size = 425604, upload-time = "2025-05-28T19:25:45.702Z" }, + { url = "https://files.pythonhosted.org/packages/76/a1/7a5a94032c83375e4fe7e7f56e3976ea6ac90c5e85fac8576409e25c39c3/protobuf-6.31.1-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:a40fc12b84c154884d7d4c4ebd675d5b3b5283e155f324049ae396b95ddebc39", size = 322115, upload-time = "2025-05-28T19:25:47.128Z" }, + { url = "https://files.pythonhosted.org/packages/fa/b1/b59d405d64d31999244643d88c45c8241c58f17cc887e73bcb90602327f8/protobuf-6.31.1-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:4ee898bf66f7a8b0bd21bce523814e6fbd8c6add948045ce958b73af7e8878c6", size = 321070, upload-time = "2025-05-28T19:25:50.036Z" }, + { url = "https://files.pythonhosted.org/packages/f7/af/ab3c51ab7507a7325e98ffe691d9495ee3d3aa5f589afad65ec920d39821/protobuf-6.31.1-py3-none-any.whl", hash = "sha256:720a6c7e6b77288b85063569baae8536671b39f15cc22037ec7045658d80489e", size = 168724, upload-time = "2025-05-28T19:25:53.926Z" }, +] + +[[package]] +name = "pydata-sphinx-theme" +version = "0.15.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "accessible-pygments" }, + { name = "babel" }, + { name = "beautifulsoup4" }, + { name = "docutils" }, + { name = "packaging" }, + { name = "pygments" }, + { name = "sphinx" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/67/ea/3ab478cccacc2e8ef69892c42c44ae547bae089f356c4b47caf61730958d/pydata_sphinx_theme-0.15.4.tar.gz", hash = "sha256:7762ec0ac59df3acecf49fd2f889e1b4565dbce8b88b2e29ee06fdd90645a06d", size = 2400673, upload-time = "2024-06-25T19:28:45.041Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/d3/c622950d87a2ffd1654208733b5bd1c5645930014abed8f4c0d74863988b/pydata_sphinx_theme-0.15.4-py3-none-any.whl", hash = "sha256:2136ad0e9500d0949f96167e63f3e298620040aea8f9c74621959eda5d4cf8e6", size = 4640157, upload-time = "2024-06-25T19:28:42.383Z" }, +] + +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + +[[package]] +name = "pytest" +version = "8.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload-time = "2025-06-18T05:48:06.109Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474, upload-time = "2025-06-18T05:48:03.955Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" }, + { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" }, + { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" }, + { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" }, + { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" }, + { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" }, + { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" }, + { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" }, +] + +[[package]] +name = "rcrscore" +version = "0.1.0" +source = { git = "https://github.com/adf-python/rcrs-core-python?tag=v0.2.0#d8227cfcfb479c020fd0354a923aefcb6f2573df" } +dependencies = [ + { name = "protobuf" }, + { name = "rtree" }, +] + +[[package]] +name = "requests" +version = "2.32.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e1/0a/929373653770d8a0d7ea76c37de6e41f11eb07559b103b1c02cafb3f7cf8/requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422", size = 135258, upload-time = "2025-06-09T16:43:07.34Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7c/e4/56027c4a6b4ae70ca9de302488c5ca95ad4a39e190093d6c1a8ace08341b/requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c", size = 64847, upload-time = "2025-06-09T16:43:05.728Z" }, +] + +[[package]] +name = "roman-numerals-py" +version = "3.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/76/48fd56d17c5bdbdf65609abbc67288728a98ed4c02919428d4f52d23b24b/roman_numerals_py-3.1.0.tar.gz", hash = "sha256:be4bf804f083a4ce001b5eb7e3c0862479d10f94c936f6c4e5f250aa5ff5bd2d", size = 9017, upload-time = "2025-02-22T07:34:54.333Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/53/97/d2cbbaa10c9b826af0e10fdf836e1bf344d9f0abb873ebc34d1f49642d3f/roman_numerals_py-3.1.0-py3-none-any.whl", hash = "sha256:9da2ad2fb670bcf24e81070ceb3be72f6c11c440d73bd579fbeca1e9f330954c", size = 7742, upload-time = "2025-02-22T07:34:52.422Z" }, +] + +[[package]] +name = "rtree" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/b8/0091f020acafcb034daa5b062f0626f6a73c7e0d64826af23861390a9585/rtree-1.4.0.tar.gz", hash = "sha256:9d97c7c5dcf25f6c0599c76d9933368c6a8d7238f2c1d00e76f1a69369ca82a0", size = 50789, upload-time = "2025-03-05T23:31:45.962Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f6/4c/8d54d6dc5ff8ba8ced1fad9378f89f9dd60addcc4cf0e525ee0e67b1769f/rtree-1.4.0-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:4d1bebc418101480aabf41767e772dd2155d3b27b1376cccbd93e4509485e091", size = 482755, upload-time = "2025-03-05T23:31:29.884Z" }, + { url = "https://files.pythonhosted.org/packages/20/29/045e700d2135e9a67896086c831fde80fd4105971b443d5727a4093fcbf1/rtree-1.4.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:997f8c38d5dffa3949ea8adb4c8b291ea5cd4ef5ee69455d642dd171baf9991d", size = 439796, upload-time = "2025-03-05T23:31:31.517Z" }, + { url = "https://files.pythonhosted.org/packages/3d/fc/c3bd8cd67b10a12a6b9e2d06796779128c3e6968922dbf29fcd53af68d81/rtree-1.4.0-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0133d9c54ab3ffe874ba6d411dbe0254765c5e68d92da5b91362c370f16fd997", size = 497549, upload-time = "2025-03-05T23:31:33.722Z" }, + { url = "https://files.pythonhosted.org/packages/a0/dd/49dc9ab037d0cb288ed40f8b7f498f69d44243e4745e241c05d5e457ea8b/rtree-1.4.0-py3-none-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:d3b7bf1fe6463139377995ebe22a01a7005d134707f43672a3c09305e12f5f43", size = 568787, upload-time = "2025-03-05T23:31:35.478Z" }, + { url = "https://files.pythonhosted.org/packages/fe/e7/57737dff73ce789bdadd916d48ac12e977d8578176e1e890b1b8d89b9dbf/rtree-1.4.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:27e4a6d617d63dcb82fcd4c2856134b8a3741bd1af3b1a0d98e886054f394da5", size = 541090, upload-time = "2025-03-05T23:31:37.712Z" }, + { url = "https://files.pythonhosted.org/packages/8e/8f/1f3f716c4e8388670cfd5d0a3578e2354a1e6a3403648e234e1540e3e3bd/rtree-1.4.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5258e826064eab82439760201e9421ce6d4340789d6d080c1b49367ddd03f61f", size = 1454194, upload-time = "2025-03-05T23:31:39.851Z" }, + { url = "https://files.pythonhosted.org/packages/22/ec/b42052b10e63a1c5d5d61ce234332f689736053644ba1756f7a632ea7659/rtree-1.4.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:20d5b3f9cf8bbbcc9fec42ab837c603c5dd86103ef29134300c8da2495c1248b", size = 1692814, upload-time = "2025-03-05T23:31:41.617Z" }, + { url = "https://files.pythonhosted.org/packages/c5/5b/a9920e9a2dc43b066ff13b7fde2e7bffcca315cfa43ae6f4cc15970e39eb/rtree-1.4.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a67bee1233370a4c72c0969a96d2a1df1ba404ddd9f146849c53ab420eab361b", size = 1554860, upload-time = "2025-03-05T23:31:43.091Z" }, + { url = "https://files.pythonhosted.org/packages/ce/c2/362f2cc36a7a57b47380061c23fc109c7222c1a544ffd24cda289ba19673/rtree-1.4.0-py3-none-win_amd64.whl", hash = "sha256:ba83efc7b7563905b1bfdfc14490c4bfb59e92e5e6156bdeb6ec5df5117252f4", size = 385221, upload-time = "2025-03-05T23:31:44.537Z" }, +] + +[[package]] +name = "ruff" +version = "0.12.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/81/0bd3594fa0f690466e41bd033bdcdf86cba8288345ac77ad4afbe5ec743a/ruff-0.12.7.tar.gz", hash = "sha256:1fc3193f238bc2d7968772c82831a4ff69252f673be371fb49663f0068b7ec71", size = 5197814, upload-time = "2025-07-29T22:32:35.877Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/d2/6cb35e9c85e7a91e8d22ab32ae07ac39cc34a71f1009a6f9e4a2a019e602/ruff-0.12.7-py3-none-linux_armv6l.whl", hash = "sha256:76e4f31529899b8c434c3c1dede98c4483b89590e15fb49f2d46183801565303", size = 11852189, upload-time = "2025-07-29T22:31:41.281Z" }, + { url = "https://files.pythonhosted.org/packages/63/5b/a4136b9921aa84638f1a6be7fb086f8cad0fde538ba76bda3682f2599a2f/ruff-0.12.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:789b7a03e72507c54fb3ba6209e4bb36517b90f1a3569ea17084e3fd295500fb", size = 12519389, upload-time = "2025-07-29T22:31:54.265Z" }, + { url = "https://files.pythonhosted.org/packages/a8/c9/3e24a8472484269b6b1821794141f879c54645a111ded4b6f58f9ab0705f/ruff-0.12.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:2e1c2a3b8626339bb6369116e7030a4cf194ea48f49b64bb505732a7fce4f4e3", size = 11743384, upload-time = "2025-07-29T22:31:59.575Z" }, + { url = "https://files.pythonhosted.org/packages/26/7c/458dd25deeb3452c43eaee853c0b17a1e84169f8021a26d500ead77964fd/ruff-0.12.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32dec41817623d388e645612ec70d5757a6d9c035f3744a52c7b195a57e03860", size = 11943759, upload-time = "2025-07-29T22:32:01.95Z" }, + { url = "https://files.pythonhosted.org/packages/7f/8b/658798472ef260ca050e400ab96ef7e85c366c39cf3dfbef4d0a46a528b6/ruff-0.12.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:47ef751f722053a5df5fa48d412dbb54d41ab9b17875c6840a58ec63ff0c247c", size = 11654028, upload-time = "2025-07-29T22:32:04.367Z" }, + { url = "https://files.pythonhosted.org/packages/a8/86/9c2336f13b2a3326d06d39178fd3448dcc7025f82514d1b15816fe42bfe8/ruff-0.12.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a828a5fc25a3efd3e1ff7b241fd392686c9386f20e5ac90aa9234a5faa12c423", size = 13225209, upload-time = "2025-07-29T22:32:06.952Z" }, + { url = "https://files.pythonhosted.org/packages/76/69/df73f65f53d6c463b19b6b312fd2391dc36425d926ec237a7ed028a90fc1/ruff-0.12.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5726f59b171111fa6a69d82aef48f00b56598b03a22f0f4170664ff4d8298efb", size = 14182353, upload-time = "2025-07-29T22:32:10.053Z" }, + { url = "https://files.pythonhosted.org/packages/58/1e/de6cda406d99fea84b66811c189b5ea139814b98125b052424b55d28a41c/ruff-0.12.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:74e6f5c04c4dd4aba223f4fe6e7104f79e0eebf7d307e4f9b18c18362124bccd", size = 13631555, upload-time = "2025-07-29T22:32:12.644Z" }, + { url = "https://files.pythonhosted.org/packages/6f/ae/625d46d5164a6cc9261945a5e89df24457dc8262539ace3ac36c40f0b51e/ruff-0.12.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d0bfe4e77fba61bf2ccadf8cf005d6133e3ce08793bbe870dd1c734f2699a3e", size = 12667556, upload-time = "2025-07-29T22:32:15.312Z" }, + { url = "https://files.pythonhosted.org/packages/55/bf/9cb1ea5e3066779e42ade8d0cd3d3b0582a5720a814ae1586f85014656b6/ruff-0.12.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06bfb01e1623bf7f59ea749a841da56f8f653d641bfd046edee32ede7ff6c606", size = 12939784, upload-time = "2025-07-29T22:32:17.69Z" }, + { url = "https://files.pythonhosted.org/packages/55/7f/7ead2663be5627c04be83754c4f3096603bf5e99ed856c7cd29618c691bd/ruff-0.12.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e41df94a957d50083fd09b916d6e89e497246698c3f3d5c681c8b3e7b9bb4ac8", size = 11771356, upload-time = "2025-07-29T22:32:20.134Z" }, + { url = "https://files.pythonhosted.org/packages/17/40/a95352ea16edf78cd3a938085dccc55df692a4d8ba1b3af7accbe2c806b0/ruff-0.12.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:4000623300563c709458d0ce170c3d0d788c23a058912f28bbadc6f905d67afa", size = 11612124, upload-time = "2025-07-29T22:32:22.645Z" }, + { url = "https://files.pythonhosted.org/packages/4d/74/633b04871c669e23b8917877e812376827c06df866e1677f15abfadc95cb/ruff-0.12.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:69ffe0e5f9b2cf2b8e289a3f8945b402a1b19eff24ec389f45f23c42a3dd6fb5", size = 12479945, upload-time = "2025-07-29T22:32:24.765Z" }, + { url = "https://files.pythonhosted.org/packages/be/34/c3ef2d7799c9778b835a76189c6f53c179d3bdebc8c65288c29032e03613/ruff-0.12.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a07a5c8ffa2611a52732bdc67bf88e243abd84fe2d7f6daef3826b59abbfeda4", size = 12998677, upload-time = "2025-07-29T22:32:27.022Z" }, + { url = "https://files.pythonhosted.org/packages/77/ab/aca2e756ad7b09b3d662a41773f3edcbd262872a4fc81f920dc1ffa44541/ruff-0.12.7-py3-none-win32.whl", hash = "sha256:c928f1b2ec59fb77dfdf70e0419408898b63998789cc98197e15f560b9e77f77", size = 11756687, upload-time = "2025-07-29T22:32:29.381Z" }, + { url = "https://files.pythonhosted.org/packages/b4/71/26d45a5042bc71db22ddd8252ca9d01e9ca454f230e2996bb04f16d72799/ruff-0.12.7-py3-none-win_amd64.whl", hash = "sha256:9c18f3d707ee9edf89da76131956aba1270c6348bfee8f6c647de841eac7194f", size = 12912365, upload-time = "2025-07-29T22:32:31.517Z" }, + { url = "https://files.pythonhosted.org/packages/4c/9b/0b8aa09817b63e78d94b4977f18b1fcaead3165a5ee49251c5d5c245bb2d/ruff-0.12.7-py3-none-win_arm64.whl", hash = "sha256:dfce05101dbd11833a0776716d5d1578641b7fddb537fe7fa956ab85d1769b69", size = 11982083, upload-time = "2025-07-29T22:32:33.881Z" }, +] + +[[package]] +name = "scikit-learn" +version = "1.7.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "joblib" }, + { name = "numpy" }, + { name = "scipy" }, + { name = "threadpoolctl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/41/84/5f4af978fff619706b8961accac84780a6d298d82a8873446f72edb4ead0/scikit_learn-1.7.1.tar.gz", hash = "sha256:24b3f1e976a4665aa74ee0fcaac2b8fccc6ae77c8e07ab25da3ba6d3292b9802", size = 7190445, upload-time = "2025-07-18T08:01:54.5Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/52/f8/e0533303f318a0f37b88300d21f79b6ac067188d4824f1047a37214ab718/scikit_learn-1.7.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b7839687fa46d02e01035ad775982f2470be2668e13ddd151f0f55a5bf123bae", size = 9213143, upload-time = "2025-07-18T08:01:32.942Z" }, + { url = "https://files.pythonhosted.org/packages/71/f3/f1df377d1bdfc3e3e2adc9c119c238b182293e6740df4cbeac6de2cc3e23/scikit_learn-1.7.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:a10f276639195a96c86aa572ee0698ad64ee939a7b042060b98bd1930c261d10", size = 8591977, upload-time = "2025-07-18T08:01:34.967Z" }, + { url = "https://files.pythonhosted.org/packages/99/72/c86a4cd867816350fe8dee13f30222340b9cd6b96173955819a5561810c5/scikit_learn-1.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:13679981fdaebc10cc4c13c43344416a86fcbc61449cb3e6517e1df9d12c8309", size = 9436142, upload-time = "2025-07-18T08:01:37.397Z" }, + { url = "https://files.pythonhosted.org/packages/e8/66/277967b29bd297538dc7a6ecfb1a7dce751beabd0d7f7a2233be7a4f7832/scikit_learn-1.7.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4f1262883c6a63f067a980a8cdd2d2e7f2513dddcef6a9eaada6416a7a7cbe43", size = 9282996, upload-time = "2025-07-18T08:01:39.721Z" }, + { url = "https://files.pythonhosted.org/packages/e2/47/9291cfa1db1dae9880420d1e07dbc7e8dd4a7cdbc42eaba22512e6bde958/scikit_learn-1.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:ca6d31fb10e04d50bfd2b50d66744729dbb512d4efd0223b864e2fdbfc4cee11", size = 8707418, upload-time = "2025-07-18T08:01:42.124Z" }, + { url = "https://files.pythonhosted.org/packages/61/95/45726819beccdaa34d3362ea9b2ff9f2b5d3b8bf721bd632675870308ceb/scikit_learn-1.7.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:781674d096303cfe3d351ae6963ff7c958db61cde3421cd490e3a5a58f2a94ae", size = 9561466, upload-time = "2025-07-18T08:01:44.195Z" }, + { url = "https://files.pythonhosted.org/packages/ee/1c/6f4b3344805de783d20a51eb24d4c9ad4b11a7f75c1801e6ec6d777361fd/scikit_learn-1.7.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:10679f7f125fe7ecd5fad37dd1aa2daae7e3ad8df7f3eefa08901b8254b3e12c", size = 9040467, upload-time = "2025-07-18T08:01:46.671Z" }, + { url = "https://files.pythonhosted.org/packages/6f/80/abe18fe471af9f1d181904203d62697998b27d9b62124cd281d740ded2f9/scikit_learn-1.7.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1f812729e38c8cb37f760dce71a9b83ccfb04f59b3dca7c6079dcdc60544fa9e", size = 9532052, upload-time = "2025-07-18T08:01:48.676Z" }, + { url = "https://files.pythonhosted.org/packages/14/82/b21aa1e0c4cee7e74864d3a5a721ab8fcae5ca55033cb6263dca297ed35b/scikit_learn-1.7.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:88e1a20131cf741b84b89567e1717f27a2ced228e0f29103426102bc2e3b8ef7", size = 9361575, upload-time = "2025-07-18T08:01:50.639Z" }, + { url = "https://files.pythonhosted.org/packages/f2/20/f4777fcd5627dc6695fa6b92179d0edb7a3ac1b91bcd9a1c7f64fa7ade23/scikit_learn-1.7.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b1bd1d919210b6a10b7554b717c9000b5485aa95a1d0f177ae0d7ee8ec750da5", size = 9277310, upload-time = "2025-07-18T08:01:52.547Z" }, +] + +[[package]] +name = "scipy" +version = "1.16.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f5/4a/b927028464795439faec8eaf0b03b011005c487bb2d07409f28bf30879c4/scipy-1.16.1.tar.gz", hash = "sha256:44c76f9e8b6e8e488a586190ab38016e4ed2f8a038af7cd3defa903c0a2238b3", size = 30580861, upload-time = "2025-07-27T16:33:30.834Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/93/0b/b5c99382b839854a71ca9482c684e3472badc62620287cbbdab499b75ce6/scipy-1.16.1-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:5451606823a5e73dfa621a89948096c6528e2896e40b39248295d3a0138d594f", size = 36533717, upload-time = "2025-07-27T16:28:51.706Z" }, + { url = "https://files.pythonhosted.org/packages/eb/e5/69ab2771062c91e23e07c12e7d5033a6b9b80b0903ee709c3c36b3eb520c/scipy-1.16.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:89728678c5ca5abd610aee148c199ac1afb16e19844401ca97d43dc548a354eb", size = 28570009, upload-time = "2025-07-27T16:28:57.017Z" }, + { url = "https://files.pythonhosted.org/packages/f4/69/bd75dbfdd3cf524f4d753484d723594aed62cfaac510123e91a6686d520b/scipy-1.16.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e756d688cb03fd07de0fffad475649b03cb89bee696c98ce508b17c11a03f95c", size = 20841942, upload-time = "2025-07-27T16:29:01.152Z" }, + { url = "https://files.pythonhosted.org/packages/ea/74/add181c87663f178ba7d6144b370243a87af8476664d5435e57d599e6874/scipy-1.16.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5aa2687b9935da3ed89c5dbed5234576589dd28d0bf7cd237501ccfbdf1ad608", size = 23498507, upload-time = "2025-07-27T16:29:05.202Z" }, + { url = "https://files.pythonhosted.org/packages/1d/74/ece2e582a0d9550cee33e2e416cc96737dce423a994d12bbe59716f47ff1/scipy-1.16.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0851f6a1e537fe9399f35986897e395a1aa61c574b178c0d456be5b1a0f5ca1f", size = 33286040, upload-time = "2025-07-27T16:29:10.201Z" }, + { url = "https://files.pythonhosted.org/packages/e4/82/08e4076df538fb56caa1d489588d880ec7c52d8273a606bb54d660528f7c/scipy-1.16.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fedc2cbd1baed37474b1924c331b97bdff611d762c196fac1a9b71e67b813b1b", size = 35176096, upload-time = "2025-07-27T16:29:17.091Z" }, + { url = "https://files.pythonhosted.org/packages/fa/79/cd710aab8c921375711a8321c6be696e705a120e3011a643efbbcdeeabcc/scipy-1.16.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2ef500e72f9623a6735769e4b93e9dcb158d40752cdbb077f305487e3e2d1f45", size = 35490328, upload-time = "2025-07-27T16:29:22.928Z" }, + { url = "https://files.pythonhosted.org/packages/71/73/e9cc3d35ee4526d784520d4494a3e1ca969b071fb5ae5910c036a375ceec/scipy-1.16.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:978d8311674b05a8f7ff2ea6c6bce5d8b45a0cb09d4c5793e0318f448613ea65", size = 37939921, upload-time = "2025-07-27T16:29:29.108Z" }, + { url = "https://files.pythonhosted.org/packages/21/12/c0efd2941f01940119b5305c375ae5c0fcb7ec193f806bd8f158b73a1782/scipy-1.16.1-cp313-cp313-win_amd64.whl", hash = "sha256:81929ed0fa7a5713fcdd8b2e6f73697d3b4c4816d090dd34ff937c20fa90e8ab", size = 38479462, upload-time = "2025-07-27T16:30:24.078Z" }, + { url = "https://files.pythonhosted.org/packages/7a/19/c3d08b675260046a991040e1ea5d65f91f40c7df1045fffff412dcfc6765/scipy-1.16.1-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:bcc12db731858abda693cecdb3bdc9e6d4bd200213f49d224fe22df82687bdd6", size = 36938832, upload-time = "2025-07-27T16:29:35.057Z" }, + { url = "https://files.pythonhosted.org/packages/81/f2/ce53db652c033a414a5b34598dba6b95f3d38153a2417c5a3883da429029/scipy-1.16.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:744d977daa4becb9fc59135e75c069f8d301a87d64f88f1e602a9ecf51e77b27", size = 29093084, upload-time = "2025-07-27T16:29:40.201Z" }, + { url = "https://files.pythonhosted.org/packages/a9/ae/7a10ff04a7dc15f9057d05b33737ade244e4bd195caa3f7cc04d77b9e214/scipy-1.16.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:dc54f76ac18073bcecffb98d93f03ed6b81a92ef91b5d3b135dcc81d55a724c7", size = 21365098, upload-time = "2025-07-27T16:29:44.295Z" }, + { url = "https://files.pythonhosted.org/packages/36/ac/029ff710959932ad3c2a98721b20b405f05f752f07344622fd61a47c5197/scipy-1.16.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:367d567ee9fc1e9e2047d31f39d9d6a7a04e0710c86e701e053f237d14a9b4f6", size = 23896858, upload-time = "2025-07-27T16:29:48.784Z" }, + { url = "https://files.pythonhosted.org/packages/71/13/d1ef77b6bd7898720e1f0b6b3743cb945f6c3cafa7718eaac8841035ab60/scipy-1.16.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4cf5785e44e19dcd32a0e4807555e1e9a9b8d475c6afff3d21c3c543a6aa84f4", size = 33438311, upload-time = "2025-07-27T16:29:54.164Z" }, + { url = "https://files.pythonhosted.org/packages/2d/e0/e64a6821ffbb00b4c5b05169f1c1fddb4800e9307efe3db3788995a82a2c/scipy-1.16.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3d0b80fb26d3e13a794c71d4b837e2a589d839fd574a6bbb4ee1288c213ad4a3", size = 35279542, upload-time = "2025-07-27T16:30:00.249Z" }, + { url = "https://files.pythonhosted.org/packages/57/59/0dc3c8b43e118f1e4ee2b798dcc96ac21bb20014e5f1f7a8e85cc0653bdb/scipy-1.16.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8503517c44c18d1030d666cb70aaac1cc8913608816e06742498833b128488b7", size = 35667665, upload-time = "2025-07-27T16:30:05.916Z" }, + { url = "https://files.pythonhosted.org/packages/45/5f/844ee26e34e2f3f9f8febb9343748e72daeaec64fe0c70e9bf1ff84ec955/scipy-1.16.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:30cc4bb81c41831ecfd6dc450baf48ffd80ef5aed0f5cf3ea775740e80f16ecc", size = 38045210, upload-time = "2025-07-27T16:30:11.655Z" }, + { url = "https://files.pythonhosted.org/packages/8d/d7/210f2b45290f444f1de64bc7353aa598ece9f0e90c384b4a156f9b1a5063/scipy-1.16.1-cp313-cp313t-win_amd64.whl", hash = "sha256:c24fa02f7ed23ae514460a22c57eca8f530dbfa50b1cfdbf4f37c05b5309cc39", size = 38593661, upload-time = "2025-07-27T16:30:17.825Z" }, + { url = "https://files.pythonhosted.org/packages/81/ea/84d481a5237ed223bd3d32d6e82d7a6a96e34756492666c260cef16011d1/scipy-1.16.1-cp314-cp314-macosx_10_14_x86_64.whl", hash = "sha256:796a5a9ad36fa3a782375db8f4241ab02a091308eb079746bc0f874c9b998318", size = 36525921, upload-time = "2025-07-27T16:30:30.081Z" }, + { url = "https://files.pythonhosted.org/packages/4e/9f/d9edbdeff9f3a664807ae3aea383e10afaa247e8e6255e6d2aa4515e8863/scipy-1.16.1-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:3ea0733a2ff73fd6fdc5fecca54ee9b459f4d74f00b99aced7d9a3adb43fb1cc", size = 28564152, upload-time = "2025-07-27T16:30:35.336Z" }, + { url = "https://files.pythonhosted.org/packages/3b/95/8125bcb1fe04bc267d103e76516243e8d5e11229e6b306bda1024a5423d1/scipy-1.16.1-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:85764fb15a2ad994e708258bb4ed8290d1305c62a4e1ef07c414356a24fcfbf8", size = 20836028, upload-time = "2025-07-27T16:30:39.421Z" }, + { url = "https://files.pythonhosted.org/packages/77/9c/bf92e215701fc70bbcd3d14d86337cf56a9b912a804b9c776a269524a9e9/scipy-1.16.1-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:ca66d980469cb623b1759bdd6e9fd97d4e33a9fad5b33771ced24d0cb24df67e", size = 23489666, upload-time = "2025-07-27T16:30:43.663Z" }, + { url = "https://files.pythonhosted.org/packages/5e/00/5e941d397d9adac41b02839011594620d54d99488d1be5be755c00cde9ee/scipy-1.16.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e7cc1ffcc230f568549fc56670bcf3df1884c30bd652c5da8138199c8c76dae0", size = 33358318, upload-time = "2025-07-27T16:30:48.982Z" }, + { url = "https://files.pythonhosted.org/packages/0e/87/8db3aa10dde6e3e8e7eb0133f24baa011377d543f5b19c71469cf2648026/scipy-1.16.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3ddfb1e8d0b540cb4ee9c53fc3dea3186f97711248fb94b4142a1b27178d8b4b", size = 35185724, upload-time = "2025-07-27T16:30:54.26Z" }, + { url = "https://files.pythonhosted.org/packages/89/b4/6ab9ae443216807622bcff02690262d8184078ea467efee2f8c93288a3b1/scipy-1.16.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4dc0e7be79e95d8ba3435d193e0d8ce372f47f774cffd882f88ea4e1e1ddc731", size = 35554335, upload-time = "2025-07-27T16:30:59.765Z" }, + { url = "https://files.pythonhosted.org/packages/9c/9a/d0e9dc03c5269a1afb60661118296a32ed5d2c24298af61b676c11e05e56/scipy-1.16.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f23634f9e5adb51b2a77766dac217063e764337fbc816aa8ad9aaebcd4397fd3", size = 37960310, upload-time = "2025-07-27T16:31:06.151Z" }, + { url = "https://files.pythonhosted.org/packages/5e/00/c8f3130a50521a7977874817ca89e0599b1b4ee8e938bad8ae798a0e1f0d/scipy-1.16.1-cp314-cp314-win_amd64.whl", hash = "sha256:57d75524cb1c5a374958a2eae3d84e1929bb971204cc9d52213fb8589183fc19", size = 39319239, upload-time = "2025-07-27T16:31:59.942Z" }, + { url = "https://files.pythonhosted.org/packages/f2/f2/1ca3eda54c3a7e4c92f6acef7db7b3a057deb135540d23aa6343ef8ad333/scipy-1.16.1-cp314-cp314t-macosx_10_14_x86_64.whl", hash = "sha256:d8da7c3dd67bcd93f15618938f43ed0995982eb38973023d46d4646c4283ad65", size = 36939460, upload-time = "2025-07-27T16:31:11.865Z" }, + { url = "https://files.pythonhosted.org/packages/80/30/98c2840b293a132400c0940bb9e140171dcb8189588619048f42b2ce7b4f/scipy-1.16.1-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:cc1d2f2fd48ba1e0620554fe5bc44d3e8f5d4185c8c109c7fbdf5af2792cfad2", size = 29093322, upload-time = "2025-07-27T16:31:17.045Z" }, + { url = "https://files.pythonhosted.org/packages/c1/e6/1e6e006e850622cf2a039b62d1a6ddc4497d4851e58b68008526f04a9a00/scipy-1.16.1-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:21a611ced9275cb861bacadbada0b8c0623bc00b05b09eb97f23b370fc2ae56d", size = 21365329, upload-time = "2025-07-27T16:31:21.188Z" }, + { url = "https://files.pythonhosted.org/packages/8e/02/72a5aa5b820589dda9a25e329ca752842bfbbaf635e36bc7065a9b42216e/scipy-1.16.1-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:8dfbb25dffc4c3dd9371d8ab456ca81beeaf6f9e1c2119f179392f0dc1ab7695", size = 23897544, upload-time = "2025-07-27T16:31:25.408Z" }, + { url = "https://files.pythonhosted.org/packages/2b/dc/7122d806a6f9eb8a33532982234bed91f90272e990f414f2830cfe656e0b/scipy-1.16.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f0ebb7204f063fad87fc0a0e4ff4a2ff40b2a226e4ba1b7e34bf4b79bf97cd86", size = 33442112, upload-time = "2025-07-27T16:31:30.62Z" }, + { url = "https://files.pythonhosted.org/packages/24/39/e383af23564daa1021a5b3afbe0d8d6a68ec639b943661841f44ac92de85/scipy-1.16.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f1b9e5962656f2734c2b285a8745358ecb4e4efbadd00208c80a389227ec61ff", size = 35286594, upload-time = "2025-07-27T16:31:36.112Z" }, + { url = "https://files.pythonhosted.org/packages/95/47/1a0b0aff40c3056d955f38b0df5d178350c3d74734ec54f9c68d23910be5/scipy-1.16.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e1a106f8c023d57a2a903e771228bf5c5b27b5d692088f457acacd3b54511e4", size = 35665080, upload-time = "2025-07-27T16:31:42.025Z" }, + { url = "https://files.pythonhosted.org/packages/64/df/ce88803e9ed6e27fe9b9abefa157cf2c80e4fa527cf17ee14be41f790ad4/scipy-1.16.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:709559a1db68a9abc3b2c8672c4badf1614f3b440b3ab326d86a5c0491eafae3", size = 38050306, upload-time = "2025-07-27T16:31:48.109Z" }, + { url = "https://files.pythonhosted.org/packages/6e/6c/a76329897a7cae4937d403e623aa6aaea616a0bb5b36588f0b9d1c9a3739/scipy-1.16.1-cp314-cp314t-win_amd64.whl", hash = "sha256:c0c804d60492a0aad7f5b2bb1862f4548b990049e27e828391ff2bf6f7199998", size = 39427705, upload-time = "2025-07-27T16:31:53.96Z" }, +] + +[[package]] +name = "setuptools" +version = "80.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload-time = "2025-05-27T00:56:51.443Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" }, +] + +[[package]] +name = "shapely" +version = "2.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ca/3c/2da625233f4e605155926566c0e7ea8dda361877f48e8b1655e53456f252/shapely-2.1.1.tar.gz", hash = "sha256:500621967f2ffe9642454808009044c21e5b35db89ce69f8a2042c2ffd0e2772", size = 315422, upload-time = "2025-05-19T11:04:41.265Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/8e/2bc836437f4b84d62efc1faddce0d4e023a5d990bbddd3c78b2004ebc246/shapely-2.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3004a644d9e89e26c20286d5fdc10f41b1744c48ce910bd1867fdff963fe6c48", size = 1832107, upload-time = "2025-05-19T11:04:19.736Z" }, + { url = "https://files.pythonhosted.org/packages/12/a2/12c7cae5b62d5d851c2db836eadd0986f63918a91976495861f7c492f4a9/shapely-2.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1415146fa12d80a47d13cfad5310b3c8b9c2aa8c14a0c845c9d3d75e77cb54f6", size = 1642355, upload-time = "2025-05-19T11:04:21.035Z" }, + { url = "https://files.pythonhosted.org/packages/5b/7e/6d28b43d53fea56de69c744e34c2b999ed4042f7a811dc1bceb876071c95/shapely-2.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21fcab88b7520820ec16d09d6bea68652ca13993c84dffc6129dc3607c95594c", size = 2968871, upload-time = "2025-05-19T11:04:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/dd/87/1017c31e52370b2b79e4d29e07cbb590ab9e5e58cf7e2bdfe363765d6251/shapely-2.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5ce6a5cc52c974b291237a96c08c5592e50f066871704fb5b12be2639d9026a", size = 3080830, upload-time = "2025-05-19T11:04:23.997Z" }, + { url = "https://files.pythonhosted.org/packages/1d/fe/f4a03d81abd96a6ce31c49cd8aaba970eaaa98e191bd1e4d43041e57ae5a/shapely-2.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:04e4c12a45a1d70aeb266618d8cf81a2de9c4df511b63e105b90bfdfb52146de", size = 3908961, upload-time = "2025-05-19T11:04:25.702Z" }, + { url = "https://files.pythonhosted.org/packages/ef/59/7605289a95a6844056a2017ab36d9b0cb9d6a3c3b5317c1f968c193031c9/shapely-2.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6ca74d851ca5264aae16c2b47e96735579686cb69fa93c4078070a0ec845b8d8", size = 4079623, upload-time = "2025-05-19T11:04:27.171Z" }, + { url = "https://files.pythonhosted.org/packages/bc/4d/9fea036eff2ef4059d30247128b2d67aaa5f0b25e9fc27e1d15cc1b84704/shapely-2.1.1-cp313-cp313-win32.whl", hash = "sha256:fd9130501bf42ffb7e0695b9ea17a27ae8ce68d50b56b6941c7f9b3d3453bc52", size = 1521916, upload-time = "2025-05-19T11:04:28.405Z" }, + { url = "https://files.pythonhosted.org/packages/12/d9/6d13b8957a17c95794f0c4dfb65ecd0957e6c7131a56ce18d135c1107a52/shapely-2.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:ab8d878687b438a2f4c138ed1a80941c6ab0029e0f4c785ecfe114413b498a97", size = 1702746, upload-time = "2025-05-19T11:04:29.643Z" }, + { url = "https://files.pythonhosted.org/packages/60/36/b1452e3e7f35f5f6454d96f3be6e2bb87082720ff6c9437ecc215fa79be0/shapely-2.1.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0c062384316a47f776305ed2fa22182717508ffdeb4a56d0ff4087a77b2a0f6d", size = 1833482, upload-time = "2025-05-19T11:04:30.852Z" }, + { url = "https://files.pythonhosted.org/packages/ce/ca/8e6f59be0718893eb3e478141285796a923636dc8f086f83e5b0ec0036d0/shapely-2.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4ecf6c196b896e8f1360cc219ed4eee1c1e5f5883e505d449f263bd053fb8c05", size = 1642256, upload-time = "2025-05-19T11:04:32.068Z" }, + { url = "https://files.pythonhosted.org/packages/ab/78/0053aea449bb1d4503999525fec6232f049abcdc8df60d290416110de943/shapely-2.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb00070b4c4860f6743c600285109c273cca5241e970ad56bb87bef0be1ea3a0", size = 3016614, upload-time = "2025-05-19T11:04:33.7Z" }, + { url = "https://files.pythonhosted.org/packages/ee/53/36f1b1de1dfafd1b457dcbafa785b298ce1b8a3e7026b79619e708a245d5/shapely-2.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d14a9afa5fa980fbe7bf63706fdfb8ff588f638f145a1d9dbc18374b5b7de913", size = 3093542, upload-time = "2025-05-19T11:04:34.952Z" }, + { url = "https://files.pythonhosted.org/packages/b9/bf/0619f37ceec6b924d84427c88835b61f27f43560239936ff88915c37da19/shapely-2.1.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b640e390dabde790e3fb947198b466e63223e0a9ccd787da5f07bcb14756c28d", size = 3945961, upload-time = "2025-05-19T11:04:36.32Z" }, + { url = "https://files.pythonhosted.org/packages/93/c9/20ca4afeb572763b07a7997f00854cb9499df6af85929e93012b189d8917/shapely-2.1.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:69e08bf9697c1b73ec6aa70437db922bafcea7baca131c90c26d59491a9760f9", size = 4089514, upload-time = "2025-05-19T11:04:37.683Z" }, + { url = "https://files.pythonhosted.org/packages/33/6a/27036a5a560b80012a544366bceafd491e8abb94a8db14047b5346b5a749/shapely-2.1.1-cp313-cp313t-win32.whl", hash = "sha256:ef2d09d5a964cc90c2c18b03566cf918a61c248596998a0301d5b632beadb9db", size = 1540607, upload-time = "2025-05-19T11:04:38.925Z" }, + { url = "https://files.pythonhosted.org/packages/ea/f1/5e9b3ba5c7aa7ebfaf269657e728067d16a7c99401c7973ddf5f0cf121bd/shapely-2.1.1-cp313-cp313t-win_amd64.whl", hash = "sha256:8cb8f17c377260452e9d7720eeaf59082c5f8ea48cf104524d953e5d36d4bdb7", size = 1723061, upload-time = "2025-05-19T11:04:40.082Z" }, +] + +[[package]] +name = "snowballstemmer" +version = "3.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/75/a7/9810d872919697c9d01295633f5d574fb416d47e535f258272ca1f01f447/snowballstemmer-3.0.1.tar.gz", hash = "sha256:6d5eeeec8e9f84d4d56b847692bacf79bc2c8e90c7f80ca4444ff8b6f2e52895", size = 105575, upload-time = "2025-05-09T16:34:51.843Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/78/3565d011c61f5a43488987ee32b6f3f656e7f107ac2782dd57bdd7d91d9a/snowballstemmer-3.0.1-py3-none-any.whl", hash = "sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064", size = 103274, upload-time = "2025-05-09T16:34:50.371Z" }, +] + +[[package]] +name = "soupsieve" +version = "2.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3f/f4/4a80cd6ef364b2e8b65b15816a843c0980f7a5a2b4dc701fc574952aa19f/soupsieve-2.7.tar.gz", hash = "sha256:ad282f9b6926286d2ead4750552c8a6142bc4c783fd66b0293547c8fe6ae126a", size = 103418, upload-time = "2025-04-20T18:50:08.518Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/9c/0e6afc12c269578be5c0c1c9f4b49a8d32770a080260c333ac04cc1c832d/soupsieve-2.7-py3-none-any.whl", hash = "sha256:6e60cc5c1ffaf1cebcc12e8188320b72071e922c2e897f737cadce79ad5d30c4", size = 36677, upload-time = "2025-04-20T18:50:07.196Z" }, +] + +[[package]] +name = "sphinx" +version = "8.2.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "alabaster" }, + { name = "babel" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "docutils" }, + { name = "imagesize" }, + { name = "jinja2" }, + { name = "packaging" }, + { name = "pygments" }, + { name = "requests" }, + { name = "roman-numerals-py" }, + { name = "snowballstemmer" }, + { name = "sphinxcontrib-applehelp" }, + { name = "sphinxcontrib-devhelp" }, + { name = "sphinxcontrib-htmlhelp" }, + { name = "sphinxcontrib-jsmath" }, + { name = "sphinxcontrib-qthelp" }, + { name = "sphinxcontrib-serializinghtml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/38/ad/4360e50ed56cb483667b8e6dadf2d3fda62359593faabbe749a27c4eaca6/sphinx-8.2.3.tar.gz", hash = "sha256:398ad29dee7f63a75888314e9424d40f52ce5a6a87ae88e7071e80af296ec348", size = 8321876, upload-time = "2025-03-02T22:31:59.658Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/31/53/136e9eca6e0b9dc0e1962e2c908fbea2e5ac000c2a2fbd9a35797958c48b/sphinx-8.2.3-py3-none-any.whl", hash = "sha256:4405915165f13521d875a8c29c8970800a0141c14cc5416a38feca4ea5d9b9c3", size = 3589741, upload-time = "2025-03-02T22:31:56.836Z" }, +] + +[[package]] +name = "sphinx-book-theme" +version = "1.1.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydata-sphinx-theme" }, + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/45/19/d002ed96bdc7738c15847c730e1e88282d738263deac705d5713b4d8fa94/sphinx_book_theme-1.1.4.tar.gz", hash = "sha256:73efe28af871d0a89bd05856d300e61edce0d5b2fbb7984e84454be0fedfe9ed", size = 439188, upload-time = "2025-02-20T16:32:32.581Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/9e/c41d68be04eef5b6202b468e0f90faf0c469f3a03353f2a218fd78279710/sphinx_book_theme-1.1.4-py3-none-any.whl", hash = "sha256:843b3f5c8684640f4a2d01abd298beb66452d1b2394cd9ef5be5ebd5640ea0e1", size = 433952, upload-time = "2025-02-20T16:32:31.009Z" }, +] + +[[package]] +name = "sphinx-copybutton" +version = "0.5.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fc/2b/a964715e7f5295f77509e59309959f4125122d648f86b4fe7d70ca1d882c/sphinx-copybutton-0.5.2.tar.gz", hash = "sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd", size = 23039, upload-time = "2023-04-14T08:10:22.998Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/48/1ea60e74949eecb12cdd6ac43987f9fd331156388dcc2319b45e2ebb81bf/sphinx_copybutton-0.5.2-py3-none-any.whl", hash = "sha256:fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e", size = 13343, upload-time = "2023-04-14T08:10:20.844Z" }, +] + +[[package]] +name = "sphinx-intl" +version = "2.3.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "babel" }, + { name = "click" }, + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7a/21/eb12016ecb0b52861762b0d227dff75622988f238776a5ee4c75bade507e/sphinx_intl-2.3.2.tar.gz", hash = "sha256:04b0d8ea04d111a7ba278b17b7b3fe9625c58b6f8ffb78bb8a1dd1288d88c1c7", size = 27921, upload-time = "2025-08-02T04:53:01.891Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f7/3b/156032fa29a87e9eba9182b8e893a7e88c1d98907a078a371d69be432e52/sphinx_intl-2.3.2-py3-none-any.whl", hash = "sha256:f0082f9383066bab8406129a2ed531d21c38706d08467bf5ca3714e8914bb2be", size = 12899, upload-time = "2025-08-02T04:53:00.353Z" }, +] + +[[package]] +name = "sphinx-rtd-theme" +version = "3.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils" }, + { name = "sphinx" }, + { name = "sphinxcontrib-jquery" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/91/44/c97faec644d29a5ceddd3020ae2edffa69e7d00054a8c7a6021e82f20335/sphinx_rtd_theme-3.0.2.tar.gz", hash = "sha256:b7457bc25dda723b20b086a670b9953c859eab60a2a03ee8eb2bb23e176e5f85", size = 7620463, upload-time = "2024-11-13T11:06:04.545Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/77/46e3bac77b82b4df5bb5b61f2de98637724f246b4966cfc34bc5895d852a/sphinx_rtd_theme-3.0.2-py2.py3-none-any.whl", hash = "sha256:422ccc750c3a3a311de4ae327e82affdaf59eb695ba4936538552f3b00f4ee13", size = 7655561, upload-time = "2024-11-13T11:06:02.094Z" }, +] + +[[package]] +name = "sphinx-togglebutton" +version = "0.3.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils" }, + { name = "setuptools" }, + { name = "sphinx" }, + { name = "wheel" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f0/df/d151dfbbe588116e450ca7e898750cb218dca6b2e557ced8de6f9bd7242b/sphinx-togglebutton-0.3.2.tar.gz", hash = "sha256:ab0c8b366427b01e4c89802d5d078472c427fa6e9d12d521c34fa0442559dc7a", size = 8324, upload-time = "2022-07-15T12:08:50.286Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/18/267ce39f29d26cdc7177231428ba823fe5ca94db8c56d1bed69033b364c8/sphinx_togglebutton-0.3.2-py3-none-any.whl", hash = "sha256:9647ba7874b7d1e2d43413d8497153a85edc6ac95a3fea9a75ef9c1e08aaae2b", size = 8249, upload-time = "2022-07-15T12:08:48.8Z" }, +] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/6e/b837e84a1a704953c62ef8776d45c3e8d759876b4a84fe14eba2859106fe/sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1", size = 20053, upload-time = "2024-07-29T01:09:00.465Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5", size = 119300, upload-time = "2024-07-29T01:08:58.99Z" }, +] + +[[package]] +name = "sphinxcontrib-devhelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/d2/5beee64d3e4e747f316bae86b55943f51e82bb86ecd325883ef65741e7da/sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad", size = 12967, upload-time = "2024-07-29T01:09:23.417Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2", size = 82530, upload-time = "2024-07-29T01:09:21.945Z" }, +] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/93/983afd9aa001e5201eab16b5a444ed5b9b0a7a010541e0ddfbbfd0b2470c/sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9", size = 22617, upload-time = "2024-07-29T01:09:37.889Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8", size = 98705, upload-time = "2024-07-29T01:09:36.407Z" }, +] + +[[package]] +name = "sphinxcontrib-jquery" +version = "4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/de/f3/aa67467e051df70a6330fe7770894b3e4f09436dea6881ae0b4f3d87cad8/sphinxcontrib-jquery-4.1.tar.gz", hash = "sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a", size = 122331, upload-time = "2023-03-14T15:01:01.944Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/85/749bd22d1a68db7291c89e2ebca53f4306c3f205853cf31e9de279034c3c/sphinxcontrib_jquery-4.1-py2.py3-none-any.whl", hash = "sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae", size = 121104, upload-time = "2023-03-14T15:01:00.356Z" }, +] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/e8/9ed3830aeed71f17c026a07a5097edcf44b692850ef215b161b8ad875729/sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8", size = 5787, upload-time = "2019-01-21T16:10:16.347Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", size = 5071, upload-time = "2019-01-21T16:10:14.333Z" }, +] + +[[package]] +name = "sphinxcontrib-mermaid" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyyaml" }, + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/97/69/bf039237ad260073e8c02f820b3e00dc34f3a2de20aff7861e6b19d2f8c5/sphinxcontrib_mermaid-1.0.0.tar.gz", hash = "sha256:2e8ab67d3e1e2816663f9347d026a8dee4a858acdd4ad32dd1c808893db88146", size = 15153, upload-time = "2024-10-12T16:33:03.863Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cd/c8/784b9ac6ea08aa594c1a4becbd0dbe77186785362e31fd633b8c6ae0197a/sphinxcontrib_mermaid-1.0.0-py3-none-any.whl", hash = "sha256:60b72710ea02087f212028feb09711225fbc2e343a10d34822fe787510e1caa3", size = 9597, upload-time = "2024-10-12T16:33:02.303Z" }, +] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/68/bc/9104308fc285eb3e0b31b67688235db556cd5b0ef31d96f30e45f2e51cae/sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab", size = 17165, upload-time = "2024-07-29T01:09:56.435Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb", size = 88743, upload-time = "2024-07-29T01:09:54.885Z" }, +] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3b/44/6716b257b0aa6bfd51a1b31665d1c205fb12cb5ad56de752dfa15657de2f/sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d", size = 16080, upload-time = "2024-07-29T01:10:09.332Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331", size = 92072, upload-time = "2024-07-29T01:10:08.203Z" }, +] + +[[package]] +name = "structlog" +version = "25.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/79/b9/6e672db4fec07349e7a8a8172c1a6ae235c58679ca29c3f86a61b5e59ff3/structlog-25.4.0.tar.gz", hash = "sha256:186cd1b0a8ae762e29417095664adf1d6a31702160a46dacb7796ea82f7409e4", size = 1369138, upload-time = "2025-06-02T08:21:12.971Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/4a/97ee6973e3a73c74c8120d59829c3861ea52210667ec3e7a16045c62b64d/structlog-25.4.0-py3-none-any.whl", hash = "sha256:fe809ff5c27e557d14e613f45ca441aabda051d119ee5a0102aaba6ce40eed2c", size = 68720, upload-time = "2025-06-02T08:21:11.43Z" }, +] + +[[package]] +name = "threadpoolctl" +version = "3.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b7/4d/08c89e34946fce2aec4fbb45c9016efd5f4d7f24af8e5d93296e935631d8/threadpoolctl-3.6.0.tar.gz", hash = "sha256:8ab8b4aa3491d812b623328249fab5302a68d2d71745c8a4c719a2fcaba9f44e", size = 21274, upload-time = "2025-03-13T13:49:23.031Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl", hash = "sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb", size = 18638, upload-time = "2025-03-13T13:49:21.846Z" }, +] + +[[package]] +name = "types-protobuf" +version = "6.30.2.20250703" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/dc/54/d63ce1eee8e93c4d710bbe2c663ec68e3672cf4f2fca26eecd20981c0c5d/types_protobuf-6.30.2.20250703.tar.gz", hash = "sha256:609a974754bbb71fa178fc641f51050395e8e1849f49d0420a6281ed8d1ddf46", size = 62300, upload-time = "2025-07-03T03:14:05.74Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/2b/5d0377c3d6e0f49d4847ad2c40629593fee4a5c9ec56eba26a15c708fbc0/types_protobuf-6.30.2.20250703-py3-none-any.whl", hash = "sha256:fa5aff9036e9ef432d703abbdd801b436a249b6802e4df5ef74513e272434e57", size = 76489, upload-time = "2025-07-03T03:14:04.453Z" }, +] + +[[package]] +name = "types-pyyaml" +version = "6.0.12.20250516" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4e/22/59e2aeb48ceeee1f7cd4537db9568df80d62bdb44a7f9e743502ea8aab9c/types_pyyaml-6.0.12.20250516.tar.gz", hash = "sha256:9f21a70216fc0fa1b216a8176db5f9e0af6eb35d2f2932acb87689d03a5bf6ba", size = 17378, upload-time = "2025-05-16T03:08:04.897Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/99/5f/e0af6f7f6a260d9af67e1db4f54d732abad514252a7a378a6c4d17dd1036/types_pyyaml-6.0.12.20250516-py3-none-any.whl", hash = "sha256:8478208feaeb53a34cb5d970c56a7cd76b72659442e733e268a94dc72b2d0530", size = 20312, upload-time = "2025-05-16T03:08:04.019Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.14.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/98/5a/da40306b885cc8c09109dc2e1abd358d5684b1425678151cdaed4731c822/typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36", size = 107673, upload-time = "2025-07-04T13:28:34.16Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76", size = 43906, upload-time = "2025-07-04T13:28:32.743Z" }, +] + +[[package]] +name = "urllib3" +version = "2.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, +] + +[[package]] +name = "wheel" +version = "0.45.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8a/98/2d9906746cdc6a6ef809ae6338005b3f21bb568bea3165cfc6a243fdc25c/wheel-0.45.1.tar.gz", hash = "sha256:661e1abd9198507b1409a20c02106d9670b2576e916d58f520316666abca6729", size = 107545, upload-time = "2024-11-23T00:18:23.513Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/2c/87f3254fd8ffd29e4c02732eee68a83a1d3c346ae39bc6822dcbcb697f2b/wheel-0.45.1-py3-none-any.whl", hash = "sha256:708e7481cc80179af0e556bbf0cc00b8444c7321e2700b8d8580231d13017248", size = 72494, upload-time = "2024-11-23T00:18:21.207Z" }, +] From 622574f24c46332b4850cdc064224d5f510d66df Mon Sep 17 00:00:00 2001 From: shima004 Date: Mon, 4 Aug 2025 15:15:15 +0900 Subject: [PATCH 05/13] chore: format --- src/adf_core_python/cli/cli.py | 72 +- src/adf_core_python/cli/template/main.py | 4 +- .../module/complex/sample_human_detector.py | 261 ++- .../module/complex/sample_road_detector.py | 264 ++- .../team_name/module/complex/sample_search.py | 174 +- .../core/agent/action/action.py | 10 +- .../agent/action/ambulance/action_load.py | 12 +- .../agent/action/ambulance/action_rescue.py | 12 +- .../agent/action/ambulance/action_unload.py | 8 +- .../core/agent/action/common/action_move.py | 58 +- .../core/agent/action/common/action_rest.py | 8 +- .../agent/action/fire/action_extinguish.py | 16 +- .../core/agent/action/fire/action_refill.py | 8 +- .../core/agent/action/fire/action_rescue.py | 12 +- .../core/agent/action/police/action_clear.py | 12 +- .../agent/action/police/action_clear_area.py | 24 +- src/adf_core_python/core/agent/agent.py | 638 ++++---- .../agent/communication/message_manager.py | 724 ++++----- .../bundle/centralized/command_ambulance.py | 236 ++- .../bundle/centralized/command_fire.py | 238 ++- .../bundle/centralized/command_police.py | 234 ++- .../bundle/centralized/command_scout.py | 224 ++- .../bundle/centralized/message_report.py | 130 +- .../information/message_ambulance_team.py | 336 ++-- .../bundle/information/message_building.py | 184 +-- .../bundle/information/message_civilian.py | 232 ++- .../information/message_fire_brigade.py | 352 ++-- .../information/message_police_force.py | 316 ++-- .../bundle/information/message_road.py | 314 ++-- .../standard/bundle/standard_message.py | 92 +- .../bundle/standard_message_priority.py | 32 +- .../standard/standard_communication_module.py | 298 ++-- .../standard/utility/apply_to_world_info.py | 542 +++---- .../utility/bitarray_with_exits_flag.py | 108 +- .../core/agent/config/module_config.py | 144 +- .../core/agent/develop/develop_data.py | 108 +- .../core/agent/info/agent_info.py | 346 ++-- .../core/agent/info/scenario_info.py | 204 +-- .../core/agent/info/world_info.py | 404 +++-- .../core/agent/module/module_manager.py | 470 +++--- .../core/agent/office/office.py | 218 +-- .../core/agent/office/office_ambulance.py | 54 +- .../core/agent/office/office_fire.py | 50 +- .../core/agent/office/office_police.py | 50 +- .../core/agent/platoon/platoon.py | 226 +-- .../core/agent/platoon/platoon_ambulance.py | 50 +- .../core/agent/platoon/platoon_fire.py | 50 +- .../core/agent/platoon/platoon_police.py | 50 +- .../core/component/abstract_loader.py | 56 +- .../core/component/action/extend_action.py | 158 +- .../component/centralized/command_executor.py | 164 +- .../component/centralized/command_picker.py | 168 +- .../communication/channel_subscriber.py | 52 +- .../communication/communication_message.py | 26 +- .../communication/communication_module.py | 16 +- .../communication/message_coordinator.py | 36 +- .../core/component/module/abstract_module.py | 186 +-- .../component/module/algorithm/clustering.py | 94 +- .../module/algorithm/path_planning.py | 94 +- .../complex/ambulance_target_allocator.py | 88 +- .../module/complex/fire_target_allocator.py | 88 +- .../module/complex/human_detector.py | 68 +- .../module/complex/police_target_allocator.py | 88 +- .../component/module/complex/road_detector.py | 68 +- .../core/component/module/complex/search.py | 68 +- .../module/complex/target_allocator.py | 86 +- .../module/complex/target_detector.py | 86 +- .../core/component/tactics/tactics_agent.py | 318 ++-- .../tactics/tactics_ambulance_center.py | 4 +- .../tactics/tactics_ambulance_team.py | 4 +- .../core/component/tactics/tactics_center.py | 230 +-- .../component/tactics/tactics_fire_brigade.py | 4 +- .../component/tactics/tactics_fire_station.py | 4 +- .../component/tactics/tactics_police_force.py | 4 +- .../tactics/tactics_police_office.py | 4 +- src/adf_core_python/core/config/config.py | 74 +- .../module/algorithm/gateway_clustering.py | 156 +- .../module/algorithm/gateway_path_planning.py | 164 +- .../gateway_ambulance_target_allocator.py | 94 +- .../complex/gateway_fire_target_allocator.py | 96 +- .../module/complex/gateway_human_detector.py | 94 +- .../gateway_police_target_allocator.py | 100 +- .../module/complex/gateway_road_detector.py | 90 +- .../module/complex/gateway_search.py | 92 +- .../complex/gateway_target_allocator.py | 102 +- .../module/complex/gateway_target_detector.py | 94 +- .../module/gateway_abstract_module.py | 90 +- .../core/gateway/gateway_agent.py | 190 ++- .../core/gateway/gateway_launcher.py | 68 +- .../core/gateway/gateway_module.py | 146 +- .../core/gateway/message/am_agent.py | 80 +- .../core/gateway/message/am_exec.py | 32 +- .../core/gateway/message/am_module.py | 36 +- .../core/gateway/message/am_update.py | 44 +- .../core/gateway/message/ma_exec_response.py | 30 +- .../gateway/message/ma_module_response.py | 28 +- .../gateway/message/moduleMessageFactory.py | 22 +- .../core/gateway/message/urn/urn.py | 40 +- .../core/gateway/module_dict.py | 52 +- .../core/launcher/agent_launcher.py | 204 ++- .../core/launcher/config_key.py | 54 +- .../launcher/connect/component_launcher.py | 174 +- .../core/launcher/connect/connection.py | 149 +- .../core/launcher/connect/connector.py | 26 +- .../connect/connector_ambulance_center.py | 132 +- .../connect/connector_ambulance_team.py | 130 +- .../connect/connector_fire_brigade.py | 128 +- .../connect/connector_fire_station.py | 128 +- .../connect/connector_police_force.py | 128 +- .../connect/connector_police_office.py | 130 +- .../launcher/connect/error/agent_error.py | 2 +- .../launcher/connect/error/server_error.py | 2 +- src/adf_core_python/core/logger/logger.py | 150 +- .../action/default_extend_action_clear.py | 1445 ++++++++--------- .../action/default_extend_action_move.py | 156 +- .../action/default_extend_action_rescue.py | 254 +-- .../action/default_extend_action_transport.py | 456 +++--- .../default_command_executor_ambulance.py | 502 +++--- .../default_command_executor_fire.py | 414 ++--- .../default_command_executor_police.py | 438 ++--- .../default_command_executor_scout.py | 257 ++- .../default_command_executor_scout_police.py | 281 ++-- .../default_command_picker_ambulance.py | 116 +- .../default_command_picker_fire.py | 116 +- .../default_command_picker_police.py | 90 +- .../implement/default_loader.py | 48 +- .../module/algorithm/a_star_path_planning.py | 146 +- .../algorithm/dijkstra_path_planning.py | 230 ++- .../module/algorithm/k_means_clustering.py | 279 ++-- .../default_channel_subscriber.py | 161 +- .../default_message_coordinator.py | 397 +++-- .../default_ambulance_target_allocator.py | 272 ++-- .../complex/default_fire_target_allocator.py | 268 +-- .../module/complex/default_human_detector.py | 261 ++- .../default_police_target_allocator.py | 346 ++-- .../module/complex/default_road_detector.py | 264 ++- .../module/complex/default_search.py | 174 +- .../default_tactics_ambulance_center.py | 152 +- .../tactics/default_tactics_ambulance_team.py | 346 ++-- .../tactics/default_tactics_fire_brigade.py | 338 ++-- .../tactics/default_tactics_fire_station.py | 152 +- .../tactics/default_tactics_police_force.py | 346 ++-- .../tactics/default_tactics_police_office.py | 152 +- src/adf_core_python/launcher.py | 244 +-- tests/core/agent/config/test_module_config.py | 78 +- tests/core/agent/develop/test_develop.py | 24 +- .../core/agent/module/test_module_manager.py | 42 +- 147 files changed, 11722 insertions(+), 11945 deletions(-) diff --git a/src/adf_core_python/cli/cli.py b/src/adf_core_python/cli/cli.py index b14a1c7..abaf673 100644 --- a/src/adf_core_python/cli/cli.py +++ b/src/adf_core_python/cli/cli.py @@ -8,49 +8,49 @@ @click.command() @click.option( - "--name", prompt="Your agent team name", help="The name of your agent team" + "--name", prompt="Your agent team name", help="The name of your agent team" ) def cli(name: str) -> None: - # load template dir and create a new agent team - click.echo(f"Creating a new agent team with name: {name}") - # 自身がいるディレクトリを取得 - template_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)), "template") - # コマンドラインのカレントディレクトリを取得 - current_dir = os.getcwd() + # load template dir and create a new agent team + click.echo(f"Creating a new agent team with name: {name}") + # 自身がいるディレクトリを取得 + template_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)), "template") + # コマンドラインのカレントディレクトリを取得 + current_dir = os.getcwd() - _copy_template( - template_dir, - current_dir, - name, - ) + _copy_template( + template_dir, + current_dir, + name, + ) def _copy_template( - src: str, - dest: str, - name: str, + src: str, + dest: str, + name: str, ) -> None: - dest = os.path.join(dest, name) - shutil.copytree(src, dest) - - # dest以下のファイル内のNAME_PLACEHOLDERをnameに置換 - for root, dirs, files in os.walk(dest): - for file in files: - file_path = os.path.join(root, file) - with open(file_path, "r") as f: - if not file_path.endswith((".py", ".yaml", ".json")): - continue - content = f.read() - with open(file_path, "w") as f: - f.write(content.replace(NAME_PLACEHOLDER, name)) - - # ディレクトリ名のNAME_PLACEHOLDERをnameに置換 - for root, dirs, files in os.walk(dest): - for dir in dirs: - dir_path = os.path.join(root, dir) - new_dir_path = dir_path.replace(NAME_PLACEHOLDER, name) - os.rename(dir_path, new_dir_path) + dest = os.path.join(dest, name) + shutil.copytree(src, dest) + + # dest以下のファイル内のNAME_PLACEHOLDERをnameに置換 + for root, dirs, files in os.walk(dest): + for file in files: + file_path = os.path.join(root, file) + with open(file_path, "r") as f: + if not file_path.endswith((".py", ".yaml", ".json")): + continue + content = f.read() + with open(file_path, "w") as f: + f.write(content.replace(NAME_PLACEHOLDER, name)) + + # ディレクトリ名のNAME_PLACEHOLDERをnameに置換 + for root, dirs, files in os.walk(dest): + for dir in dirs: + dir_path = os.path.join(root, dir) + new_dir_path = dir_path.replace(NAME_PLACEHOLDER, name) + os.rename(dir_path, new_dir_path) if __name__ == "__main__": - cli() + cli() diff --git a/src/adf_core_python/cli/template/main.py b/src/adf_core_python/cli/template/main.py index 82ce430..8630da1 100644 --- a/src/adf_core_python/cli/template/main.py +++ b/src/adf_core_python/cli/template/main.py @@ -1,5 +1,5 @@ from adf_core_python.launcher import Launcher if __name__ == "__main__": - launcher = Launcher("./config/launcher.yaml") - launcher.launch() + launcher = Launcher("./config/launcher.yaml") + launcher.launch() diff --git a/src/adf_core_python/cli/template/src/team_name/module/complex/sample_human_detector.py b/src/adf_core_python/cli/template/src/team_name/module/complex/sample_human_detector.py index 1768cfc..b782c9d 100644 --- a/src/adf_core_python/cli/template/src/team_name/module/complex/sample_human_detector.py +++ b/src/adf_core_python/cli/template/src/team_name/module/complex/sample_human_detector.py @@ -14,136 +14,135 @@ class SampleHumanDetector(HumanDetector): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + self._clustering: Clustering = cast( + Clustering, + module_manager.get_module( + "SampleHumanDetector.Clustering", + "adf_core_python.implement.module.algorithm.k_means_clustering.KMeansClustering", + ), + ) + self.register_sub_module(self._clustering) + + self._result: Optional[EntityID] = None + self._logger = get_agent_logger( + f"{self.__class__.__module__}.{self.__class__.__qualname__}", + self._agent_info, + ) + + def calculate(self) -> HumanDetector: + transport_human: Optional[Human] = self._agent_info.some_one_on_board() + if transport_human is not None: + self._result = transport_human.get_entity_id() + return self + + if self._result is not None: + if not self._is_valid_human(self._result): + self._result = None + + if self._result is None: + self._result = self._select_target() + + return self + + def _select_target(self) -> Optional[EntityID]: + if self._result is not None and self._is_valid_human(self._result): + return self._result + + cluster_index: int = self._clustering.get_cluster_index( + self._agent_info.get_entity_id() + ) + cluster_entities: list[Entity] = self._clustering.get_cluster_entities( + cluster_index + ) + + cluster_valid_human_entities: list[Entity] = [ + entity + for entity in cluster_entities + if self._is_valid_human(entity.get_entity_id()) and isinstance(entity, Civilian) + ] + if len(cluster_valid_human_entities) != 0: + nearest_human_entity = cluster_valid_human_entities[0] + nearest_distance = self._world_info.get_distance( + self._agent_info.get_entity_id(), + nearest_human_entity.get_entity_id(), + ) + for entity in cluster_valid_human_entities: + distance = self._world_info.get_distance( + self._agent_info.get_entity_id(), + entity.get_entity_id(), ) - self._clustering: Clustering = cast( - Clustering, - module_manager.get_module( - "SampleHumanDetector.Clustering", - "adf_core_python.implement.module.algorithm.k_means_clustering.KMeansClustering", - ), + if distance < nearest_distance: + nearest_distance = distance + nearest_human_entity = entity + return nearest_human_entity.get_entity_id() + + world_valid_human_entities: list[Entity] = [ + entity + for entity in self._world_info.get_entities_of_types([Civilian]) + if self._is_valid_human(entity.get_entity_id()) + ] + if len(world_valid_human_entities) != 0: + nearest_human_entity = world_valid_human_entities[0] + nearest_distance = self._world_info.get_distance( + self._agent_info.get_entity_id(), + nearest_human_entity.get_entity_id(), + ) + for entity in world_valid_human_entities: + distance = self._world_info.get_distance( + self._agent_info.get_entity_id(), + entity.get_entity_id(), ) - self.register_sub_module(self._clustering) - - self._result: Optional[EntityID] = None - self._logger = get_agent_logger( - f"{self.__class__.__module__}.{self.__class__.__qualname__}", - self._agent_info, - ) - - def calculate(self) -> HumanDetector: - transport_human: Optional[Human] = self._agent_info.some_one_on_board() - if transport_human is not None: - self._result = transport_human.get_entity_id() - return self - - if self._result is not None: - if not self._is_valid_human(self._result): - self._result = None - - if self._result is None: - self._result = self._select_target() - - return self - - def _select_target(self) -> Optional[EntityID]: - if self._result is not None and self._is_valid_human(self._result): - return self._result - - cluster_index: int = self._clustering.get_cluster_index( - self._agent_info.get_entity_id() - ) - cluster_entities: list[Entity] = self._clustering.get_cluster_entities( - cluster_index - ) - - cluster_valid_human_entities: list[Entity] = [ - entity - for entity in cluster_entities - if self._is_valid_human(entity.get_entity_id()) - and isinstance(entity, Civilian) - ] - if len(cluster_valid_human_entities) != 0: - nearest_human_entity = cluster_valid_human_entities[0] - nearest_distance = self._world_info.get_distance( - self._agent_info.get_entity_id(), - nearest_human_entity.get_entity_id(), - ) - for entity in cluster_valid_human_entities: - distance = self._world_info.get_distance( - self._agent_info.get_entity_id(), - entity.get_entity_id(), - ) - if distance < nearest_distance: - nearest_distance = distance - nearest_human_entity = entity - return nearest_human_entity.get_entity_id() - - world_valid_human_entities: list[Entity] = [ - entity - for entity in self._world_info.get_entities_of_types([Civilian]) - if self._is_valid_human(entity.get_entity_id()) - ] - if len(world_valid_human_entities) != 0: - nearest_human_entity = world_valid_human_entities[0] - nearest_distance = self._world_info.get_distance( - self._agent_info.get_entity_id(), - nearest_human_entity.get_entity_id(), - ) - for entity in world_valid_human_entities: - distance = self._world_info.get_distance( - self._agent_info.get_entity_id(), - entity.get_entity_id(), - ) - if distance < nearest_distance: - nearest_distance = distance - nearest_human_entity = entity - return nearest_human_entity.get_entity_id() - - return None - - def _is_valid_human(self, target_entity_id: EntityID) -> bool: - target: Optional[Entity] = self._world_info.get_entity(target_entity_id) - if target is None: - return False - if not isinstance(target, Human): - return False - hp: Optional[int] = target.get_hp() - if hp is None or hp <= 0: - return False - buriedness: Optional[int] = target.get_buriedness() - if buriedness is None: - return False - myself = self._agent_info.get_myself() - if myself is None: - return False - if myself.get_urn() == EntityURN.FIRE_BRIGADE and buriedness == 0: - return False - if myself.get_urn() == EntityURN.AMBULANCE_TEAM and buriedness > 0: - return False - damage: Optional[int] = target.get_damage() - if damage is None or damage == 0: - return False - position_entity_id: Optional[EntityID] = target.get_position() - if position_entity_id is None: - return False - position: Optional[Entity] = self._world_info.get_entity(position_entity_id) - if position is None: - return False - urn: EntityURN = position.get_urn() - if urn == EntityURN.REFUGE or urn == EntityURN.AMBULANCE_TEAM: - return False - - return True - - def get_target_entity_id(self) -> Optional[EntityID]: - return self._result + if distance < nearest_distance: + nearest_distance = distance + nearest_human_entity = entity + return nearest_human_entity.get_entity_id() + + return None + + def _is_valid_human(self, target_entity_id: EntityID) -> bool: + target: Optional[Entity] = self._world_info.get_entity(target_entity_id) + if target is None: + return False + if not isinstance(target, Human): + return False + hp: Optional[int] = target.get_hp() + if hp is None or hp <= 0: + return False + buriedness: Optional[int] = target.get_buriedness() + if buriedness is None: + return False + myself = self._agent_info.get_myself() + if myself is None: + return False + if myself.get_urn() == EntityURN.FIRE_BRIGADE and buriedness == 0: + return False + if myself.get_urn() == EntityURN.AMBULANCE_TEAM and buriedness > 0: + return False + damage: Optional[int] = target.get_damage() + if damage is None or damage == 0: + return False + position_entity_id: Optional[EntityID] = target.get_position() + if position_entity_id is None: + return False + position: Optional[Entity] = self._world_info.get_entity(position_entity_id) + if position is None: + return False + urn: EntityURN = position.get_urn() + if urn == EntityURN.REFUGE or urn == EntityURN.AMBULANCE_TEAM: + return False + + return True + + def get_target_entity_id(self) -> Optional[EntityID]: + return self._result diff --git a/src/adf_core_python/cli/template/src/team_name/module/complex/sample_road_detector.py b/src/adf_core_python/cli/template/src/team_name/module/complex/sample_road_detector.py index 2e71d61..4ec1295 100644 --- a/src/adf_core_python/cli/template/src/team_name/module/complex/sample_road_detector.py +++ b/src/adf_core_python/cli/template/src/team_name/module/complex/sample_road_detector.py @@ -10,147 +10,143 @@ 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.path_planning import ( - PathPlanning, + PathPlanning, ) from adf_core_python.core.component.module.complex.road_detector import RoadDetector class SampleRoadDetector(RoadDetector): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - - 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: Optional[EntityID] = None - - def precompute(self, precompute_data: PrecomputeData) -> RoadDetector: - super().precompute(precompute_data) + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + + 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: Optional[EntityID] = None + + def precompute(self, precompute_data: PrecomputeData) -> RoadDetector: + super().precompute(precompute_data) + return self + + def resume(self, precompute_data: PrecomputeData) -> RoadDetector: + super().resume(precompute_data) + if self.get_count_resume() >= 2: + return self + + self._target_areas: set[EntityID] = set() + entities = self._world_info.get_entities_of_types([Refuge, Building, GasStation]) + for entity in entities: + if not isinstance(entity, Building): + continue + for entity_id in entity.get_neighbors(): + neighbor = self._world_info.get_entity(entity_id) + if isinstance(neighbor, Road): + self._target_areas.add(entity_id) + + self._priority_roads = set() + for entity in self._world_info.get_entities_of_types([Refuge]): + if not isinstance(entity, Building): + continue + for entity_id in entity.get_neighbors(): + neighbor = self._world_info.get_entity(entity_id) + if isinstance(neighbor, Road): + self._priority_roads.add(entity_id) + + return self + + def prepare(self) -> RoadDetector: + super().prepare() + if self.get_count_prepare() >= 2: + return self + + self._target_areas = set() + entities = self._world_info.get_entities_of_types([Refuge, Building, GasStation]) + for entity in entities: + building: Building = cast(Building, entity) + for entity_id in building.get_neighbors(): + neighbor = self._world_info.get_entity(entity_id) + if isinstance(neighbor, Road): + self._target_areas.add(entity_id) + + self._priority_roads = set() + for entity in self._world_info.get_entities_of_types([Refuge]): + refuge: Refuge = cast(Refuge, entity) + for entity_id in refuge.get_neighbors(): + neighbor = self._world_info.get_entity(entity_id) + if isinstance(neighbor, Road): + self._priority_roads.add(entity_id) + + return self + + def update_info(self, message_manager: MessageManager) -> RoadDetector: + super().update_info(message_manager) + if self.get_count_update_info() >= 2: + return self + + if self._result is not None: + if self._agent_info.get_position_entity_id == self._result: + entity = self._world_info.get_entity(self._result) + if isinstance(entity, Building): + self._result = None + elif isinstance(entity, Road): + road = entity + if road.get_blockades() == []: + self._target_areas.remove(self._result) + self._result = None + + return self + + def calculate(self) -> RoadDetector: + if self._result is None: + position_entity_id = self._agent_info.get_position_entity_id() + if position_entity_id is None: return self - - def resume(self, precompute_data: PrecomputeData) -> RoadDetector: - super().resume(precompute_data) - if self.get_count_resume() >= 2: - return self - - self._target_areas: set[EntityID] = set() - entities = self._world_info.get_entities_of_types( - [Refuge, Building, GasStation] - ) - for entity in entities: - if not isinstance(entity, Building): - continue - for entity_id in entity.get_neighbors(): - neighbor = self._world_info.get_entity(entity_id) - if isinstance(neighbor, Road): - self._target_areas.add(entity_id) - - self._priority_roads = set() - for entity in self._world_info.get_entities_of_types([Refuge]): - if not isinstance(entity, Building): - continue - for entity_id in entity.get_neighbors(): - neighbor = self._world_info.get_entity(entity_id) - if isinstance(neighbor, Road): - self._priority_roads.add(entity_id) - + if position_entity_id in self._target_areas: + self._result = position_entity_id return self - - def prepare(self) -> RoadDetector: - super().prepare() - if self.get_count_prepare() >= 2: - return self - - self._target_areas = set() - entities = self._world_info.get_entities_of_types( - [Refuge, Building, GasStation] + remove_list = [] + for entity_id in self._priority_roads: + if entity_id not in self._target_areas: + remove_list.append(entity_id) + + self._priority_roads = self._priority_roads - set(remove_list) + if len(self._priority_roads) > 0: + agent_position = self._agent_info.get_position_entity_id() + if agent_position is None: + return self + _nearest_target_area = agent_position + _nearest_distance = float("inf") + for target_area in self._target_areas: + if ( + self._world_info.get_distance(agent_position, target_area) + < _nearest_distance + ): + _nearest_target_area = target_area + _nearest_distance = self._world_info.get_distance( + agent_position, target_area + ) + path: list[EntityID] = self._path_planning.get_path( + agent_position, _nearest_target_area ) - for entity in entities: - building: Building = cast(Building, entity) - for entity_id in building.get_neighbors(): - neighbor = self._world_info.get_entity(entity_id) - if isinstance(neighbor, Road): - self._target_areas.add(entity_id) - - self._priority_roads = set() - for entity in self._world_info.get_entities_of_types([Refuge]): - refuge: Refuge = cast(Refuge, entity) - for entity_id in refuge.get_neighbors(): - neighbor = self._world_info.get_entity(entity_id) - if isinstance(neighbor, Road): - self._priority_roads.add(entity_id) - - return self - - def update_info(self, message_manager: MessageManager) -> RoadDetector: - super().update_info(message_manager) - if self.get_count_update_info() >= 2: - return self - - if self._result is not None: - if self._agent_info.get_position_entity_id == self._result: - entity = self._world_info.get_entity(self._result) - if isinstance(entity, Building): - self._result = None - elif isinstance(entity, Road): - road = entity - if road.get_blockades() == []: - self._target_areas.remove(self._result) - self._result = None + if path is not None and len(path) > 0: + self._result = path[-1] - return self - - def calculate(self) -> RoadDetector: - if self._result is None: - position_entity_id = self._agent_info.get_position_entity_id() - if position_entity_id is None: - return self - if position_entity_id in self._target_areas: - self._result = position_entity_id - return self - remove_list = [] - for entity_id in self._priority_roads: - if entity_id not in self._target_areas: - remove_list.append(entity_id) - - self._priority_roads = self._priority_roads - set(remove_list) - if len(self._priority_roads) > 0: - agent_position = self._agent_info.get_position_entity_id() - if agent_position is None: - return self - _nearest_target_area = agent_position - _nearest_distance = float("inf") - for target_area in self._target_areas: - if ( - self._world_info.get_distance(agent_position, target_area) - < _nearest_distance - ): - _nearest_target_area = target_area - _nearest_distance = self._world_info.get_distance( - agent_position, target_area - ) - path: list[EntityID] = self._path_planning.get_path( - agent_position, _nearest_target_area - ) - if path is not None and len(path) > 0: - self._result = path[-1] - - return self + return self - def get_target_entity_id(self) -> Optional[EntityID]: - return self._result + def get_target_entity_id(self) -> Optional[EntityID]: + return self._result diff --git a/src/adf_core_python/cli/template/src/team_name/module/complex/sample_search.py b/src/adf_core_python/cli/template/src/team_name/module/complex/sample_search.py index 888f657..9da8af3 100644 --- a/src/adf_core_python/cli/template/src/team_name/module/complex/sample_search.py +++ b/src/adf_core_python/cli/template/src/team_name/module/complex/sample_search.py @@ -15,90 +15,90 @@ class SampleSearch(Search): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - - self._unreached_building_ids: set[EntityID] = set() - self._result: Optional[EntityID] = None - - self._clustering: Clustering = cast( - Clustering, - module_manager.get_module( - "SampleSearch.Clustering", - "adf_core_python.implement.module.algorithm.k_means_clustering.KMeansClustering", - ), - ) - - self._path_planning: PathPlanning = cast( - PathPlanning, - module_manager.get_module( - "SampleSearch.PathPlanning", - "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", - ), - ) - - self._logger = get_agent_logger( - f"{self.__class__.__module__}.{self.__class__.__qualname__}", - self._agent_info, - ) - - self.register_sub_module(self._clustering) - self.register_sub_module(self._path_planning) - - def update_info(self, message_manager: MessageManager) -> Search: - super().update_info(message_manager) - if self.get_count_update_info() > 1: - return self - - self._logger.debug( - f"unreached_building_ids: {[str(id) for id in self._unreached_building_ids]}" - ) - - searched_building_id = self._agent_info.get_position_entity_id() - if searched_building_id is not None: - self._unreached_building_ids.discard(searched_building_id) - - if len(self._unreached_building_ids) == 0: - self._unreached_building_ids = self._get_search_targets() - - return self - - def calculate(self) -> Search: - nearest_building_id: Optional[EntityID] = None - nearest_distance: Optional[float] = None - for building_id in self._unreached_building_ids: - distance = self._world_info.get_distance( - self._agent_info.get_entity_id(), building_id - ) - if nearest_distance is None or distance < nearest_distance: - nearest_building_id = building_id - nearest_distance = distance - self._result = nearest_building_id - return self - - def get_target_entity_id(self) -> Optional[EntityID]: - return self._result - - def _get_search_targets(self) -> set[EntityID]: - cluster_index: int = self._clustering.get_cluster_index( - self._agent_info.get_entity_id() - ) - cluster_entities: list[Entity] = self._clustering.get_cluster_entities( - cluster_index - ) - building_entity_ids: list[EntityID] = [ - entity.get_entity_id() - for entity in cluster_entities - if isinstance(entity, Building) and not isinstance(entity, Refuge) - ] - - return set(building_entity_ids) + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + + self._unreached_building_ids: set[EntityID] = set() + self._result: Optional[EntityID] = None + + self._clustering: Clustering = cast( + Clustering, + module_manager.get_module( + "SampleSearch.Clustering", + "adf_core_python.implement.module.algorithm.k_means_clustering.KMeansClustering", + ), + ) + + self._path_planning: PathPlanning = cast( + PathPlanning, + module_manager.get_module( + "SampleSearch.PathPlanning", + "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", + ), + ) + + self._logger = get_agent_logger( + f"{self.__class__.__module__}.{self.__class__.__qualname__}", + self._agent_info, + ) + + self.register_sub_module(self._clustering) + self.register_sub_module(self._path_planning) + + def update_info(self, message_manager: MessageManager) -> Search: + super().update_info(message_manager) + if self.get_count_update_info() > 1: + return self + + self._logger.debug( + f"unreached_building_ids: {[str(id) for id in self._unreached_building_ids]}" + ) + + searched_building_id = self._agent_info.get_position_entity_id() + if searched_building_id is not None: + self._unreached_building_ids.discard(searched_building_id) + + if len(self._unreached_building_ids) == 0: + self._unreached_building_ids = self._get_search_targets() + + return self + + def calculate(self) -> Search: + nearest_building_id: Optional[EntityID] = None + nearest_distance: Optional[float] = None + for building_id in self._unreached_building_ids: + distance = self._world_info.get_distance( + self._agent_info.get_entity_id(), building_id + ) + if nearest_distance is None or distance < nearest_distance: + nearest_building_id = building_id + nearest_distance = distance + self._result = nearest_building_id + return self + + def get_target_entity_id(self) -> Optional[EntityID]: + return self._result + + def _get_search_targets(self) -> set[EntityID]: + cluster_index: int = self._clustering.get_cluster_index( + self._agent_info.get_entity_id() + ) + cluster_entities: list[Entity] = self._clustering.get_cluster_entities( + cluster_index + ) + building_entity_ids: list[EntityID] = [ + entity.get_entity_id() + for entity in cluster_entities + if isinstance(entity, Building) and not isinstance(entity, Refuge) + ] + + return set(building_entity_ids) diff --git a/src/adf_core_python/core/agent/action/action.py b/src/adf_core_python/core/agent/action/action.py index 911b028..551d18e 100644 --- a/src/adf_core_python/core/agent/action/action.py +++ b/src/adf_core_python/core/agent/action/action.py @@ -5,9 +5,9 @@ class Action(ABC): - def __init__(self) -> None: - pass + def __init__(self) -> None: + pass - @abstractmethod - def get_command(self, agent_id: EntityID, time: int) -> Command: - raise NotImplementedError + @abstractmethod + def get_command(self, agent_id: EntityID, time: int) -> Command: + raise NotImplementedError diff --git a/src/adf_core_python/core/agent/action/ambulance/action_load.py b/src/adf_core_python/core/agent/action/ambulance/action_load.py index 1e9eee5..572b50b 100644 --- a/src/adf_core_python/core/agent/action/ambulance/action_load.py +++ b/src/adf_core_python/core/agent/action/ambulance/action_load.py @@ -5,11 +5,11 @@ class ActionLoad(Action): - def __init__(self, target_id: EntityID) -> None: - self.target_id = target_id + def __init__(self, target_id: EntityID) -> None: + self.target_id = target_id - def get_command(self, agent_id: EntityID, time: int) -> Command: - return AKLoad(agent_id, time, self.target_id) + def get_command(self, agent_id: EntityID, time: int) -> Command: + return AKLoad(agent_id, time, self.target_id) - def __str__(self) -> str: - return f"ActionLoad(target_id={self.target_id})" + def __str__(self) -> str: + return f"ActionLoad(target_id={self.target_id})" diff --git a/src/adf_core_python/core/agent/action/ambulance/action_rescue.py b/src/adf_core_python/core/agent/action/ambulance/action_rescue.py index e3ad8e1..8e3ce84 100644 --- a/src/adf_core_python/core/agent/action/ambulance/action_rescue.py +++ b/src/adf_core_python/core/agent/action/ambulance/action_rescue.py @@ -5,11 +5,11 @@ class ActionRescue(Action): - def __init__(self, target_id: EntityID) -> None: - self.target_id = target_id + def __init__(self, target_id: EntityID) -> None: + self.target_id = target_id - def get_command(self, agent_id: EntityID, time: int) -> Command: - return AKRescue(agent_id, time, self.target_id) + def get_command(self, agent_id: EntityID, time: int) -> Command: + return AKRescue(agent_id, time, self.target_id) - def __str__(self) -> str: - return f"ActionRescue(target_id={self.target_id})" + def __str__(self) -> str: + return f"ActionRescue(target_id={self.target_id})" diff --git a/src/adf_core_python/core/agent/action/ambulance/action_unload.py b/src/adf_core_python/core/agent/action/ambulance/action_unload.py index 2f725cb..4c46458 100644 --- a/src/adf_core_python/core/agent/action/ambulance/action_unload.py +++ b/src/adf_core_python/core/agent/action/ambulance/action_unload.py @@ -5,8 +5,8 @@ class ActionUnload(Action): - def get_command(self, agent_id: EntityID, time: int) -> Command: - return AKUnload(agent_id, time) + def get_command(self, agent_id: EntityID, time: int) -> Command: + return AKUnload(agent_id, time) - def __str__(self) -> str: - return "ActionUnload()" + def __str__(self) -> str: + return "ActionUnload()" diff --git a/src/adf_core_python/core/agent/action/common/action_move.py b/src/adf_core_python/core/agent/action/common/action_move.py index c2829a8..b6ddac0 100644 --- a/src/adf_core_python/core/agent/action/common/action_move.py +++ b/src/adf_core_python/core/agent/action/common/action_move.py @@ -7,33 +7,31 @@ class ActionMove(Action): - def __init__( - self, - path: list[EntityID], - destination_x: Optional[int] = None, - destination_y: Optional[int] = None, - ) -> None: - self.path = path - self.destination_x = destination_x - self.destination_y = destination_y - - def is_destination_defined(self) -> bool: - return self.destination_x is not None and self.destination_y is not None - - def get_destination_x(self) -> Optional[int]: - return self.destination_x - - def get_destination_y(self) -> Optional[int]: - return self.destination_y - - def get_command(self, agent_id: EntityID, time: int) -> Command: - if self.destination_x is not None and self.destination_y is not None: - return AKMove( - agent_id, time, self.path, self.destination_x, self.destination_y - ) - else: - return AKMove(agent_id, time, self.path) - - def __str__(self) -> str: - path: str = ", ".join([str(p) for p in self.path]) - return f"ActionMove(path={path}, destination_x={self.destination_x}, destination_y={self.destination_y})" + def __init__( + self, + path: list[EntityID], + destination_x: Optional[int] = None, + destination_y: Optional[int] = None, + ) -> None: + self.path = path + self.destination_x = destination_x + self.destination_y = destination_y + + def is_destination_defined(self) -> bool: + return self.destination_x is not None and self.destination_y is not None + + def get_destination_x(self) -> Optional[int]: + return self.destination_x + + def get_destination_y(self) -> Optional[int]: + return self.destination_y + + def get_command(self, agent_id: EntityID, time: int) -> Command: + if self.destination_x is not None and self.destination_y is not None: + return AKMove(agent_id, time, self.path, self.destination_x, self.destination_y) + else: + return AKMove(agent_id, time, self.path) + + def __str__(self) -> str: + path: str = ", ".join([str(p) for p in self.path]) + return f"ActionMove(path={path}, destination_x={self.destination_x}, destination_y={self.destination_y})" diff --git a/src/adf_core_python/core/agent/action/common/action_rest.py b/src/adf_core_python/core/agent/action/common/action_rest.py index 94bfaea..1d61001 100644 --- a/src/adf_core_python/core/agent/action/common/action_rest.py +++ b/src/adf_core_python/core/agent/action/common/action_rest.py @@ -5,8 +5,8 @@ class ActionRest(Action): - def get_command(self, agent_id: EntityID, time: int) -> Command: - return AKRest(agent_id, time) + def get_command(self, agent_id: EntityID, time: int) -> Command: + return AKRest(agent_id, time) - def __str__(self) -> str: - return "ActionRest()" + def __str__(self) -> str: + return "ActionRest()" diff --git a/src/adf_core_python/core/agent/action/fire/action_extinguish.py b/src/adf_core_python/core/agent/action/fire/action_extinguish.py index 64713a9..e14a663 100644 --- a/src/adf_core_python/core/agent/action/fire/action_extinguish.py +++ b/src/adf_core_python/core/agent/action/fire/action_extinguish.py @@ -5,14 +5,12 @@ class ActionExtinguish(Action): - def __init__(self, target_id: EntityID, max_power: int) -> None: - self.target_id = target_id - self.max_power = max_power + def __init__(self, target_id: EntityID, max_power: int) -> None: + self.target_id = target_id + self.max_power = max_power - def get_command(self, agent_id: EntityID, time: int) -> Command: - return AKExtinguish(agent_id, time, self.target_id, self.max_power) + def get_command(self, agent_id: EntityID, time: int) -> Command: + return AKExtinguish(agent_id, time, self.target_id, self.max_power) - def __str__(self) -> str: - return ( - f"ActionExtinguish(target_id={self.target_id}, max_power={self.max_power})" - ) + def __str__(self) -> str: + return f"ActionExtinguish(target_id={self.target_id}, max_power={self.max_power})" diff --git a/src/adf_core_python/core/agent/action/fire/action_refill.py b/src/adf_core_python/core/agent/action/fire/action_refill.py index 15c0242..8d11578 100644 --- a/src/adf_core_python/core/agent/action/fire/action_refill.py +++ b/src/adf_core_python/core/agent/action/fire/action_refill.py @@ -5,8 +5,8 @@ class ActionRefill(Action): - def get_command(self, agent_id: EntityID, time: int) -> Command: - return AKRest(agent_id, time) + def get_command(self, agent_id: EntityID, time: int) -> Command: + return AKRest(agent_id, time) - def __str__(self) -> str: - return "ActionRefill()" + def __str__(self) -> str: + return "ActionRefill()" diff --git a/src/adf_core_python/core/agent/action/fire/action_rescue.py b/src/adf_core_python/core/agent/action/fire/action_rescue.py index e3ad8e1..8e3ce84 100644 --- a/src/adf_core_python/core/agent/action/fire/action_rescue.py +++ b/src/adf_core_python/core/agent/action/fire/action_rescue.py @@ -5,11 +5,11 @@ class ActionRescue(Action): - def __init__(self, target_id: EntityID) -> None: - self.target_id = target_id + def __init__(self, target_id: EntityID) -> None: + self.target_id = target_id - def get_command(self, agent_id: EntityID, time: int) -> Command: - return AKRescue(agent_id, time, self.target_id) + def get_command(self, agent_id: EntityID, time: int) -> Command: + return AKRescue(agent_id, time, self.target_id) - def __str__(self) -> str: - return f"ActionRescue(target_id={self.target_id})" + def __str__(self) -> str: + return f"ActionRescue(target_id={self.target_id})" diff --git a/src/adf_core_python/core/agent/action/police/action_clear.py b/src/adf_core_python/core/agent/action/police/action_clear.py index 6ba35d3..2709b72 100644 --- a/src/adf_core_python/core/agent/action/police/action_clear.py +++ b/src/adf_core_python/core/agent/action/police/action_clear.py @@ -5,11 +5,11 @@ class ActionClear(Action): - def __init__(self, blockade: Blockade) -> None: - self.blockade = blockade + def __init__(self, blockade: Blockade) -> None: + self.blockade = blockade - def get_command(self, agent_id: EntityID, time: int) -> Command: - return AKClear(agent_id, time, self.blockade.get_entity_id()) + def get_command(self, agent_id: EntityID, time: int) -> Command: + return AKClear(agent_id, time, self.blockade.get_entity_id()) - def __str__(self) -> str: - return f"ActionClear(blockade={self.blockade})" + def __str__(self) -> str: + return f"ActionClear(blockade={self.blockade})" diff --git a/src/adf_core_python/core/agent/action/police/action_clear_area.py b/src/adf_core_python/core/agent/action/police/action_clear_area.py index be92c8a..41dbc63 100644 --- a/src/adf_core_python/core/agent/action/police/action_clear_area.py +++ b/src/adf_core_python/core/agent/action/police/action_clear_area.py @@ -5,18 +5,20 @@ class ActionClearArea(Action): - def __init__(self, position_x: int, position_y: int) -> None: - self.position_x = position_x - self.position_y = position_y + def __init__(self, position_x: int, position_y: int) -> None: + self.position_x = position_x + self.position_y = position_y - def get_position_x(self) -> int: - return self.position_x + def get_position_x(self) -> int: + return self.position_x - def get_position_y(self) -> int: - return self.position_y + def get_position_y(self) -> int: + return self.position_y - def get_command(self, agent_id: EntityID, time: int) -> Command: - return AKClearArea(agent_id, time, self.position_x, self.position_y) + def get_command(self, agent_id: EntityID, time: int) -> Command: + return AKClearArea(agent_id, time, self.position_x, self.position_y) - def __str__(self) -> str: - return f"ActionClearArea(position_x={self.position_x}, position_y={self.position_y})" + def __str__(self) -> str: + return ( + f"ActionClearArea(position_x={self.position_x}, position_y={self.position_y})" + ) diff --git a/src/adf_core_python/core/agent/agent.py b/src/adf_core_python/core/agent/agent.py index e3409c4..f96dd58 100644 --- a/src/adf_core_python/core/agent/agent.py +++ b/src/adf_core_python/core/agent/agent.py @@ -6,18 +6,18 @@ from bitarray import bitarray from rcrscore.commands import ( - AKClear, - AKClearArea, - AKLoad, - AKMove, - AKRescue, - AKRest, - AKSay, - AKSpeak, - AKSubscribe, - AKTell, - AKUnload, - Command, + AKClear, + AKClearArea, + AKLoad, + AKMove, + AKRescue, + AKRest, + AKSay, + AKSpeak, + AKSubscribe, + AKTell, + AKUnload, + Command, ) from rcrscore.config.config import Config as RCRSConfig @@ -34,57 +34,57 @@ # from rcrscore.messages.KAConnectOK import KAConnectOK # from rcrscore.messages.KASense import KASense from rcrscore.messages import ( - AKAcknowledge, - AKConnect, - ControlMessageFactory, - KAConnectError, - KAConnectOK, - KASense, + AKAcknowledge, + AKConnect, + ControlMessageFactory, + KAConnectError, + KAConnectOK, + KASense, ) from rcrscore.urn import ( - CommandURN, - ComponentCommandURN, - ComponentControlMessageURN, - EntityURN, + CommandURN, + ComponentCommandURN, + ComponentControlMessageURN, + EntityURN, ) from rcrscore.worldmodel import ChangeSet, WorldModel from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.communication.standard.bundle.centralized.command_ambulance import ( - CommandAmbulance, + CommandAmbulance, ) from adf_core_python.core.agent.communication.standard.bundle.centralized.command_fire import ( - CommandFire, + CommandFire, ) from adf_core_python.core.agent.communication.standard.bundle.centralized.command_police import ( - CommandPolice, + CommandPolice, ) from adf_core_python.core.agent.communication.standard.bundle.centralized.command_scout import ( - CommandScout, + CommandScout, ) from adf_core_python.core.agent.communication.standard.bundle.centralized.message_report import ( - MessageReport, + MessageReport, ) from adf_core_python.core.agent.communication.standard.bundle.information.message_ambulance_team import ( - MessageAmbulanceTeam, + MessageAmbulanceTeam, ) from adf_core_python.core.agent.communication.standard.bundle.information.message_building import ( - MessageBuilding, + MessageBuilding, ) from adf_core_python.core.agent.communication.standard.bundle.information.message_civilian import ( - MessageCivilian, + MessageCivilian, ) from adf_core_python.core.agent.communication.standard.bundle.information.message_fire_brigade import ( - MessageFireBrigade, + MessageFireBrigade, ) from adf_core_python.core.agent.communication.standard.bundle.information.message_police_force import ( - MessagePoliceForce, + MessagePoliceForce, ) from adf_core_python.core.agent.communication.standard.bundle.information.message_road import ( - MessageRoad, + MessageRoad, ) from adf_core_python.core.agent.communication.standard.standard_communication_module import ( - StandardCommunicationModule, + StandardCommunicationModule, ) from adf_core_python.core.agent.config.module_config import ModuleConfig from adf_core_python.core.agent.develop.develop_data import DevelopData @@ -93,7 +93,7 @@ from adf_core_python.core.agent.info.world_info import WorldInfo from adf_core_python.core.agent.precompute.precompute_data import PrecomputeData from adf_core_python.core.component.communication.communication_module import ( - CommunicationModule, + CommunicationModule, ) from adf_core_python.core.config.config import Config from adf_core_python.core.gateway.gateway_agent import GatewayAgent @@ -102,291 +102,285 @@ class Agent: - def __init__( - self, - is_precompute: bool, - name: str, - is_debug: bool, - team_name: str, - data_storage_name: str, - module_config: ModuleConfig, - develop_data: DevelopData, - finish_post_connect_event: Event, - gateway_agent: Optional[GatewayAgent], - ) -> None: - self.name = name - self.connect_request_id = None - self.world_model = WorldModel() - self.config: Config - self.random = None - self.agent_id: EntityID - self.precompute_flag = is_precompute - self.logger = get_logger( - f"{self.__class__.__module__}.{self.__class__.__qualname__}" + def __init__( + self, + is_precompute: bool, + name: str, + is_debug: bool, + team_name: str, + data_storage_name: str, + module_config: ModuleConfig, + develop_data: DevelopData, + finish_post_connect_event: Event, + gateway_agent: Optional[GatewayAgent], + ) -> None: + self.name = name + self.connect_request_id = None + self.world_model = WorldModel() + self.config: Config + self.random = None + self.agent_id: EntityID + self.precompute_flag = is_precompute + self.logger = get_logger( + f"{self.__class__.__module__}.{self.__class__.__qualname__}" + ) + self.finish_post_connect_event = finish_post_connect_event + + self.team_name = team_name + self.is_debug = is_debug + self.is_precompute = is_precompute + + if is_precompute: + 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._message_manager: MessageManager = MessageManager() + self._communication_module: CommunicationModule = StandardCommunicationModule() + + self._gateway_agent: Optional[GatewayAgent] = gateway_agent + + def get_entity_id(self) -> EntityID: + return self.agent_id + + def set_send_msg(self, connection_send_func: Callable) -> None: + self.send_msg = connection_send_func + + def post_connect(self) -> None: + if self.is_precompute: + self._mode = Mode.PRECOMPUTATION + else: + 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( + ConfigKey.KEY_DEVELOP_FLAG, self._develop_data.is_develop_mode() + ) + self._ignore_time: int = int(self.config.get_value("kernel.agents.ignoreuntil", 3)) + + self._scenario_info: ScenarioInfo = ScenarioInfo(self.config, self._mode) + self._world_info: WorldInfo = WorldInfo(self.world_model) + self._agent_info = AgentInfo(self, self.world_model) + + if isinstance(self._gateway_agent, GatewayAgent): + self._gateway_agent.set_initialize_data( + self._agent_info, self._world_info, self._scenario_info + ) + + self.logger = get_agent_logger( + f"{self.__class__.__module__}.{self.__class__.__qualname__}", + self._agent_info, + ) + self.logger.debug(f"agent_config: {self.config}") + + def update_step_info( + self, time: int, change_set: ChangeSet, hear: list[Command] + ) -> None: + self._agent_info.record_think_start_time() + self._agent_info.set_time(time) + + if time == 1: + self._message_manager.register_message_class(0, MessageAmbulanceTeam) + self._message_manager.register_message_class(1, MessageFireBrigade) + self._message_manager.register_message_class(2, MessagePoliceForce) + self._message_manager.register_message_class(3, MessageBuilding) + self._message_manager.register_message_class(4, MessageCivilian) + self._message_manager.register_message_class(5, MessageRoad) + self._message_manager.register_message_class(6, CommandAmbulance) + self._message_manager.register_message_class(7, CommandFire) + self._message_manager.register_message_class(8, CommandPolice) + self._message_manager.register_message_class(9, CommandScout) + self._message_manager.register_message_class(10, MessageReport) + + if time > self._ignore_time: + self._message_manager.subscribe( + self._agent_info, self._world_info, self._scenario_info + ) + if not self._message_manager.get_is_subscribed(): + subscribed_channels = self._message_manager.get_subscribed_channels() + if subscribed_channels: + self.logger.debug( + f"Subscribed channels: {subscribed_channels}", + message_manager=self._message_manager, + ) + self.send_subscribe(time, subscribed_channels) + self._message_manager.set_is_subscribed(True) + + self._agent_info.set_heard_commands(hear) + self._agent_info.set_change_set(change_set) + self._world_info.set_change_set(change_set) + + if ( + isinstance(self._gateway_agent, GatewayAgent) + and self._gateway_agent.is_initialized() + ): + self._gateway_agent.update() + + self._message_manager.refresh() + self._communication_module.receive(self, self._message_manager) + + self.think() + + self._message_manager.coordinate_message( + self._agent_info, self._world_info, self._scenario_info + ) + self._communication_module.send(self, self._message_manager) + + @abstractmethod + def think(self) -> None: + pass + + @abstractmethod + def get_requested_entities(self) -> list[EntityURN]: + pass + + def start_up(self, request_id: int) -> None: + ak_connect = AKConnect() + self.send_msg( + ak_connect.write(request_id, self.name, self.get_requested_entities()) + ) + + def message_received(self, msg: Any) -> None: + c_msg = ControlMessageFactory().make_message(msg) + if isinstance(c_msg, KASense): + self.handler_sense(c_msg) + elif isinstance(c_msg, KAConnectOK): + self.handle_connect_ok(c_msg) + elif isinstance(c_msg, KAConnectError): + self.handle_connect_error(c_msg) + + def handle_connect_error(self, msg: Any) -> NoReturn: + if msg.reason.startswith("No more agents"): + self.logger.debug( + "Agent already connected: %s(request_id: %s)", + msg.reason, + msg.request_id, + ) + self.finish_post_connect_event.set() + else: + self.logger.error( + "Failed to connect agent: %s(request_id: %s)", + msg.reason, + msg.request_id, + ) + sys.exit(1) + + def handle_connect_ok(self, msg: Any) -> None: + self.agent_id = EntityID(msg.agent_id) + self.world_model.add_entities(msg.world) + config: RCRSConfig = msg.config + self.config = Config() + if config is not None: + for key, value in config.data.items(): + self.config.set_value(key, value) + + self.send_acknowledge(msg.request_id) + self.post_connect() + self.logger.info( + 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.is_precompute: + self.logger.info("Precompute finished") + exit(0) + + self.finish_post_connect_event.set() + + def handler_sense(self, msg: KASense) -> None: + _id = msg.agent_id + time = msg.time + change_set = msg.change_set + heard = msg.hear.commands + + if _id != self.get_entity_id(): + self.logger.error("Agent ID mismatch: %s != %s", _id, self.get_entity_id()) + return + + heard_commands: list[Command] = [] + for heard_command in heard: + if heard_command.urn == CommandURN.AK_SPEAK: + heard_commands.append( + AKSpeak( + EntityID( + heard_command.components[ComponentControlMessageURN.AgentID].entityID + ), + heard_command.components[ComponentControlMessageURN.Time].intValue, + heard_command.components[ComponentCommandURN.Message].rawData, + heard_command.components[ComponentCommandURN.Channel].intValue, + ) ) - self.finish_post_connect_event = finish_post_connect_event - - self.team_name = team_name - self.is_debug = is_debug - self.is_precompute = is_precompute - - if is_precompute: - 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._message_manager: MessageManager = MessageManager() - self._communication_module: CommunicationModule = StandardCommunicationModule() - - self._gateway_agent: Optional[GatewayAgent] = gateway_agent - - def get_entity_id(self) -> EntityID: - return self.agent_id - - def set_send_msg(self, connection_send_func: Callable) -> None: - self.send_msg = connection_send_func - - def post_connect(self) -> None: - if self.is_precompute: - self._mode = Mode.PRECOMPUTATION - else: - 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( - ConfigKey.KEY_DEVELOP_FLAG, self._develop_data.is_develop_mode() - ) - self._ignore_time: int = int( - self.config.get_value("kernel.agents.ignoreuntil", 3) - ) - - self._scenario_info: ScenarioInfo = ScenarioInfo(self.config, self._mode) - self._world_info: WorldInfo = WorldInfo(self.world_model) - self._agent_info = AgentInfo(self, self.world_model) - - if isinstance(self._gateway_agent, GatewayAgent): - self._gateway_agent.set_initialize_data( - self._agent_info, self._world_info, self._scenario_info - ) - - self.logger = get_agent_logger( - f"{self.__class__.__module__}.{self.__class__.__qualname__}", - self._agent_info, - ) - self.logger.debug(f"agent_config: {self.config}") - - def update_step_info( - self, time: int, change_set: ChangeSet, hear: list[Command] - ) -> None: - self._agent_info.record_think_start_time() - self._agent_info.set_time(time) - - if time == 1: - self._message_manager.register_message_class(0, MessageAmbulanceTeam) - self._message_manager.register_message_class(1, MessageFireBrigade) - self._message_manager.register_message_class(2, MessagePoliceForce) - self._message_manager.register_message_class(3, MessageBuilding) - self._message_manager.register_message_class(4, MessageCivilian) - self._message_manager.register_message_class(5, MessageRoad) - self._message_manager.register_message_class(6, CommandAmbulance) - self._message_manager.register_message_class(7, CommandFire) - self._message_manager.register_message_class(8, CommandPolice) - self._message_manager.register_message_class(9, CommandScout) - self._message_manager.register_message_class(10, MessageReport) - - if time > self._ignore_time: - self._message_manager.subscribe( - self._agent_info, self._world_info, self._scenario_info - ) - if not self._message_manager.get_is_subscribed(): - subscribed_channels = self._message_manager.get_subscribed_channels() - if subscribed_channels: - self.logger.debug( - f"Subscribed channels: {subscribed_channels}", - message_manager=self._message_manager, - ) - self.send_subscribe(time, subscribed_channels) - self._message_manager.set_is_subscribed(True) - - self._agent_info.set_heard_commands(hear) - self._agent_info.set_change_set(change_set) - self._world_info.set_change_set(change_set) - - if ( - isinstance(self._gateway_agent, GatewayAgent) - and self._gateway_agent.is_initialized() - ): - self._gateway_agent.update() - - self._message_manager.refresh() - self._communication_module.receive(self, self._message_manager) - - self.think() - - self._message_manager.coordinate_message( - self._agent_info, self._world_info, self._scenario_info - ) - self._communication_module.send(self, self._message_manager) - - @abstractmethod - def think(self) -> None: - pass - - @abstractmethod - def get_requested_entities(self) -> list[EntityURN]: - pass - - def start_up(self, request_id: int) -> None: - ak_connect = AKConnect() - self.send_msg( - ak_connect.write(request_id, self.name, self.get_requested_entities()) - ) - - def message_received(self, msg: Any) -> None: - c_msg = ControlMessageFactory().make_message(msg) - if isinstance(c_msg, KASense): - self.handler_sense(c_msg) - elif isinstance(c_msg, KAConnectOK): - self.handle_connect_ok(c_msg) - elif isinstance(c_msg, KAConnectError): - self.handle_connect_error(c_msg) - - def handle_connect_error(self, msg: Any) -> NoReturn: - if msg.reason.startswith("No more agents"): - self.logger.debug( - "Agent already connected: %s(request_id: %s)", - msg.reason, - msg.request_id, - ) - self.finish_post_connect_event.set() - else: - self.logger.error( - "Failed to connect agent: %s(request_id: %s)", - msg.reason, - msg.request_id, - ) - sys.exit(1) - - def handle_connect_ok(self, msg: Any) -> None: - self.agent_id = EntityID(msg.agent_id) - self.world_model.add_entities(msg.world) - config: RCRSConfig = msg.config - self.config = Config() - if config is not None: - for key, value in config.data.items(): - self.config.set_value(key, value) - - self.send_acknowledge(msg.request_id) - self.post_connect() - self.logger.info( - 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.is_precompute: - self.logger.info("Precompute finished") - exit(0) - - self.finish_post_connect_event.set() - - def handler_sense(self, msg: KASense) -> None: - _id = msg.agent_id - time = msg.time - change_set = msg.change_set - heard = msg.hear.commands - - if _id != self.get_entity_id(): - self.logger.error("Agent ID mismatch: %s != %s", _id, self.get_entity_id()) - return - - heard_commands: list[Command] = [] - for heard_command in heard: - if heard_command.urn == CommandURN.AK_SPEAK: - heard_commands.append( - AKSpeak( - EntityID( - heard_command.components[ - ComponentControlMessageURN.AgentID - ].entityID - ), - heard_command.components[ - ComponentControlMessageURN.Time - ].intValue, - heard_command.components[ComponentCommandURN.Message].rawData, - heard_command.components[ComponentCommandURN.Channel].intValue, - ) - ) - self.world_model.merge(change_set) - start_update_info_time = _time.time() - self.update_step_info(time, change_set, heard_commands) - self.logger.debug( - f"{time} step calculation time: {_time.time() - start_update_info_time}" - ) - - def send_acknowledge(self, request_id: int) -> None: - ak_ack = AKAcknowledge() - self.send_msg(ak_ack.write(request_id, self.agent_id)) - - def send_clear(self, time: int, target: EntityID) -> None: - cmd = AKClear(self.get_entity_id(), time, target) - msg = cmd.to_message_proto() - self.send_msg(msg) - - def send_clear_area(self, time: int, x: int = -1, y: int = -1) -> None: - cmd = AKClearArea(self.get_entity_id(), time, x, y) - msg = cmd.to_message_proto() - self.send_msg(msg) - - def send_load(self, time: int, target: EntityID) -> None: - cmd = AKLoad(self.get_entity_id(), time, target) - msg = cmd.to_message_proto() - self.send_msg(msg) - - def send_move( - self, time: int, path: list[EntityID], x: int = -1, y: int = -1 - ) -> None: - cmd = AKMove(self.get_entity_id(), time, path, x, y) - msg = cmd.to_message_proto() - self.send_msg(msg) - - def send_rescue(self, time: int, target: EntityID) -> None: - cmd = AKRescue(self.get_entity_id(), time, target) - msg = cmd.to_message_proto() - self.send_msg(msg) - - def send_rest(self, time: int) -> None: - cmd = AKRest(self.get_entity_id(), time) - msg = cmd.to_message_proto() - self.send_msg(msg) - - def send_say(self, time_step: int, message: bytes) -> None: - cmd = AKSay(self.get_entity_id(), time_step, message) - msg = cmd.to_message_proto() - self.send_msg(msg) - - def send_speak(self, time_step: int, message: bitarray, channel: int) -> None: - cmd = AKSpeak(self.get_entity_id(), time_step, bytes(message), channel) # type: ignore - msg = cmd.to_message_proto() - self.send_msg(msg) - - def send_subscribe(self, time: int, channels: list[int]) -> None: - cmd = AKSubscribe(self.get_entity_id(), time, channels) - msg = cmd.to_message_proto() - self.send_msg(msg) - - def send_tell(self, time: int, message: bytes) -> None: - cmd = AKTell(self.get_entity_id(), time, message) - msg = cmd.to_message_proto() - self.send_msg(msg) - - def send_unload(self, time: int) -> None: - cmd = AKUnload(self.get_entity_id(), time) - msg = cmd.to_message_proto() - self.send_msg(msg) + self.world_model.merge(change_set) + start_update_info_time = _time.time() + self.update_step_info(time, change_set, heard_commands) + self.logger.debug( + f"{time} step calculation time: {_time.time() - start_update_info_time}" + ) + + def send_acknowledge(self, request_id: int) -> None: + ak_ack = AKAcknowledge() + self.send_msg(ak_ack.write(request_id, self.agent_id)) + + def send_clear(self, time: int, target: EntityID) -> None: + cmd = AKClear(self.get_entity_id(), time, target) + msg = cmd.to_message_proto() + self.send_msg(msg) + + def send_clear_area(self, time: int, x: int = -1, y: int = -1) -> None: + cmd = AKClearArea(self.get_entity_id(), time, x, y) + msg = cmd.to_message_proto() + self.send_msg(msg) + + def send_load(self, time: int, target: EntityID) -> None: + cmd = AKLoad(self.get_entity_id(), time, target) + msg = cmd.to_message_proto() + self.send_msg(msg) + + def send_move( + self, time: int, path: list[EntityID], x: int = -1, y: int = -1 + ) -> None: + cmd = AKMove(self.get_entity_id(), time, path, x, y) + msg = cmd.to_message_proto() + self.send_msg(msg) + + def send_rescue(self, time: int, target: EntityID) -> None: + cmd = AKRescue(self.get_entity_id(), time, target) + msg = cmd.to_message_proto() + self.send_msg(msg) + + def send_rest(self, time: int) -> None: + cmd = AKRest(self.get_entity_id(), time) + msg = cmd.to_message_proto() + self.send_msg(msg) + + def send_say(self, time_step: int, message: bytes) -> None: + cmd = AKSay(self.get_entity_id(), time_step, message) + msg = cmd.to_message_proto() + self.send_msg(msg) + + def send_speak(self, time_step: int, message: bitarray, channel: int) -> None: + cmd = AKSpeak(self.get_entity_id(), time_step, bytes(message), channel) # type: ignore + msg = cmd.to_message_proto() + self.send_msg(msg) + + def send_subscribe(self, time: int, channels: list[int]) -> None: + cmd = AKSubscribe(self.get_entity_id(), time, channels) + msg = cmd.to_message_proto() + self.send_msg(msg) + + def send_tell(self, time: int, message: bytes) -> None: + cmd = AKTell(self.get_entity_id(), time, message) + msg = cmd.to_message_proto() + self.send_msg(msg) + + def send_unload(self, time: int) -> None: + cmd = AKUnload(self.get_entity_id(), time) + msg = cmd.to_message_proto() + self.send_msg(msg) diff --git a/src/adf_core_python/core/agent/communication/message_manager.py b/src/adf_core_python/core/agent/communication/message_manager.py index fc16479..f66fc89 100644 --- a/src/adf_core_python/core/agent/communication/message_manager.py +++ b/src/adf_core_python/core/agent/communication/message_manager.py @@ -6,370 +6,366 @@ from adf_core_python.core.agent.info.world_info import WorldInfo if TYPE_CHECKING: - from adf_core_python.core.agent.info.agent_info import AgentInfo - from adf_core_python.core.component.communication.channel_subscriber import ( - ChannelSubscriber, - ) - from adf_core_python.core.component.communication.communication_message import ( - CommunicationMessage, - ) - from adf_core_python.core.component.communication.message_coordinator import ( - MessageCoordinator, - ) + from adf_core_python.core.agent.info.agent_info import AgentInfo + from adf_core_python.core.component.communication.channel_subscriber import ( + ChannelSubscriber, + ) + from adf_core_python.core.component.communication.communication_message import ( + CommunicationMessage, + ) + from adf_core_python.core.component.communication.message_coordinator import ( + MessageCoordinator, + ) class MessageManager: - MAX_MESSAGE_CLASS_COUNT = 32 - - def __init__(self) -> None: - """ - Initialize the MessageManager. - - Parameters - ---------- - __standard_message_class_count : int - The count of standard message classes. - __custom_message_class_count : int - The count of custom message classes. - __message_classes : dict[int, CommunicationMessage] - The message classes. - __subscribed_channels : list[int] - The subscribed channels. Default is [1]. - __is_subscribed : bool - The flag to indicate if the agent is subscribed to the channel. - """ - self.__standard_message_class_count = 0b0000_0001 - self.__custom_message_class_count = 0b0001_0000 - self.__message_classes: dict[int, type[CommunicationMessage]] = {} - self.__send_message_list: list[CommunicationMessage] = [] - self.__received_message_list: list[CommunicationMessage] = [] - self.__channel_send_message_list: list[list[CommunicationMessage]] = [] - self.__check_duplicate_cache: set[int] = set() - self.__message_coordinator: MessageCoordinator - self.__channel_subscriber: ChannelSubscriber - self.__heard_agent_help_message_count: int = 0 - self.__subscribed_channels: list[int] = [1] - self.__is_subscribed = False - - def set_subscribed_channels(self, subscribed_channels: list[int]) -> None: - """ - Set the subscribed channels. - - Parameters - ---------- - subscribed_channels : list[int] - The subscribed channels. - - """ - self.__subscribed_channels = subscribed_channels - self.__is_subscribed = False - - def get_subscribed_channels(self) -> list[int]: - """ - Get the subscribed channels. - - Returns - ------- - list[int] - The subscribed channels. - - """ - return self.__subscribed_channels - - def set_is_subscribed(self, is_subscribed: bool) -> None: - """ - Set the flag to indicate if the agent is subscribed to the channel. - - Parameters - ---------- - is_subscribed : bool - The flag to indicate if the agent is subscribed to the channel. - - """ - self.__is_subscribed = is_subscribed - - def get_is_subscribed(self) -> bool: - """ - Get the flag to indicate if the agent is subscribed to the channel. - - Returns - ------- - bool - The flag to indicate if the agent is subscribed to the channel. - - """ - return self.__is_subscribed - - def set_channel_subscriber(self, channel_subscriber: ChannelSubscriber) -> None: - """ - Set the channel subscriber. - - Parameters - ---------- - channel_subscriber : ChannelSubscriber - The channel subscriber. - - """ - self.__channel_subscriber = channel_subscriber - - def set_message_coordinator(self, message_coordinator: MessageCoordinator) -> None: - """ - Set the message coordinator. - - Parameters - ---------- - message_coordinator : MessageCoordinator - The message coordinator. - - """ - self.__message_coordinator = message_coordinator - - def get_channel_subscriber(self) -> ChannelSubscriber: - """ - Get the channel subscriber. - - Returns - ------- - ChannelSubscriber - The channel subscriber. - - """ - return self.__channel_subscriber - - def add_heard_agent_help_message_count(self) -> None: - """ - Add the heard agent help message count. - - """ - self.__heard_agent_help_message_count += 1 - - def get_heard_agent_help_message_count(self) -> int: - """ - Get the heard agent help message count. - - Returns - ------- - int - The heard agent help message count. - - """ - return self.__heard_agent_help_message_count - - def add_received_message(self, message: CommunicationMessage) -> None: - """ - Add the received message. - - Parameters - ---------- - message : CommunicationMessage - The received message. - - """ - self.__received_message_list.append(message) - - def get_received_message_list(self) -> list[CommunicationMessage]: - """ - Get the received message list. - - Returns - ------- - list[CommunicationMessage] - The received message list. - - """ - return self.__received_message_list - - def get_channel_send_message_list(self) -> list[list[CommunicationMessage]]: - """ - Get the channel send message list. - - Returns - ------- - list[list[CommunicationMessage]] - The channel send message list. - - """ - return self.__channel_send_message_list - - def subscribe( - self, agent_info: AgentInfo, world_info: WorldInfo, scenario_info: ScenarioInfo - ) -> None: - """ - Subscribe to the channel. - - Parameters - ---------- - agent_info : AgentInfo - The agent info. - world_info : WorldInfo - The world info. - scenario_info : ScenarioInfo - The scenario info. - - Throws - ------ - ValueError - If the ChannelSubscriber is not set. - - """ - if self.__channel_subscriber is None: - raise ValueError("ChannelSubscriber is not set.") - - if agent_info.get_time() == 1: - self.__subscribed_channels = self.__channel_subscriber.subscribe( - agent_info, world_info, scenario_info - ) - - def register_message_class( - self, index: int, message_class: type[CommunicationMessage] - ) -> None: - """ - Register the message class. - - Parameters - ---------- - message_class : type[CommunicationMessage] - The message class. - - """ - if index >= self.MAX_MESSAGE_CLASS_COUNT: - raise ValueError( - f"Possible index values are 0 to {self.MAX_MESSAGE_CLASS_COUNT - 1}" - ) - self.__message_classes[index] = message_class - - def get_message_class(self, index: int) -> type[CommunicationMessage]: - """ - Get the message class. - - Parameters - ---------- - index : int - The index. - - Returns - ------- - type[CommunicationMessage] - The message class. - - """ - return self.__message_classes[index] - - def get_message_class_index(self, message_class: type[CommunicationMessage]) -> int: - """ - Get the message class index. - - Parameters - ---------- - message_class : type[CommunicationMessage] - The message class. - - Returns - ------- - int - The message class index. - - """ - for index, cls in self.__message_classes.items(): - if cls == message_class: - return index - return -1 - - def add_message( - self, message: CommunicationMessage, check_duplicate: bool = True - ) -> None: - """ - Add the message. - - Parameters - ---------- - message : CommunicationMessage - The message. - - """ - check_key = message.__hash__() - # TODO:両方同じコードになっているが、なぜなのか調査する - if check_duplicate and check_key not in self.__check_duplicate_cache: - self.__send_message_list.append(message) - self.__check_duplicate_cache.add(check_key) - else: - self.__send_message_list.append(message) - self.__check_duplicate_cache.add(check_key) - - def get_send_message_list(self) -> list[CommunicationMessage]: - """ - Get the send message list. - - Returns - ------- - list[CommunicationMessage] - The send message list. - - """ - return self.__send_message_list - - def coordinate_message( - self, agent_info: AgentInfo, world_info: WorldInfo, scenario_info: ScenarioInfo - ) -> None: - """ - Coordinate the message. - - Parameters - ---------- - agent_info : AgentInfo - The agent info. - world_info : WorldInfo - The world info. - scenario_info : ScenarioInfo - The scenario info. - - """ - if self.__message_coordinator is None: - raise ValueError("MessageCoordinator is not set.") - - self.__channel_send_message_list = [ - [] - for _ in range( - int( - scenario_info.get_value( - ScenarioInfoKeys.COMMUNICATION_CHANNELS_COUNT, 1 - ) - ) - ) - ] - - self.__message_coordinator.coordinate( - agent_info, - world_info, - scenario_info, - self, - self.__send_message_list, - self.__channel_send_message_list, - ) - - def refresh(self) -> None: - """ - Refresh the message manager. - - """ - self.__send_message_list = [] - self.__received_message_list = [] - self.__check_duplicate_cache = set() - self.__heard_agent_help_message_count = 0 - - def __str__(self) -> str: - return ( - f"MessageManager(" - f"standard_message_class_count={self.__standard_message_class_count}, " - f"custom_message_class_count={self.__custom_message_class_count}, " - f"message_classes={self.__message_classes}, " - f"send_message_list={self.__send_message_list}, " - f"received_message_list={self.__received_message_list}, " - f"channel_send_message_list={self.__channel_send_message_list}, " - f"check_duplicate_cache={self.__check_duplicate_cache}, " - f"message_coordinator={self.__message_coordinator}, " - f"channel_subscriber={self.__channel_subscriber}, " - f"heard_agent_help_message_count={self.__heard_agent_help_message_count}, " - f"subscribed_channels={self.__subscribed_channels}, " - f"is_subscribed={self.__is_subscribed})" - ) + MAX_MESSAGE_CLASS_COUNT = 32 + + def __init__(self) -> None: + """ + Initialize the MessageManager. + + Parameters + ---------- + __standard_message_class_count : int + The count of standard message classes. + __custom_message_class_count : int + The count of custom message classes. + __message_classes : dict[int, CommunicationMessage] + The message classes. + __subscribed_channels : list[int] + The subscribed channels. Default is [1]. + __is_subscribed : bool + The flag to indicate if the agent is subscribed to the channel. + """ + self.__standard_message_class_count = 0b0000_0001 + self.__custom_message_class_count = 0b0001_0000 + self.__message_classes: dict[int, type[CommunicationMessage]] = {} + self.__send_message_list: list[CommunicationMessage] = [] + self.__received_message_list: list[CommunicationMessage] = [] + self.__channel_send_message_list: list[list[CommunicationMessage]] = [] + self.__check_duplicate_cache: set[int] = set() + self.__message_coordinator: MessageCoordinator + self.__channel_subscriber: ChannelSubscriber + self.__heard_agent_help_message_count: int = 0 + self.__subscribed_channels: list[int] = [1] + self.__is_subscribed = False + + def set_subscribed_channels(self, subscribed_channels: list[int]) -> None: + """ + Set the subscribed channels. + + Parameters + ---------- + subscribed_channels : list[int] + The subscribed channels. + + """ + self.__subscribed_channels = subscribed_channels + self.__is_subscribed = False + + def get_subscribed_channels(self) -> list[int]: + """ + Get the subscribed channels. + + Returns + ------- + list[int] + The subscribed channels. + + """ + return self.__subscribed_channels + + def set_is_subscribed(self, is_subscribed: bool) -> None: + """ + Set the flag to indicate if the agent is subscribed to the channel. + + Parameters + ---------- + is_subscribed : bool + The flag to indicate if the agent is subscribed to the channel. + + """ + self.__is_subscribed = is_subscribed + + def get_is_subscribed(self) -> bool: + """ + Get the flag to indicate if the agent is subscribed to the channel. + + Returns + ------- + bool + The flag to indicate if the agent is subscribed to the channel. + + """ + return self.__is_subscribed + + def set_channel_subscriber(self, channel_subscriber: ChannelSubscriber) -> None: + """ + Set the channel subscriber. + + Parameters + ---------- + channel_subscriber : ChannelSubscriber + The channel subscriber. + + """ + self.__channel_subscriber = channel_subscriber + + def set_message_coordinator(self, message_coordinator: MessageCoordinator) -> None: + """ + Set the message coordinator. + + Parameters + ---------- + message_coordinator : MessageCoordinator + The message coordinator. + + """ + self.__message_coordinator = message_coordinator + + def get_channel_subscriber(self) -> ChannelSubscriber: + """ + Get the channel subscriber. + + Returns + ------- + ChannelSubscriber + The channel subscriber. + + """ + return self.__channel_subscriber + + def add_heard_agent_help_message_count(self) -> None: + """ + Add the heard agent help message count. + + """ + self.__heard_agent_help_message_count += 1 + + def get_heard_agent_help_message_count(self) -> int: + """ + Get the heard agent help message count. + + Returns + ------- + int + The heard agent help message count. + + """ + return self.__heard_agent_help_message_count + + def add_received_message(self, message: CommunicationMessage) -> None: + """ + Add the received message. + + Parameters + ---------- + message : CommunicationMessage + The received message. + + """ + self.__received_message_list.append(message) + + def get_received_message_list(self) -> list[CommunicationMessage]: + """ + Get the received message list. + + Returns + ------- + list[CommunicationMessage] + The received message list. + + """ + return self.__received_message_list + + def get_channel_send_message_list(self) -> list[list[CommunicationMessage]]: + """ + Get the channel send message list. + + Returns + ------- + list[list[CommunicationMessage]] + The channel send message list. + + """ + return self.__channel_send_message_list + + def subscribe( + self, agent_info: AgentInfo, world_info: WorldInfo, scenario_info: ScenarioInfo + ) -> None: + """ + Subscribe to the channel. + + Parameters + ---------- + agent_info : AgentInfo + The agent info. + world_info : WorldInfo + The world info. + scenario_info : ScenarioInfo + The scenario info. + + Throws + ------ + ValueError + If the ChannelSubscriber is not set. + + """ + if self.__channel_subscriber is None: + raise ValueError("ChannelSubscriber is not set.") + + if agent_info.get_time() == 1: + self.__subscribed_channels = self.__channel_subscriber.subscribe( + agent_info, world_info, scenario_info + ) + + def register_message_class( + self, index: int, message_class: type[CommunicationMessage] + ) -> None: + """ + Register the message class. + + Parameters + ---------- + message_class : type[CommunicationMessage] + The message class. + + """ + if index >= self.MAX_MESSAGE_CLASS_COUNT: + raise ValueError( + f"Possible index values are 0 to {self.MAX_MESSAGE_CLASS_COUNT - 1}" + ) + self.__message_classes[index] = message_class + + def get_message_class(self, index: int) -> type[CommunicationMessage]: + """ + Get the message class. + + Parameters + ---------- + index : int + The index. + + Returns + ------- + type[CommunicationMessage] + The message class. + + """ + return self.__message_classes[index] + + def get_message_class_index(self, message_class: type[CommunicationMessage]) -> int: + """ + Get the message class index. + + Parameters + ---------- + message_class : type[CommunicationMessage] + The message class. + + Returns + ------- + int + The message class index. + + """ + for index, cls in self.__message_classes.items(): + if cls == message_class: + return index + return -1 + + def add_message( + self, message: CommunicationMessage, check_duplicate: bool = True + ) -> None: + """ + Add the message. + + Parameters + ---------- + message : CommunicationMessage + The message. + + """ + check_key = message.__hash__() + # TODO:両方同じコードになっているが、なぜなのか調査する + if check_duplicate and check_key not in self.__check_duplicate_cache: + self.__send_message_list.append(message) + self.__check_duplicate_cache.add(check_key) + else: + self.__send_message_list.append(message) + self.__check_duplicate_cache.add(check_key) + + def get_send_message_list(self) -> list[CommunicationMessage]: + """ + Get the send message list. + + Returns + ------- + list[CommunicationMessage] + The send message list. + + """ + return self.__send_message_list + + def coordinate_message( + self, agent_info: AgentInfo, world_info: WorldInfo, scenario_info: ScenarioInfo + ) -> None: + """ + Coordinate the message. + + Parameters + ---------- + agent_info : AgentInfo + The agent info. + world_info : WorldInfo + The world info. + scenario_info : ScenarioInfo + The scenario info. + + """ + if self.__message_coordinator is None: + raise ValueError("MessageCoordinator is not set.") + + self.__channel_send_message_list = [ + [] + for _ in range( + int(scenario_info.get_value(ScenarioInfoKeys.COMMUNICATION_CHANNELS_COUNT, 1)) + ) + ] + + self.__message_coordinator.coordinate( + agent_info, + world_info, + scenario_info, + self, + self.__send_message_list, + self.__channel_send_message_list, + ) + + def refresh(self) -> None: + """ + Refresh the message manager. + + """ + self.__send_message_list = [] + self.__received_message_list = [] + self.__check_duplicate_cache = set() + self.__heard_agent_help_message_count = 0 + + def __str__(self) -> str: + return ( + f"MessageManager(" + f"standard_message_class_count={self.__standard_message_class_count}, " + f"custom_message_class_count={self.__custom_message_class_count}, " + f"message_classes={self.__message_classes}, " + f"send_message_list={self.__send_message_list}, " + f"received_message_list={self.__received_message_list}, " + f"channel_send_message_list={self.__channel_send_message_list}, " + f"check_duplicate_cache={self.__check_duplicate_cache}, " + f"message_coordinator={self.__message_coordinator}, " + f"channel_subscriber={self.__channel_subscriber}, " + f"heard_agent_help_message_count={self.__heard_agent_help_message_count}, " + f"subscribed_channels={self.__subscribed_channels}, " + f"is_subscribed={self.__is_subscribed})" + ) diff --git a/src/adf_core_python/core/agent/communication/standard/bundle/centralized/command_ambulance.py b/src/adf_core_python/core/agent/communication/standard/bundle/centralized/command_ambulance.py index 1a0a2f0..6398af7 100644 --- a/src/adf_core_python/core/agent/communication/standard/bundle/centralized/command_ambulance.py +++ b/src/adf_core_python/core/agent/communication/standard/bundle/centralized/command_ambulance.py @@ -6,130 +6,128 @@ from rcrscore.entities import EntityID from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( - StandardMessage, + StandardMessage, ) from adf_core_python.core.agent.communication.standard.bundle.standard_message_priority import ( - StandardMessagePriority, + StandardMessagePriority, ) from adf_core_python.core.agent.communication.standard.utility.bitarray_with_exits_flag import ( - read_with_exist_flag, - write_with_exist_flag, + read_with_exist_flag, + write_with_exist_flag, ) class CommandAmbulance(StandardMessage): - ACTION_REST: int = 0 - ACTION_MOVE: int = 1 - ACTION_RESCUE: int = 2 - ACTION_LOAD: int = 3 - ACTION_UNLOAD: int = 4 - ACTION_AUTONOMY: int = 5 - - SIZE_AMBULANCE_TEAM_ENTITY_ID: int = 32 - SIZE_TARGET_ENTITY_ID: int = 32 - SIZE_ACTION: int = 4 - - def __init__( - self, - is_wireless_message: bool, - command_executor_agent_entity_id: EntityID, - sender_entity_id: EntityID, - execute_action: int, - priority: StandardMessagePriority, - command_target_entity_id: Optional[EntityID] = None, - ): - super().__init__(is_wireless_message, priority, sender_entity_id) - self._command_executor_agent_entity_id: Optional[EntityID] = ( - command_executor_agent_entity_id - ) - self._command_target_entity_id: Optional[EntityID] = command_target_entity_id - self._is_bloadcast: bool = command_target_entity_id is None - self._execute_action: Optional[int] = execute_action - - def get_command_executor_agent_entity_id(self) -> Optional[EntityID]: - return self._command_executor_agent_entity_id - - def get_command_target_entity_id(self) -> Optional[EntityID]: - return self._command_target_entity_id - - def get_execute_action(self) -> Optional[int]: - return self._execute_action - - def is_broadcast(self) -> bool: - return self._is_bloadcast - - def get_bit_size(self) -> int: - return self.to_bits().__len__() - - def to_bits(self) -> bitarray: - bit_array = super().to_bits() - raw_command_executor_agent_entity_id = ( - self._command_executor_agent_entity_id.get_value() - if self._command_executor_agent_entity_id is not None - else None - ) - write_with_exist_flag( - bit_array, - raw_command_executor_agent_entity_id, - self.SIZE_AMBULANCE_TEAM_ENTITY_ID, - ) - raw_command_target_entity_id = ( - self._command_target_entity_id.get_value() - if self._command_target_entity_id is not None - else None - ) - write_with_exist_flag( - bit_array, raw_command_target_entity_id, self.SIZE_TARGET_ENTITY_ID - ) - write_with_exist_flag(bit_array, self._execute_action, self.SIZE_ACTION) - return bit_array - - @classmethod - def from_bits( - cls, - bit_array: bitarray, - is_wireless_message: bool, - sender_entity_id: EntityID, - ) -> CommandAmbulance: - std_message = super().from_bits( - bit_array, is_wireless_message, sender_entity_id - ) - raw_command_executor_agent_entity_id = read_with_exist_flag( - bit_array, cls.SIZE_AMBULANCE_TEAM_ENTITY_ID - ) - command_executor_agent_id = ( - EntityID(raw_command_executor_agent_entity_id) - if raw_command_executor_agent_entity_id is not None - else None - ) - raw_command_target_entity_id = read_with_exist_flag( - bit_array, cls.SIZE_TARGET_ENTITY_ID - ) - command_target_id = ( - EntityID(raw_command_target_entity_id) - if raw_command_target_entity_id is not None - else None - ) - execute_action = read_with_exist_flag(bit_array, cls.SIZE_ACTION) - return cls( - is_wireless_message, - command_executor_agent_id or EntityID(-1), - sender_entity_id, - execute_action if execute_action is not None else -1, - std_message.get_priority(), - command_target_id, - ) - - def __hash__(self) -> int: - h = super().__hash__() - return hash( - ( - h, - self._command_executor_agent_entity_id, - self._command_target_entity_id, - self._execute_action, - ) - ) - - def __str__(self) -> str: - return f"CommandAmbulance(executor={self._command_executor_agent_entity_id}, target={self._command_target_entity_id}, action={self._execute_action})" + ACTION_REST: int = 0 + ACTION_MOVE: int = 1 + ACTION_RESCUE: int = 2 + ACTION_LOAD: int = 3 + ACTION_UNLOAD: int = 4 + ACTION_AUTONOMY: int = 5 + + SIZE_AMBULANCE_TEAM_ENTITY_ID: int = 32 + SIZE_TARGET_ENTITY_ID: int = 32 + SIZE_ACTION: int = 4 + + def __init__( + self, + is_wireless_message: bool, + command_executor_agent_entity_id: EntityID, + sender_entity_id: EntityID, + execute_action: int, + priority: StandardMessagePriority, + command_target_entity_id: Optional[EntityID] = None, + ): + super().__init__(is_wireless_message, priority, sender_entity_id) + self._command_executor_agent_entity_id: Optional[EntityID] = ( + command_executor_agent_entity_id + ) + self._command_target_entity_id: Optional[EntityID] = command_target_entity_id + self._is_bloadcast: bool = command_target_entity_id is None + self._execute_action: Optional[int] = execute_action + + def get_command_executor_agent_entity_id(self) -> Optional[EntityID]: + return self._command_executor_agent_entity_id + + def get_command_target_entity_id(self) -> Optional[EntityID]: + return self._command_target_entity_id + + def get_execute_action(self) -> Optional[int]: + return self._execute_action + + def is_broadcast(self) -> bool: + return self._is_bloadcast + + def get_bit_size(self) -> int: + return self.to_bits().__len__() + + def to_bits(self) -> bitarray: + bit_array = super().to_bits() + raw_command_executor_agent_entity_id = ( + self._command_executor_agent_entity_id.get_value() + if self._command_executor_agent_entity_id is not None + else None + ) + write_with_exist_flag( + bit_array, + raw_command_executor_agent_entity_id, + self.SIZE_AMBULANCE_TEAM_ENTITY_ID, + ) + raw_command_target_entity_id = ( + self._command_target_entity_id.get_value() + if self._command_target_entity_id is not None + else None + ) + write_with_exist_flag( + bit_array, raw_command_target_entity_id, self.SIZE_TARGET_ENTITY_ID + ) + write_with_exist_flag(bit_array, self._execute_action, self.SIZE_ACTION) + return bit_array + + @classmethod + def from_bits( + cls, + bit_array: bitarray, + is_wireless_message: bool, + sender_entity_id: EntityID, + ) -> CommandAmbulance: + std_message = super().from_bits(bit_array, is_wireless_message, sender_entity_id) + raw_command_executor_agent_entity_id = read_with_exist_flag( + bit_array, cls.SIZE_AMBULANCE_TEAM_ENTITY_ID + ) + command_executor_agent_id = ( + EntityID(raw_command_executor_agent_entity_id) + if raw_command_executor_agent_entity_id is not None + else None + ) + raw_command_target_entity_id = read_with_exist_flag( + bit_array, cls.SIZE_TARGET_ENTITY_ID + ) + command_target_id = ( + EntityID(raw_command_target_entity_id) + if raw_command_target_entity_id is not None + else None + ) + execute_action = read_with_exist_flag(bit_array, cls.SIZE_ACTION) + return cls( + is_wireless_message, + command_executor_agent_id or EntityID(-1), + sender_entity_id, + execute_action if execute_action is not None else -1, + std_message.get_priority(), + command_target_id, + ) + + def __hash__(self) -> int: + h = super().__hash__() + return hash( + ( + h, + self._command_executor_agent_entity_id, + self._command_target_entity_id, + self._execute_action, + ) + ) + + def __str__(self) -> str: + return f"CommandAmbulance(executor={self._command_executor_agent_entity_id}, target={self._command_target_entity_id}, action={self._execute_action})" diff --git a/src/adf_core_python/core/agent/communication/standard/bundle/centralized/command_fire.py b/src/adf_core_python/core/agent/communication/standard/bundle/centralized/command_fire.py index a4bd8ae..3dc7d02 100644 --- a/src/adf_core_python/core/agent/communication/standard/bundle/centralized/command_fire.py +++ b/src/adf_core_python/core/agent/communication/standard/bundle/centralized/command_fire.py @@ -6,131 +6,129 @@ from rcrscore.entities import EntityID from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( - StandardMessage, + StandardMessage, ) from adf_core_python.core.agent.communication.standard.bundle.standard_message_priority import ( - StandardMessagePriority, + StandardMessagePriority, ) from adf_core_python.core.agent.communication.standard.utility.bitarray_with_exits_flag import ( - read_with_exist_flag, - write_with_exist_flag, + read_with_exist_flag, + write_with_exist_flag, ) class CommandFire(StandardMessage): - ACTION_REST: int = 0 - ACTION_MOVE: int = 1 - ACTION_EXTINGUISH: int = 2 - ACTION_REFILL: int = 3 - ACTION_RESCUE: int = 4 - ACTION_AUTONOMY: int = 5 - - SIZE_FIRE_BRIGADE_ENTITY_ID: int = 32 - SIZE_TARGET_ENTITY_ID: int = 32 - SIZE_ACTION: int = 4 - - def __init__( - self, - is_wireless_message: bool, - command_executor_agent_entity_id: EntityID, - sender_entity_id: EntityID, - execute_action: int, - priority: StandardMessagePriority, - command_target_entity_id: Optional[EntityID] = None, - ): - super().__init__(is_wireless_message, priority, sender_entity_id) - self._command_executor_agent_entity_id: Optional[EntityID] = ( - command_executor_agent_entity_id - ) - self._command_target_entity_id: Optional[EntityID] = command_target_entity_id - self._is_bloadcast: bool = command_target_entity_id is None - self._execute_action: Optional[int] = execute_action - - def get_command_executor_agent_entity_id(self) -> Optional[EntityID]: - return self._command_executor_agent_entity_id - - def get_command_target_entity_id(self) -> Optional[EntityID]: - return self._command_target_entity_id - - def get_execute_action(self) -> Optional[int]: - return self._execute_action - - def is_broadcast(self) -> bool: - return self._is_bloadcast - - def get_bit_size(self) -> int: - return self.to_bits().__len__() - - def to_bits(self) -> bitarray: - bit_array = super().to_bits() - raw_command_executor_agent_entity_id = ( - self._command_executor_agent_entity_id.get_value() - if self._command_executor_agent_entity_id is not None - else None - ) - write_with_exist_flag( - bit_array, - raw_command_executor_agent_entity_id, - self.SIZE_FIRE_BRIGADE_ENTITY_ID, - ) - raw_command_target_entity_id = ( - self._command_target_entity_id.get_value() - if self._command_target_entity_id is not None - else None - ) - write_with_exist_flag( - bit_array, raw_command_target_entity_id, self.SIZE_TARGET_ENTITY_ID - ) - write_with_exist_flag(bit_array, self._execute_action, self.SIZE_ACTION) - - return bit_array - - @classmethod - def from_bits( - cls, - bit_array: bitarray, - is_wireless_message: bool, - sender_entity_id: EntityID, - ) -> CommandFire: - std_message = super().from_bits( - bit_array, is_wireless_message, sender_entity_id - ) - raw_command_executor_agent_entity_id = read_with_exist_flag( - bit_array, cls.SIZE_FIRE_BRIGADE_ENTITY_ID - ) - command_executor_agent_id = ( - EntityID(raw_command_executor_agent_entity_id) - if raw_command_executor_agent_entity_id is not None - else None - ) - raw_command_target_entity_id = read_with_exist_flag( - bit_array, cls.SIZE_TARGET_ENTITY_ID - ) - command_target_id = ( - EntityID(raw_command_target_entity_id) - if raw_command_target_entity_id is not None - else None - ) - execute_action = read_with_exist_flag(bit_array, cls.SIZE_ACTION) - return cls( - is_wireless_message, - command_executor_agent_id or EntityID(-1), - sender_entity_id, - execute_action if execute_action is not None else -1, - std_message.get_priority(), - command_target_id, - ) - - def __hash__(self) -> int: - h = super().__hash__() - return hash( - ( - h, - self._command_executor_agent_entity_id, - self._command_target_entity_id, - self._execute_action, - ) - ) - - def __str__(self) -> str: - return f"CommandFire(executor={self._command_executor_agent_entity_id}, target={self._command_target_entity_id}, action={self._execute_action})" + ACTION_REST: int = 0 + ACTION_MOVE: int = 1 + ACTION_EXTINGUISH: int = 2 + ACTION_REFILL: int = 3 + ACTION_RESCUE: int = 4 + ACTION_AUTONOMY: int = 5 + + SIZE_FIRE_BRIGADE_ENTITY_ID: int = 32 + SIZE_TARGET_ENTITY_ID: int = 32 + SIZE_ACTION: int = 4 + + def __init__( + self, + is_wireless_message: bool, + command_executor_agent_entity_id: EntityID, + sender_entity_id: EntityID, + execute_action: int, + priority: StandardMessagePriority, + command_target_entity_id: Optional[EntityID] = None, + ): + super().__init__(is_wireless_message, priority, sender_entity_id) + self._command_executor_agent_entity_id: Optional[EntityID] = ( + command_executor_agent_entity_id + ) + self._command_target_entity_id: Optional[EntityID] = command_target_entity_id + self._is_bloadcast: bool = command_target_entity_id is None + self._execute_action: Optional[int] = execute_action + + def get_command_executor_agent_entity_id(self) -> Optional[EntityID]: + return self._command_executor_agent_entity_id + + def get_command_target_entity_id(self) -> Optional[EntityID]: + return self._command_target_entity_id + + def get_execute_action(self) -> Optional[int]: + return self._execute_action + + def is_broadcast(self) -> bool: + return self._is_bloadcast + + def get_bit_size(self) -> int: + return self.to_bits().__len__() + + def to_bits(self) -> bitarray: + bit_array = super().to_bits() + raw_command_executor_agent_entity_id = ( + self._command_executor_agent_entity_id.get_value() + if self._command_executor_agent_entity_id is not None + else None + ) + write_with_exist_flag( + bit_array, + raw_command_executor_agent_entity_id, + self.SIZE_FIRE_BRIGADE_ENTITY_ID, + ) + raw_command_target_entity_id = ( + self._command_target_entity_id.get_value() + if self._command_target_entity_id is not None + else None + ) + write_with_exist_flag( + bit_array, raw_command_target_entity_id, self.SIZE_TARGET_ENTITY_ID + ) + write_with_exist_flag(bit_array, self._execute_action, self.SIZE_ACTION) + + return bit_array + + @classmethod + def from_bits( + cls, + bit_array: bitarray, + is_wireless_message: bool, + sender_entity_id: EntityID, + ) -> CommandFire: + std_message = super().from_bits(bit_array, is_wireless_message, sender_entity_id) + raw_command_executor_agent_entity_id = read_with_exist_flag( + bit_array, cls.SIZE_FIRE_BRIGADE_ENTITY_ID + ) + command_executor_agent_id = ( + EntityID(raw_command_executor_agent_entity_id) + if raw_command_executor_agent_entity_id is not None + else None + ) + raw_command_target_entity_id = read_with_exist_flag( + bit_array, cls.SIZE_TARGET_ENTITY_ID + ) + command_target_id = ( + EntityID(raw_command_target_entity_id) + if raw_command_target_entity_id is not None + else None + ) + execute_action = read_with_exist_flag(bit_array, cls.SIZE_ACTION) + return cls( + is_wireless_message, + command_executor_agent_id or EntityID(-1), + sender_entity_id, + execute_action if execute_action is not None else -1, + std_message.get_priority(), + command_target_id, + ) + + def __hash__(self) -> int: + h = super().__hash__() + return hash( + ( + h, + self._command_executor_agent_entity_id, + self._command_target_entity_id, + self._execute_action, + ) + ) + + def __str__(self) -> str: + return f"CommandFire(executor={self._command_executor_agent_entity_id}, target={self._command_target_entity_id}, action={self._execute_action})" diff --git a/src/adf_core_python/core/agent/communication/standard/bundle/centralized/command_police.py b/src/adf_core_python/core/agent/communication/standard/bundle/centralized/command_police.py index c57f2fb..2c70726 100644 --- a/src/adf_core_python/core/agent/communication/standard/bundle/centralized/command_police.py +++ b/src/adf_core_python/core/agent/communication/standard/bundle/centralized/command_police.py @@ -6,129 +6,127 @@ from rcrscore.entities import EntityID from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( - StandardMessage, + StandardMessage, ) from adf_core_python.core.agent.communication.standard.bundle.standard_message_priority import ( - StandardMessagePriority, + StandardMessagePriority, ) from adf_core_python.core.agent.communication.standard.utility.bitarray_with_exits_flag import ( - read_with_exist_flag, - write_with_exist_flag, + read_with_exist_flag, + write_with_exist_flag, ) class CommandPolice(StandardMessage): - ACTION_REST: int = 0 - ACTION_MOVE: int = 1 - ACTION_CLEAR: int = 2 - ACTION_AUTONOMY: int = 3 - - SIZE_POLICE_FORCE_ENTITY_ID: int = 32 - SIZE_TARGET_ENTITY_ID: int = 32 - SIZE_ACTION: int = 4 - - def __init__( - self, - is_wireless_message: bool, - command_executor_agent_entity_id: EntityID, - sender_entity_id: EntityID, - execute_action: int, - priority: StandardMessagePriority, - command_target_entity_id: Optional[EntityID] = None, - ): - super().__init__(is_wireless_message, priority, sender_entity_id) - self._command_executor_agent_entity_id: Optional[EntityID] = ( - command_executor_agent_entity_id - ) - self._command_target_entity_id: Optional[EntityID] = command_target_entity_id - self._is_bloadcast: bool = command_target_entity_id is None - self._execute_action: Optional[int] = execute_action - - def get_command_executor_agent_entity_id(self) -> Optional[EntityID]: - return self._command_executor_agent_entity_id - - def get_command_target_entity_id(self) -> Optional[EntityID]: - return self._command_target_entity_id - - def get_execute_action(self) -> Optional[int]: - return self._execute_action - - def is_broadcast(self) -> bool: - return self._is_bloadcast - - def get_bit_size(self) -> int: - return self.to_bits().__len__() - - def to_bits(self) -> bitarray: - bit_array = super().to_bits() - raw_command_executor_agent_entity_id = ( - self._command_executor_agent_entity_id.get_value() - if self._command_executor_agent_entity_id is not None - else None - ) - write_with_exist_flag( - bit_array, - raw_command_executor_agent_entity_id, - self.SIZE_POLICE_FORCE_ENTITY_ID, - ) - raw_command_target_entity_id = ( - self._command_target_entity_id.get_value() - if self._command_target_entity_id is not None - else None - ) - write_with_exist_flag( - bit_array, raw_command_target_entity_id, self.SIZE_TARGET_ENTITY_ID - ) - write_with_exist_flag(bit_array, self._execute_action, self.SIZE_ACTION) - - return bit_array - - @classmethod - def from_bits( - cls, - bit_array: bitarray, - is_wireless_message: bool, - sender_entity_id: EntityID, - ) -> CommandPolice: - std_message = super().from_bits( - bit_array, is_wireless_message, sender_entity_id - ) - raw_command_executor_agent_entity_id = read_with_exist_flag( - bit_array, cls.SIZE_POLICE_FORCE_ENTITY_ID - ) - command_executor_agent_id = ( - EntityID(raw_command_executor_agent_entity_id) - if raw_command_executor_agent_entity_id is not None - else None - ) - raw_command_target_entity_id = read_with_exist_flag( - bit_array, cls.SIZE_TARGET_ENTITY_ID - ) - command_target_id = ( - EntityID(raw_command_target_entity_id) - if raw_command_target_entity_id is not None - else None - ) - execute_action = read_with_exist_flag(bit_array, cls.SIZE_ACTION) - return cls( - is_wireless_message, - command_executor_agent_id or EntityID(-1), - sender_entity_id, - execute_action if execute_action is not None else -1, - std_message.get_priority(), - command_target_id, - ) - - def __hash__(self) -> int: - h = super().__hash__() - return hash( - ( - h, - self._command_executor_agent_entity_id, - self._command_target_entity_id, - self._execute_action, - ) - ) - - def __str__(self) -> str: - return f"CommandPolice(executor={self._command_executor_agent_entity_id}, target={self._command_target_entity_id}, action={self._execute_action})" + ACTION_REST: int = 0 + ACTION_MOVE: int = 1 + ACTION_CLEAR: int = 2 + ACTION_AUTONOMY: int = 3 + + SIZE_POLICE_FORCE_ENTITY_ID: int = 32 + SIZE_TARGET_ENTITY_ID: int = 32 + SIZE_ACTION: int = 4 + + def __init__( + self, + is_wireless_message: bool, + command_executor_agent_entity_id: EntityID, + sender_entity_id: EntityID, + execute_action: int, + priority: StandardMessagePriority, + command_target_entity_id: Optional[EntityID] = None, + ): + super().__init__(is_wireless_message, priority, sender_entity_id) + self._command_executor_agent_entity_id: Optional[EntityID] = ( + command_executor_agent_entity_id + ) + self._command_target_entity_id: Optional[EntityID] = command_target_entity_id + self._is_bloadcast: bool = command_target_entity_id is None + self._execute_action: Optional[int] = execute_action + + def get_command_executor_agent_entity_id(self) -> Optional[EntityID]: + return self._command_executor_agent_entity_id + + def get_command_target_entity_id(self) -> Optional[EntityID]: + return self._command_target_entity_id + + def get_execute_action(self) -> Optional[int]: + return self._execute_action + + def is_broadcast(self) -> bool: + return self._is_bloadcast + + def get_bit_size(self) -> int: + return self.to_bits().__len__() + + def to_bits(self) -> bitarray: + bit_array = super().to_bits() + raw_command_executor_agent_entity_id = ( + self._command_executor_agent_entity_id.get_value() + if self._command_executor_agent_entity_id is not None + else None + ) + write_with_exist_flag( + bit_array, + raw_command_executor_agent_entity_id, + self.SIZE_POLICE_FORCE_ENTITY_ID, + ) + raw_command_target_entity_id = ( + self._command_target_entity_id.get_value() + if self._command_target_entity_id is not None + else None + ) + write_with_exist_flag( + bit_array, raw_command_target_entity_id, self.SIZE_TARGET_ENTITY_ID + ) + write_with_exist_flag(bit_array, self._execute_action, self.SIZE_ACTION) + + return bit_array + + @classmethod + def from_bits( + cls, + bit_array: bitarray, + is_wireless_message: bool, + sender_entity_id: EntityID, + ) -> CommandPolice: + std_message = super().from_bits(bit_array, is_wireless_message, sender_entity_id) + raw_command_executor_agent_entity_id = read_with_exist_flag( + bit_array, cls.SIZE_POLICE_FORCE_ENTITY_ID + ) + command_executor_agent_id = ( + EntityID(raw_command_executor_agent_entity_id) + if raw_command_executor_agent_entity_id is not None + else None + ) + raw_command_target_entity_id = read_with_exist_flag( + bit_array, cls.SIZE_TARGET_ENTITY_ID + ) + command_target_id = ( + EntityID(raw_command_target_entity_id) + if raw_command_target_entity_id is not None + else None + ) + execute_action = read_with_exist_flag(bit_array, cls.SIZE_ACTION) + return cls( + is_wireless_message, + command_executor_agent_id or EntityID(-1), + sender_entity_id, + execute_action if execute_action is not None else -1, + std_message.get_priority(), + command_target_id, + ) + + def __hash__(self) -> int: + h = super().__hash__() + return hash( + ( + h, + self._command_executor_agent_entity_id, + self._command_target_entity_id, + self._execute_action, + ) + ) + + def __str__(self) -> str: + return f"CommandPolice(executor={self._command_executor_agent_entity_id}, target={self._command_target_entity_id}, action={self._execute_action})" diff --git a/src/adf_core_python/core/agent/communication/standard/bundle/centralized/command_scout.py b/src/adf_core_python/core/agent/communication/standard/bundle/centralized/command_scout.py index 4d82478..9c2ae38 100644 --- a/src/adf_core_python/core/agent/communication/standard/bundle/centralized/command_scout.py +++ b/src/adf_core_python/core/agent/communication/standard/bundle/centralized/command_scout.py @@ -6,124 +6,122 @@ from rcrscore.entities import EntityID from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( - StandardMessage, + StandardMessage, ) from adf_core_python.core.agent.communication.standard.bundle.standard_message_priority import ( - StandardMessagePriority, + StandardMessagePriority, ) from adf_core_python.core.agent.communication.standard.utility.bitarray_with_exits_flag import ( - read_with_exist_flag, - write_with_exist_flag, + read_with_exist_flag, + write_with_exist_flag, ) class CommandScout(StandardMessage): - SIZE_AGENT_ENTITY_ID: int = 32 - SIZE_TARGET_ENTITY_ID: int = 32 - SIZE_SCOUT_RANGE: int = 32 - - def __init__( - self, - is_wireless_message: bool, - command_executor_agent_entity_id: EntityID, - sender_entity_id: EntityID, - scout_range: int, - priority: StandardMessagePriority, - command_target_entity_id: Optional[EntityID] = None, - ): - super().__init__(is_wireless_message, priority, sender_entity_id) - self._command_executor_agent_entity_id: Optional[EntityID] = ( - command_executor_agent_entity_id - ) - self._command_target_entity_id: Optional[EntityID] = command_target_entity_id - self._is_bloadcast: bool = command_target_entity_id is None - self._scout_range: Optional[int] = scout_range - - def get_command_executor_agent_entity_id(self) -> Optional[EntityID]: - return self._command_executor_agent_entity_id - - def get_command_target_entity_id(self) -> Optional[EntityID]: - return self._command_target_entity_id - - def get_scout_range(self) -> Optional[int]: - return self._scout_range - - def is_broadcast(self) -> bool: - return self._is_bloadcast - - def get_bit_size(self) -> int: - return self.to_bits().__len__() - - def to_bits(self) -> bitarray: - bit_array = super().to_bits() - raw_command_executor_agent_entity_id = ( - self._command_executor_agent_entity_id.get_value() - if self._command_executor_agent_entity_id is not None - else None - ) - write_with_exist_flag( - bit_array, - raw_command_executor_agent_entity_id, - self.SIZE_AGENT_ENTITY_ID, - ) - raw_command_target_entity_id = ( - self._command_target_entity_id.get_value() - if self._command_target_entity_id is not None - else None - ) - write_with_exist_flag( - bit_array, raw_command_target_entity_id, self.SIZE_TARGET_ENTITY_ID - ) - write_with_exist_flag(bit_array, self._scout_range, self.SIZE_SCOUT_RANGE) - - return bit_array - - @classmethod - def from_bits( - cls, - bit_array: bitarray, - is_wireless_message: bool, - sender_entity_id: EntityID, - ) -> CommandScout: - std_message = super().from_bits( - bit_array, is_wireless_message, sender_entity_id - ) - raw_command_executor_agent_entity_id = read_with_exist_flag( - bit_array, cls.SIZE_AGENT_ENTITY_ID - ) - command_executor_agent_id = ( - EntityID(raw_command_executor_agent_entity_id) - if raw_command_executor_agent_entity_id is not None - else None - ) - raw_command_target_entity_id = read_with_exist_flag( - bit_array, cls.SIZE_TARGET_ENTITY_ID - ) - command_target_id = ( - EntityID(raw_command_target_entity_id) - if raw_command_target_entity_id is not None - else None - ) - scout_range = read_with_exist_flag(bit_array, cls.SIZE_SCOUT_RANGE) - return cls( - is_wireless_message, - command_executor_agent_id or EntityID(-1), - sender_entity_id, - scout_range if scout_range is not None else -1, - std_message.get_priority(), - command_target_id, - ) - - def __hash__(self) -> int: - h = super().__hash__() - return hash( - ( - h, - self._command_executor_agent_entity_id, - self._command_target_entity_id, - self._scout_range, - ) - ) - - def __str__(self) -> str: - return f"CommandScout(executor={self._command_executor_agent_entity_id}, target={self._command_target_entity_id}, scout_range={self._scout_range})" + SIZE_AGENT_ENTITY_ID: int = 32 + SIZE_TARGET_ENTITY_ID: int = 32 + SIZE_SCOUT_RANGE: int = 32 + + def __init__( + self, + is_wireless_message: bool, + command_executor_agent_entity_id: EntityID, + sender_entity_id: EntityID, + scout_range: int, + priority: StandardMessagePriority, + command_target_entity_id: Optional[EntityID] = None, + ): + super().__init__(is_wireless_message, priority, sender_entity_id) + self._command_executor_agent_entity_id: Optional[EntityID] = ( + command_executor_agent_entity_id + ) + self._command_target_entity_id: Optional[EntityID] = command_target_entity_id + self._is_bloadcast: bool = command_target_entity_id is None + self._scout_range: Optional[int] = scout_range + + def get_command_executor_agent_entity_id(self) -> Optional[EntityID]: + return self._command_executor_agent_entity_id + + def get_command_target_entity_id(self) -> Optional[EntityID]: + return self._command_target_entity_id + + def get_scout_range(self) -> Optional[int]: + return self._scout_range + + def is_broadcast(self) -> bool: + return self._is_bloadcast + + def get_bit_size(self) -> int: + return self.to_bits().__len__() + + def to_bits(self) -> bitarray: + bit_array = super().to_bits() + raw_command_executor_agent_entity_id = ( + self._command_executor_agent_entity_id.get_value() + if self._command_executor_agent_entity_id is not None + else None + ) + write_with_exist_flag( + bit_array, + raw_command_executor_agent_entity_id, + self.SIZE_AGENT_ENTITY_ID, + ) + raw_command_target_entity_id = ( + self._command_target_entity_id.get_value() + if self._command_target_entity_id is not None + else None + ) + write_with_exist_flag( + bit_array, raw_command_target_entity_id, self.SIZE_TARGET_ENTITY_ID + ) + write_with_exist_flag(bit_array, self._scout_range, self.SIZE_SCOUT_RANGE) + + return bit_array + + @classmethod + def from_bits( + cls, + bit_array: bitarray, + is_wireless_message: bool, + sender_entity_id: EntityID, + ) -> CommandScout: + std_message = super().from_bits(bit_array, is_wireless_message, sender_entity_id) + raw_command_executor_agent_entity_id = read_with_exist_flag( + bit_array, cls.SIZE_AGENT_ENTITY_ID + ) + command_executor_agent_id = ( + EntityID(raw_command_executor_agent_entity_id) + if raw_command_executor_agent_entity_id is not None + else None + ) + raw_command_target_entity_id = read_with_exist_flag( + bit_array, cls.SIZE_TARGET_ENTITY_ID + ) + command_target_id = ( + EntityID(raw_command_target_entity_id) + if raw_command_target_entity_id is not None + else None + ) + scout_range = read_with_exist_flag(bit_array, cls.SIZE_SCOUT_RANGE) + return cls( + is_wireless_message, + command_executor_agent_id or EntityID(-1), + sender_entity_id, + scout_range if scout_range is not None else -1, + std_message.get_priority(), + command_target_id, + ) + + def __hash__(self) -> int: + h = super().__hash__() + return hash( + ( + h, + self._command_executor_agent_entity_id, + self._command_target_entity_id, + self._scout_range, + ) + ) + + def __str__(self) -> str: + return f"CommandScout(executor={self._command_executor_agent_entity_id}, target={self._command_target_entity_id}, scout_range={self._scout_range})" diff --git a/src/adf_core_python/core/agent/communication/standard/bundle/centralized/message_report.py b/src/adf_core_python/core/agent/communication/standard/bundle/centralized/message_report.py index 99cf589..46d2283 100644 --- a/src/adf_core_python/core/agent/communication/standard/bundle/centralized/message_report.py +++ b/src/adf_core_python/core/agent/communication/standard/bundle/centralized/message_report.py @@ -4,85 +4,83 @@ from rcrscore.entities import EntityID from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( - StandardMessage, + StandardMessage, ) from adf_core_python.core.agent.communication.standard.bundle.standard_message_priority import ( - StandardMessagePriority, + StandardMessagePriority, ) from adf_core_python.core.agent.communication.standard.utility.bitarray_with_exits_flag import ( - read_with_exist_flag, - write_with_exist_flag, + read_with_exist_flag, + write_with_exist_flag, ) class MessageReport(StandardMessage): - SIZE_DONE: int = 1 - SIZE_BLOADCAST: int = 1 + SIZE_DONE: int = 1 + SIZE_BLOADCAST: int = 1 - def __init__( - self, - is_wireless_message: bool, - is_done: bool, - is_bloadcast: bool, - sender_entity_id: EntityID, - priority: StandardMessagePriority, - ): - super().__init__(is_wireless_message, priority, sender_entity_id) - self._is_done: bool = is_done - self._is_bloadcast: bool = is_bloadcast + def __init__( + self, + is_wireless_message: bool, + is_done: bool, + is_bloadcast: bool, + sender_entity_id: EntityID, + priority: StandardMessagePriority, + ): + super().__init__(is_wireless_message, priority, sender_entity_id) + self._is_done: bool = is_done + self._is_bloadcast: bool = is_bloadcast - def is_done(self) -> bool: - return self._is_done + def is_done(self) -> bool: + return self._is_done - def is_broadcast(self) -> bool: - return self._is_bloadcast + def is_broadcast(self) -> bool: + return self._is_bloadcast - def get_bit_size(self) -> int: - return self.to_bits().__len__() + def get_bit_size(self) -> int: + return self.to_bits().__len__() - def to_bits(self) -> bitarray: - bit_array = super().to_bits() - write_with_exist_flag( - bit_array, - self._is_done, - self.SIZE_DONE, - ) - write_with_exist_flag( - bit_array, - self._is_bloadcast, - self.SIZE_BLOADCAST, - ) - return bit_array + def to_bits(self) -> bitarray: + bit_array = super().to_bits() + write_with_exist_flag( + bit_array, + self._is_done, + self.SIZE_DONE, + ) + write_with_exist_flag( + bit_array, + self._is_bloadcast, + self.SIZE_BLOADCAST, + ) + return bit_array - @classmethod - def from_bits( - cls, - bit_array: bitarray, - is_wireless_message: bool, - sender_entity_id: EntityID, - ) -> MessageReport: - std_message = super().from_bits( - bit_array, is_wireless_message, sender_entity_id - ) - is_done = read_with_exist_flag(bit_array, cls.SIZE_DONE) == 1 - is_bloadcast = read_with_exist_flag(bit_array, cls.SIZE_BLOADCAST) == 1 - return cls( - is_wireless_message, - is_done, - is_bloadcast, - std_message.get_sender_entity_id(), - std_message.get_priority(), - ) + @classmethod + def from_bits( + cls, + bit_array: bitarray, + is_wireless_message: bool, + sender_entity_id: EntityID, + ) -> MessageReport: + std_message = super().from_bits(bit_array, is_wireless_message, sender_entity_id) + is_done = read_with_exist_flag(bit_array, cls.SIZE_DONE) == 1 + is_bloadcast = read_with_exist_flag(bit_array, cls.SIZE_BLOADCAST) == 1 + return cls( + is_wireless_message, + is_done, + is_bloadcast, + std_message.get_sender_entity_id(), + std_message.get_priority(), + ) - def __hash__(self) -> int: - h = super().__hash__() - return hash( - ( - h, - self._is_done, - self._is_bloadcast, - ) - ) + def __hash__(self) -> int: + h = super().__hash__() + return hash( + ( + h, + self._is_done, + self._is_bloadcast, + ) + ) - def __str__(self) -> str: - return f"CommandReport(done={self._is_done}, broadcast={self._is_bloadcast})" + def __str__(self) -> str: + return f"CommandReport(done={self._is_done}, broadcast={self._is_bloadcast})" diff --git a/src/adf_core_python/core/agent/communication/standard/bundle/information/message_ambulance_team.py b/src/adf_core_python/core/agent/communication/standard/bundle/information/message_ambulance_team.py index 2fbe0ea..b649c83 100644 --- a/src/adf_core_python/core/agent/communication/standard/bundle/information/message_ambulance_team.py +++ b/src/adf_core_python/core/agent/communication/standard/bundle/information/message_ambulance_team.py @@ -6,182 +6,176 @@ from rcrscore.entities import AmbulanceTeam, EntityID from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( - StandardMessage, + StandardMessage, ) from adf_core_python.core.agent.communication.standard.bundle.standard_message_priority import ( - StandardMessagePriority, + StandardMessagePriority, ) from adf_core_python.core.agent.communication.standard.utility.bitarray_with_exits_flag import ( - read_with_exist_flag, - write_with_exist_flag, + read_with_exist_flag, + write_with_exist_flag, ) class MessageAmbulanceTeam(StandardMessage): - ACTION_REST: int = 0 - ACTION_MOVE: int = 1 - ACTION_RESCUE: int = 2 - ACTION_LOAD: int = 3 - ACTION_UNLOAD: int = 4 - - SIZE_AMBULANCE_TEAM_ENTITY_ID: int = 32 - SIZE_AMBULANCE_TEAM_HP: int = 14 - SIZE_AMBULANCE_TEAM_BURIEDNESS: int = 13 - SIZE_AMBULANCE_TEAM_DAMAGE: int = 14 - SIZE_AMBULANCE_TEAM_POSITION: int = 32 - SIZE_TARGET_ENTITY_ID: int = 32 - SIZE_ACTION: int = 4 - - def __init__( - self, - is_wireless_message: bool, - ambulance_team: AmbulanceTeam, - action: int, - target_entity_id: EntityID, - priority: StandardMessagePriority, - sender_entity_id: EntityID, - ttl: Optional[int] = None, - ): - super().__init__(is_wireless_message, priority, sender_entity_id, ttl) - self._ambulance_team_entity_id: Optional[EntityID] = ( - ambulance_team.get_entity_id() - ) - self._ambulance_team_hp: Optional[int] = ambulance_team.get_hp() or None - self._ambulance_team_buriedness: Optional[int] = ( - ambulance_team.get_buriedness() or None - ) - self._ambulance_team_damage: Optional[int] = ambulance_team.get_damage() or None - self._ambulance_team_position: Optional[EntityID] = ( - ambulance_team.get_position() or None - ) - self._target_entity_id: Optional[EntityID] = target_entity_id - self._action: Optional[int] = action - - def get_ambulance_team_entity_id(self) -> Optional[EntityID]: - return self._ambulance_team_entity_id - - def get_ambulance_team_hp(self) -> Optional[int]: - return self._ambulance_team_hp - - def get_ambulance_team_buriedness(self) -> Optional[int]: - return self._ambulance_team_buriedness - - def get_ambulance_team_damage(self) -> Optional[int]: - return self._ambulance_team_damage - - def get_ambulance_team_position(self) -> Optional[EntityID]: - return self._ambulance_team_position - - def get_target_entity_id(self) -> Optional[EntityID]: - return self._target_entity_id - - def get_action(self) -> Optional[int]: - return self._action - - def get_bit_size(self) -> int: - return self.to_bits().__len__() - - def to_bits(self) -> bitarray: - bit_array = super().to_bits() - write_with_exist_flag( - bit_array, - self._ambulance_team_entity_id.get_value() - if self._ambulance_team_entity_id - else None, - self.SIZE_AMBULANCE_TEAM_ENTITY_ID, - ) - write_with_exist_flag( - bit_array, self._ambulance_team_hp, self.SIZE_AMBULANCE_TEAM_HP - ) - write_with_exist_flag( - bit_array, - self._ambulance_team_buriedness, - self.SIZE_AMBULANCE_TEAM_BURIEDNESS, - ) - write_with_exist_flag( - bit_array, self._ambulance_team_damage, self.SIZE_AMBULANCE_TEAM_DAMAGE - ) - write_with_exist_flag( - bit_array, - self._ambulance_team_position.get_value() - if self._ambulance_team_position - else None, - self.SIZE_AMBULANCE_TEAM_POSITION, - ) - write_with_exist_flag( - bit_array, - self._target_entity_id.get_value() if self._target_entity_id else None, - self.SIZE_TARGET_ENTITY_ID, - ) - write_with_exist_flag(bit_array, self._action, self.SIZE_ACTION) - return bit_array - - @classmethod - def from_bits( - cls, - bit_array: bitarray, - is_wireless_message: bool, - sender_entity_id: EntityID, - ) -> MessageAmbulanceTeam: - std_message = super().from_bits( - bit_array, is_wireless_message, sender_entity_id - ) - ambulance_team_id = read_with_exist_flag( - bit_array, cls.SIZE_AMBULANCE_TEAM_ENTITY_ID - ) - ambulance_team_hp = read_with_exist_flag(bit_array, cls.SIZE_AMBULANCE_TEAM_HP) - ambulance_team_buriedness = read_with_exist_flag( - bit_array, cls.SIZE_AMBULANCE_TEAM_BURIEDNESS - ) - ambulance_team_damage = read_with_exist_flag( - bit_array, cls.SIZE_AMBULANCE_TEAM_DAMAGE - ) - raw_ambulance_team_position = read_with_exist_flag( - bit_array, cls.SIZE_AMBULANCE_TEAM_POSITION - ) - ambulance_team_position = ( - EntityID(raw_ambulance_team_position) - if raw_ambulance_team_position is not None - else None - ) - raw_target_entity_id = read_with_exist_flag( - bit_array, cls.SIZE_TARGET_ENTITY_ID - ) - target_entity_id = ( - EntityID(raw_target_entity_id) - if raw_target_entity_id is not None - else EntityID(-1) - ) - action = read_with_exist_flag(bit_array, cls.SIZE_ACTION) - ambulance_team = AmbulanceTeam(ambulance_team_id or -1) - ambulance_team.set_hp(ambulance_team_hp) - ambulance_team.set_buriedness(ambulance_team_buriedness) - ambulance_team.set_damage(ambulance_team_damage) - ambulance_team.set_position(ambulance_team_position) - return MessageAmbulanceTeam( - False, - ambulance_team, - action if action is not None else -1, - target_entity_id, - StandardMessagePriority.NORMAL, - sender_entity_id, - std_message.get_ttl(), - ) - - def __hash__(self) -> int: - h = super().__hash__() - return hash( - ( - h, - self._ambulance_team_entity_id, - self._ambulance_team_hp, - self._ambulance_team_buriedness, - self._ambulance_team_damage, - self._ambulance_team_position, - self._target_entity_id, - self._action, - ) - ) - - def __str__(self) -> str: - return f"MessageAmbulanceTeam(ambulance_team_entity_id={self._ambulance_team_entity_id}, ambulance_team_hp={self._ambulance_team_hp}, ambulance_team_buriedness={self._ambulance_team_buriedness}, ambulance_team_damage={self._ambulance_team_damage}, ambulance_team_position={self._ambulance_team_position}, target_entity_id={self._target_entity_id}, action={self._action}, ttl={self._ttl})" + ACTION_REST: int = 0 + ACTION_MOVE: int = 1 + ACTION_RESCUE: int = 2 + ACTION_LOAD: int = 3 + ACTION_UNLOAD: int = 4 + + SIZE_AMBULANCE_TEAM_ENTITY_ID: int = 32 + SIZE_AMBULANCE_TEAM_HP: int = 14 + SIZE_AMBULANCE_TEAM_BURIEDNESS: int = 13 + SIZE_AMBULANCE_TEAM_DAMAGE: int = 14 + SIZE_AMBULANCE_TEAM_POSITION: int = 32 + SIZE_TARGET_ENTITY_ID: int = 32 + SIZE_ACTION: int = 4 + + def __init__( + self, + is_wireless_message: bool, + ambulance_team: AmbulanceTeam, + action: int, + target_entity_id: EntityID, + priority: StandardMessagePriority, + sender_entity_id: EntityID, + ttl: Optional[int] = None, + ): + super().__init__(is_wireless_message, priority, sender_entity_id, ttl) + self._ambulance_team_entity_id: Optional[EntityID] = ambulance_team.get_entity_id() + self._ambulance_team_hp: Optional[int] = ambulance_team.get_hp() or None + self._ambulance_team_buriedness: Optional[int] = ( + ambulance_team.get_buriedness() or None + ) + self._ambulance_team_damage: Optional[int] = ambulance_team.get_damage() or None + self._ambulance_team_position: Optional[EntityID] = ( + ambulance_team.get_position() or None + ) + self._target_entity_id: Optional[EntityID] = target_entity_id + self._action: Optional[int] = action + + def get_ambulance_team_entity_id(self) -> Optional[EntityID]: + return self._ambulance_team_entity_id + + def get_ambulance_team_hp(self) -> Optional[int]: + return self._ambulance_team_hp + + def get_ambulance_team_buriedness(self) -> Optional[int]: + return self._ambulance_team_buriedness + + def get_ambulance_team_damage(self) -> Optional[int]: + return self._ambulance_team_damage + + def get_ambulance_team_position(self) -> Optional[EntityID]: + return self._ambulance_team_position + + def get_target_entity_id(self) -> Optional[EntityID]: + return self._target_entity_id + + def get_action(self) -> Optional[int]: + return self._action + + def get_bit_size(self) -> int: + return self.to_bits().__len__() + + def to_bits(self) -> bitarray: + bit_array = super().to_bits() + write_with_exist_flag( + bit_array, + self._ambulance_team_entity_id.get_value() + if self._ambulance_team_entity_id + else None, + self.SIZE_AMBULANCE_TEAM_ENTITY_ID, + ) + write_with_exist_flag( + bit_array, self._ambulance_team_hp, self.SIZE_AMBULANCE_TEAM_HP + ) + write_with_exist_flag( + bit_array, + self._ambulance_team_buriedness, + self.SIZE_AMBULANCE_TEAM_BURIEDNESS, + ) + write_with_exist_flag( + bit_array, self._ambulance_team_damage, self.SIZE_AMBULANCE_TEAM_DAMAGE + ) + write_with_exist_flag( + bit_array, + self._ambulance_team_position.get_value() + if self._ambulance_team_position + else None, + self.SIZE_AMBULANCE_TEAM_POSITION, + ) + write_with_exist_flag( + bit_array, + self._target_entity_id.get_value() if self._target_entity_id else None, + self.SIZE_TARGET_ENTITY_ID, + ) + write_with_exist_flag(bit_array, self._action, self.SIZE_ACTION) + return bit_array + + @classmethod + def from_bits( + cls, + bit_array: bitarray, + is_wireless_message: bool, + sender_entity_id: EntityID, + ) -> MessageAmbulanceTeam: + std_message = super().from_bits(bit_array, is_wireless_message, sender_entity_id) + ambulance_team_id = read_with_exist_flag( + bit_array, cls.SIZE_AMBULANCE_TEAM_ENTITY_ID + ) + ambulance_team_hp = read_with_exist_flag(bit_array, cls.SIZE_AMBULANCE_TEAM_HP) + ambulance_team_buriedness = read_with_exist_flag( + bit_array, cls.SIZE_AMBULANCE_TEAM_BURIEDNESS + ) + ambulance_team_damage = read_with_exist_flag( + bit_array, cls.SIZE_AMBULANCE_TEAM_DAMAGE + ) + raw_ambulance_team_position = read_with_exist_flag( + bit_array, cls.SIZE_AMBULANCE_TEAM_POSITION + ) + ambulance_team_position = ( + EntityID(raw_ambulance_team_position) + if raw_ambulance_team_position is not None + else None + ) + raw_target_entity_id = read_with_exist_flag(bit_array, cls.SIZE_TARGET_ENTITY_ID) + target_entity_id = ( + EntityID(raw_target_entity_id) + if raw_target_entity_id is not None + else EntityID(-1) + ) + action = read_with_exist_flag(bit_array, cls.SIZE_ACTION) + ambulance_team = AmbulanceTeam(ambulance_team_id or -1) + ambulance_team.set_hp(ambulance_team_hp) + ambulance_team.set_buriedness(ambulance_team_buriedness) + ambulance_team.set_damage(ambulance_team_damage) + ambulance_team.set_position(ambulance_team_position) + return MessageAmbulanceTeam( + False, + ambulance_team, + action if action is not None else -1, + target_entity_id, + StandardMessagePriority.NORMAL, + sender_entity_id, + std_message.get_ttl(), + ) + + def __hash__(self) -> int: + h = super().__hash__() + return hash( + ( + h, + self._ambulance_team_entity_id, + self._ambulance_team_hp, + self._ambulance_team_buriedness, + self._ambulance_team_damage, + self._ambulance_team_position, + self._target_entity_id, + self._action, + ) + ) + + def __str__(self) -> str: + return f"MessageAmbulanceTeam(ambulance_team_entity_id={self._ambulance_team_entity_id}, ambulance_team_hp={self._ambulance_team_hp}, ambulance_team_buriedness={self._ambulance_team_buriedness}, ambulance_team_damage={self._ambulance_team_damage}, ambulance_team_position={self._ambulance_team_position}, target_entity_id={self._target_entity_id}, action={self._action}, ttl={self._ttl})" diff --git a/src/adf_core_python/core/agent/communication/standard/bundle/information/message_building.py b/src/adf_core_python/core/agent/communication/standard/bundle/information/message_building.py index 586f836..8a909a5 100644 --- a/src/adf_core_python/core/agent/communication/standard/bundle/information/message_building.py +++ b/src/adf_core_python/core/agent/communication/standard/bundle/information/message_building.py @@ -7,116 +7,110 @@ from rcrscore.entities.building import Building from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( - StandardMessage, + StandardMessage, ) from adf_core_python.core.agent.communication.standard.bundle.standard_message_priority import ( - StandardMessagePriority, + StandardMessagePriority, ) from adf_core_python.core.agent.communication.standard.utility.bitarray_with_exits_flag import ( - read_with_exist_flag, - write_with_exist_flag, + read_with_exist_flag, + write_with_exist_flag, ) class MessageBuilding(StandardMessage): - SIZE_BUILDING_ENTITY_ID: int = 32 - SIZE_BUILDING_BROKENNESS: int = 32 - SIZE_BUILDING_FIREYNESS: int = 32 - SIZE_BUILDING_TEMPERATURE: int = 32 + SIZE_BUILDING_ENTITY_ID: int = 32 + SIZE_BUILDING_BROKENNESS: int = 32 + SIZE_BUILDING_FIREYNESS: int = 32 + SIZE_BUILDING_TEMPERATURE: int = 32 - def __init__( - self, - is_wireless_message: bool, - building: Building, - priority: StandardMessagePriority, - sender_entity_id: EntityID, - ttl: Optional[int] = None, - ): - super().__init__(is_wireless_message, priority, sender_entity_id, ttl) - self._building_entity_id: Optional[EntityID] = building.get_entity_id() - self._building_brokenness: Optional[int] = building.get_brokenness() or None - self._building_fireyness: Optional[int] = building.get_fieryness() or None - self._building_temperature: Optional[int] = building.get_temperature() or None + def __init__( + self, + is_wireless_message: bool, + building: Building, + priority: StandardMessagePriority, + sender_entity_id: EntityID, + ttl: Optional[int] = None, + ): + super().__init__(is_wireless_message, priority, sender_entity_id, ttl) + self._building_entity_id: Optional[EntityID] = building.get_entity_id() + self._building_brokenness: Optional[int] = building.get_brokenness() or None + self._building_fireyness: Optional[int] = building.get_fieryness() or None + self._building_temperature: Optional[int] = building.get_temperature() or None - def get_building_entity_id(self) -> Optional[EntityID]: - return self._building_entity_id + def get_building_entity_id(self) -> Optional[EntityID]: + return self._building_entity_id - def get_building_brokenness(self) -> Optional[int]: - return self._building_brokenness + def get_building_brokenness(self) -> Optional[int]: + return self._building_brokenness - def get_building_fireyness(self) -> Optional[int]: - return self._building_fireyness + def get_building_fireyness(self) -> Optional[int]: + return self._building_fireyness - def get_building_temperature(self) -> Optional[int]: - return self._building_temperature + def get_building_temperature(self) -> Optional[int]: + return self._building_temperature - def get_bit_size(self) -> int: - return self.to_bits().__len__() + def get_bit_size(self) -> int: + return self.to_bits().__len__() - def to_bits(self) -> bitarray: - bit_array = super().to_bits() - write_with_exist_flag( - bit_array, - self._building_entity_id.get_value() if self._building_entity_id else None, - self.SIZE_BUILDING_ENTITY_ID, - ) - write_with_exist_flag( - bit_array, - self._building_brokenness, - self.SIZE_BUILDING_BROKENNESS, - ) - write_with_exist_flag( - bit_array, - self._building_fireyness, - self.SIZE_BUILDING_FIREYNESS, - ) - write_with_exist_flag( - bit_array, - self._building_temperature, - self.SIZE_BUILDING_TEMPERATURE, - ) - return bit_array + def to_bits(self) -> bitarray: + bit_array = super().to_bits() + write_with_exist_flag( + bit_array, + self._building_entity_id.get_value() if self._building_entity_id else None, + self.SIZE_BUILDING_ENTITY_ID, + ) + write_with_exist_flag( + bit_array, + self._building_brokenness, + self.SIZE_BUILDING_BROKENNESS, + ) + write_with_exist_flag( + bit_array, + self._building_fireyness, + self.SIZE_BUILDING_FIREYNESS, + ) + write_with_exist_flag( + bit_array, + self._building_temperature, + self.SIZE_BUILDING_TEMPERATURE, + ) + return bit_array - @classmethod - def from_bits( - cls, bit_array: bitarray, is_wireless_message: bool, sender_entity_id: EntityID - ) -> MessageBuilding: - std_message = super().from_bits( - bit_array, is_wireless_message, sender_entity_id - ) - building_id = read_with_exist_flag(bit_array, cls.SIZE_BUILDING_ENTITY_ID) - building_brokenness = read_with_exist_flag( - bit_array, cls.SIZE_BUILDING_BROKENNESS - ) - building_fireyness = read_with_exist_flag( - bit_array, cls.SIZE_BUILDING_FIREYNESS - ) - building_temperature = read_with_exist_flag( - bit_array, cls.SIZE_BUILDING_TEMPERATURE - ) - building = Building(building_id or -1) - building.set_brokenness(building_brokenness) - building.set_fieryness(building_fireyness) - building.set_temperature(building_temperature) - return MessageBuilding( - False, - building, - StandardMessagePriority.NORMAL, - sender_entity_id, - std_message.get_ttl(), - ) + @classmethod + def from_bits( + cls, bit_array: bitarray, is_wireless_message: bool, sender_entity_id: EntityID + ) -> MessageBuilding: + std_message = super().from_bits(bit_array, is_wireless_message, sender_entity_id) + building_id = read_with_exist_flag(bit_array, cls.SIZE_BUILDING_ENTITY_ID) + building_brokenness = read_with_exist_flag(bit_array, cls.SIZE_BUILDING_BROKENNESS) + building_fireyness = read_with_exist_flag(bit_array, cls.SIZE_BUILDING_FIREYNESS) + building_temperature = read_with_exist_flag( + bit_array, cls.SIZE_BUILDING_TEMPERATURE + ) + building = Building(building_id or -1) + building.set_brokenness(building_brokenness) + building.set_fieryness(building_fireyness) + building.set_temperature(building_temperature) + return MessageBuilding( + False, + building, + StandardMessagePriority.NORMAL, + sender_entity_id, + std_message.get_ttl(), + ) - def __hash__(self) -> int: - h = super().__hash__() - return hash( - ( - h, - self._building_entity_id, - self._building_brokenness, - self._building_fireyness, - self._building_temperature, - ) - ) + def __hash__(self) -> int: + h = super().__hash__() + return hash( + ( + h, + self._building_entity_id, + self._building_brokenness, + self._building_fireyness, + self._building_temperature, + ) + ) - def __str__(self) -> str: - return f"MessageBuilding(building_entity_id={self._building_entity_id}, building_brokenness={self._building_brokenness}, building_fireyness={self._building_fireyness}, building_temperature={self._building_temperature})" + def __str__(self) -> str: + return f"MessageBuilding(building_entity_id={self._building_entity_id}, building_brokenness={self._building_brokenness}, building_fireyness={self._building_fireyness}, building_temperature={self._building_temperature})" diff --git a/src/adf_core_python/core/agent/communication/standard/bundle/information/message_civilian.py b/src/adf_core_python/core/agent/communication/standard/bundle/information/message_civilian.py index 79b4ae7..c1918c5 100644 --- a/src/adf_core_python/core/agent/communication/standard/bundle/information/message_civilian.py +++ b/src/adf_core_python/core/agent/communication/standard/bundle/information/message_civilian.py @@ -7,130 +7,124 @@ from rcrscore.entities.civilian import Civilian from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( - StandardMessage, + StandardMessage, ) from adf_core_python.core.agent.communication.standard.bundle.standard_message_priority import ( - StandardMessagePriority, + StandardMessagePriority, ) from adf_core_python.core.agent.communication.standard.utility.bitarray_with_exits_flag import ( - read_with_exist_flag, - write_with_exist_flag, + read_with_exist_flag, + write_with_exist_flag, ) class MessageCivilian(StandardMessage): - SIZE_CIVILIAN_ENTITY_ID: int = 32 - SIZE_CIVILIAN_HP: int = 14 - SIZE_CIVILIAN_BURIEDNESS: int = 13 - SIZE_CIVILIAN_DAMAGE: int = 14 - SIZE_CIVILIAN_POSITION: int = 32 - - def __init__( - self, - is_wireless_message: bool, - civilian: Civilian, - priority: StandardMessagePriority, - sender_entity_id: EntityID, - ttl: Optional[int] = None, - ): - super().__init__(is_wireless_message, priority, sender_entity_id, ttl) - self._civilian_entity_id: Optional[EntityID] = civilian.get_entity_id() - self._civilian_hp: Optional[int] = civilian.get_hp() or None - self._civilian_buriedness: Optional[int] = civilian.get_buriedness() or None - self._civilian_damage: Optional[int] = civilian.get_damage() or None - self._civilian_position: Optional[EntityID] = civilian.get_position() or None - - def get_civilian_entity_id(self) -> Optional[EntityID]: - return self._civilian_entity_id - - def get_civilian_hp(self) -> Optional[int]: - return self._civilian_hp - - def get_civilian_buriedness(self) -> Optional[int]: - return self._civilian_buriedness - - def get_civilian_damage(self) -> Optional[int]: - return self._civilian_damage - - def get_civilian_position(self) -> Optional[EntityID]: - return self._civilian_position - - def get_bit_size(self) -> int: - return self.to_bits().__len__() - - def to_bits(self) -> bitarray: - bit_array = super().to_bits() - write_with_exist_flag( - bit_array, - self._civilian_entity_id.get_value() if self._civilian_entity_id else None, - self.SIZE_CIVILIAN_ENTITY_ID, - ) - write_with_exist_flag( - bit_array, - self._civilian_hp, - self.SIZE_CIVILIAN_HP, - ) - write_with_exist_flag( - bit_array, - self._civilian_buriedness, - self.SIZE_CIVILIAN_BURIEDNESS, - ) - write_with_exist_flag( - bit_array, - self._civilian_damage, - self.SIZE_CIVILIAN_DAMAGE, - ) - write_with_exist_flag( - bit_array, - self._civilian_position.get_value() if self._civilian_position else None, - self.SIZE_CIVILIAN_POSITION, - ) - return bit_array - - @classmethod - def from_bits( - cls, bit_array: bitarray, is_wireless_message: bool, sender_entity_id: EntityID - ) -> MessageCivilian: - std_message = super().from_bits( - bit_array, is_wireless_message, sender_entity_id - ) - civilian_id = read_with_exist_flag(bit_array, cls.SIZE_CIVILIAN_ENTITY_ID) - civilian_hp = read_with_exist_flag(bit_array, cls.SIZE_CIVILIAN_HP) - civilian_buriedness = read_with_exist_flag( - bit_array, cls.SIZE_CIVILIAN_BURIEDNESS - ) - civilian_damage = read_with_exist_flag(bit_array, cls.SIZE_CIVILIAN_DAMAGE) - raw_civilian_position = read_with_exist_flag( - bit_array, cls.SIZE_CIVILIAN_POSITION - ) - civilian_position = ( - EntityID(raw_civilian_position) if raw_civilian_position else None - ) - civilian = Civilian(civilian_id or -1) - civilian.set_hp(civilian_hp) - civilian.set_buriedness(civilian_buriedness) - civilian.set_damage(civilian_damage) - civilian.set_position(civilian_position) - return MessageCivilian( - False, - civilian, - StandardMessagePriority.NORMAL, - sender_entity_id, - std_message.get_ttl(), - ) - - def __hash__(self) -> int: - h = super().__hash__() - return hash( - ( - h, - self._civilian_entity_id, - self._civilian_hp, - self._civilian_buriedness, - self._civilian_damage, - self._civilian_position, - ) - ) - - def __str__(self) -> str: - return f"MessageCivilian(civilian_entity_id={self._civilian_entity_id}, civilian_hp={self._civilian_hp}, civilian_buriedness={self._civilian_buriedness}, civilian_damage={self._civilian_damage}, civilian_position={self._civilian_position})" + SIZE_CIVILIAN_ENTITY_ID: int = 32 + SIZE_CIVILIAN_HP: int = 14 + SIZE_CIVILIAN_BURIEDNESS: int = 13 + SIZE_CIVILIAN_DAMAGE: int = 14 + SIZE_CIVILIAN_POSITION: int = 32 + + def __init__( + self, + is_wireless_message: bool, + civilian: Civilian, + priority: StandardMessagePriority, + sender_entity_id: EntityID, + ttl: Optional[int] = None, + ): + super().__init__(is_wireless_message, priority, sender_entity_id, ttl) + self._civilian_entity_id: Optional[EntityID] = civilian.get_entity_id() + self._civilian_hp: Optional[int] = civilian.get_hp() or None + self._civilian_buriedness: Optional[int] = civilian.get_buriedness() or None + self._civilian_damage: Optional[int] = civilian.get_damage() or None + self._civilian_position: Optional[EntityID] = civilian.get_position() or None + + def get_civilian_entity_id(self) -> Optional[EntityID]: + return self._civilian_entity_id + + def get_civilian_hp(self) -> Optional[int]: + return self._civilian_hp + + def get_civilian_buriedness(self) -> Optional[int]: + return self._civilian_buriedness + + def get_civilian_damage(self) -> Optional[int]: + return self._civilian_damage + + def get_civilian_position(self) -> Optional[EntityID]: + return self._civilian_position + + def get_bit_size(self) -> int: + return self.to_bits().__len__() + + def to_bits(self) -> bitarray: + bit_array = super().to_bits() + write_with_exist_flag( + bit_array, + self._civilian_entity_id.get_value() if self._civilian_entity_id else None, + self.SIZE_CIVILIAN_ENTITY_ID, + ) + write_with_exist_flag( + bit_array, + self._civilian_hp, + self.SIZE_CIVILIAN_HP, + ) + write_with_exist_flag( + bit_array, + self._civilian_buriedness, + self.SIZE_CIVILIAN_BURIEDNESS, + ) + write_with_exist_flag( + bit_array, + self._civilian_damage, + self.SIZE_CIVILIAN_DAMAGE, + ) + write_with_exist_flag( + bit_array, + self._civilian_position.get_value() if self._civilian_position else None, + self.SIZE_CIVILIAN_POSITION, + ) + return bit_array + + @classmethod + def from_bits( + cls, bit_array: bitarray, is_wireless_message: bool, sender_entity_id: EntityID + ) -> MessageCivilian: + std_message = super().from_bits(bit_array, is_wireless_message, sender_entity_id) + civilian_id = read_with_exist_flag(bit_array, cls.SIZE_CIVILIAN_ENTITY_ID) + civilian_hp = read_with_exist_flag(bit_array, cls.SIZE_CIVILIAN_HP) + civilian_buriedness = read_with_exist_flag(bit_array, cls.SIZE_CIVILIAN_BURIEDNESS) + civilian_damage = read_with_exist_flag(bit_array, cls.SIZE_CIVILIAN_DAMAGE) + raw_civilian_position = read_with_exist_flag(bit_array, cls.SIZE_CIVILIAN_POSITION) + civilian_position = ( + EntityID(raw_civilian_position) if raw_civilian_position else None + ) + civilian = Civilian(civilian_id or -1) + civilian.set_hp(civilian_hp) + civilian.set_buriedness(civilian_buriedness) + civilian.set_damage(civilian_damage) + civilian.set_position(civilian_position) + return MessageCivilian( + False, + civilian, + StandardMessagePriority.NORMAL, + sender_entity_id, + std_message.get_ttl(), + ) + + def __hash__(self) -> int: + h = super().__hash__() + return hash( + ( + h, + self._civilian_entity_id, + self._civilian_hp, + self._civilian_buriedness, + self._civilian_damage, + self._civilian_position, + ) + ) + + def __str__(self) -> str: + return f"MessageCivilian(civilian_entity_id={self._civilian_entity_id}, civilian_hp={self._civilian_hp}, civilian_buriedness={self._civilian_buriedness}, civilian_damage={self._civilian_damage}, civilian_position={self._civilian_position})" diff --git a/src/adf_core_python/core/agent/communication/standard/bundle/information/message_fire_brigade.py b/src/adf_core_python/core/agent/communication/standard/bundle/information/message_fire_brigade.py index 0f41702..1670b13 100644 --- a/src/adf_core_python/core/agent/communication/standard/bundle/information/message_fire_brigade.py +++ b/src/adf_core_python/core/agent/communication/standard/bundle/information/message_fire_brigade.py @@ -6,194 +6,180 @@ from rcrscore.entities import EntityID, FireBrigade from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( - StandardMessage, + StandardMessage, ) from adf_core_python.core.agent.communication.standard.bundle.standard_message_priority import ( - StandardMessagePriority, + StandardMessagePriority, ) from adf_core_python.core.agent.communication.standard.utility.bitarray_with_exits_flag import ( - read_with_exist_flag, - write_with_exist_flag, + read_with_exist_flag, + write_with_exist_flag, ) class MessageFireBrigade(StandardMessage): - ACTION_REST: int = 0 - ACTION_MOVE: int = 1 - ACTION_EXTINGUISH: int = 2 - ACTION_REFILL: int = 3 - ACTION_RESCUE: int = 4 - - SIZE_FIRE_BRIGADE_ENTITY_ID: int = 32 - SIZE_FIRE_BRIGADE_HP: int = 14 - SIZE_FIRE_BRIGADE_BURIEDNESS: int = 13 - SIZE_FIRE_BRIGADE_DAMAGE: int = 14 - SIZE_FIRE_BRIGADE_POSITION: int = 32 - SIZE_FIRE_BRIGADE_WATER: int = 14 - SIZE_TARGET_ENTITY_ID: int = 32 - SIZE_ACTION: int = 4 - - def __init__( - self, - is_wireless_message: bool, - fire_brigade: FireBrigade, - action: int, - target_entity_id: EntityID, - priority: StandardMessagePriority, - sender_entity_id: EntityID, - ttl: Optional[int] = None, - ): - super().__init__(is_wireless_message, priority, sender_entity_id, ttl) - self._fire_brigade_entity_id: Optional[EntityID] = fire_brigade.get_entity_id() - self._fire_brigade_hp: Optional[int] = fire_brigade.get_hp() or None - self._fire_brigade_buriedness: Optional[int] = ( - fire_brigade.get_buriedness() or None - ) - self._fire_brigade_damage: Optional[int] = fire_brigade.get_damage() or None - self._fire_brigade_position: Optional[EntityID] = ( - fire_brigade.get_position() or None - ) - self._fire_brigade_water: Optional[int] = fire_brigade.get_water() or None - self._target_entity_id: Optional[EntityID] = target_entity_id - self._action: Optional[int] = action - - def get_fire_brigade_entity_id(self) -> Optional[EntityID]: - return self._fire_brigade_entity_id - - def get_fire_brigade_hp(self) -> Optional[int]: - return self._fire_brigade_hp - - def get_fire_brigade_buriedness(self) -> Optional[int]: - return self._fire_brigade_buriedness - - def get_fire_brigade_damage(self) -> Optional[int]: - return self._fire_brigade_damage - - def get_fire_brigade_position(self) -> Optional[EntityID]: - return self._fire_brigade_position - - def get_fire_brigade_water(self) -> Optional[int]: - return self._fire_brigade_water - - def get_target_entity_id(self) -> Optional[EntityID]: - return self._target_entity_id - - def get_action(self) -> Optional[int]: - return self._action - - def get_bit_size(self) -> int: - return self.to_bits().__len__() - - def to_bits(self) -> bitarray: - bit_array = super().to_bits() - write_with_exist_flag( - bit_array, - self._fire_brigade_entity_id.get_value() - if self._fire_brigade_entity_id - else None, - self.SIZE_FIRE_BRIGADE_ENTITY_ID, - ) - write_with_exist_flag( - bit_array, - self._fire_brigade_hp, - self.SIZE_FIRE_BRIGADE_HP, - ) - write_with_exist_flag( - bit_array, - self._fire_brigade_buriedness, - self.SIZE_FIRE_BRIGADE_BURIEDNESS, - ) - write_with_exist_flag( - bit_array, - self._fire_brigade_damage, - self.SIZE_FIRE_BRIGADE_DAMAGE, - ) - write_with_exist_flag( - bit_array, - self._fire_brigade_position.get_value() - if self._fire_brigade_position - else None, - self.SIZE_FIRE_BRIGADE_POSITION, - ) - write_with_exist_flag( - bit_array, - self._fire_brigade_water, - self.SIZE_FIRE_BRIGADE_WATER, - ) - write_with_exist_flag( - bit_array, - self._target_entity_id.get_value() if self._target_entity_id else None, - self.SIZE_TARGET_ENTITY_ID, - ) - write_with_exist_flag(bit_array, self._action, self.SIZE_ACTION) - return bit_array - - @classmethod - def from_bits( - cls, bit_array: bitarray, is_wireless_message: bool, sender_entity_id: EntityID - ) -> MessageFireBrigade: - std_message = super().from_bits( - bit_array, is_wireless_message, sender_entity_id - ) - fire_brigade_id = read_with_exist_flag( - bit_array, cls.SIZE_FIRE_BRIGADE_ENTITY_ID - ) - fire_brigade_hp = read_with_exist_flag(bit_array, cls.SIZE_FIRE_BRIGADE_HP) - fire_brigade_buriedness = read_with_exist_flag( - bit_array, cls.SIZE_FIRE_BRIGADE_BURIEDNESS - ) - fire_brigade_damage = read_with_exist_flag( - bit_array, cls.SIZE_FIRE_BRIGADE_DAMAGE - ) - raw_fire_brigade_position = read_with_exist_flag( - bit_array, cls.SIZE_FIRE_BRIGADE_POSITION - ) - fire_brigade_position = ( - EntityID(raw_fire_brigade_position) if raw_fire_brigade_position else None - ) - fire_brigade_water = read_with_exist_flag( - bit_array, cls.SIZE_FIRE_BRIGADE_WATER - ) - raw_target_entity_id = read_with_exist_flag( - bit_array, cls.SIZE_TARGET_ENTITY_ID - ) - target_entity_id = ( - EntityID(raw_target_entity_id) if raw_target_entity_id else EntityID(-1) - ) - action = read_with_exist_flag(bit_array, cls.SIZE_ACTION) - fire_brigade = FireBrigade( - fire_brigade_id or -1, - ) - fire_brigade.set_hp(fire_brigade_hp) - fire_brigade.set_buriedness(fire_brigade_buriedness) - fire_brigade.set_damage(fire_brigade_damage) - fire_brigade.set_position(fire_brigade_position) - fire_brigade.set_water(fire_brigade_water) - return MessageFireBrigade( - False, - fire_brigade, - action if action is not None else -1, - target_entity_id, - StandardMessagePriority.NORMAL, - sender_entity_id, - std_message.get_ttl(), - ) - - def __hash__(self) -> int: - h = super().__hash__() - return hash( - ( - h, - self._fire_brigade_entity_id, - self._fire_brigade_hp, - self._fire_brigade_buriedness, - self._fire_brigade_damage, - self._fire_brigade_position, - self._fire_brigade_water, - self._target_entity_id, - self._action, - ) - ) - - def __str__(self) -> str: - return f"MessageFireBrigade(fire_brigade_entity_id={self._fire_brigade_entity_id}, fire_brigade_hp={self._fire_brigade_hp}, fire_brigade_buriedness={self._fire_brigade_buriedness}, fire_brigade_damage={self._fire_brigade_damage}, fire_brigade_position={self._fire_brigade_position}, fire_brigade_water={self._fire_brigade_water}, target_entity_id={self._target_entity_id}, action={self._action})" + ACTION_REST: int = 0 + ACTION_MOVE: int = 1 + ACTION_EXTINGUISH: int = 2 + ACTION_REFILL: int = 3 + ACTION_RESCUE: int = 4 + + SIZE_FIRE_BRIGADE_ENTITY_ID: int = 32 + SIZE_FIRE_BRIGADE_HP: int = 14 + SIZE_FIRE_BRIGADE_BURIEDNESS: int = 13 + SIZE_FIRE_BRIGADE_DAMAGE: int = 14 + SIZE_FIRE_BRIGADE_POSITION: int = 32 + SIZE_FIRE_BRIGADE_WATER: int = 14 + SIZE_TARGET_ENTITY_ID: int = 32 + SIZE_ACTION: int = 4 + + def __init__( + self, + is_wireless_message: bool, + fire_brigade: FireBrigade, + action: int, + target_entity_id: EntityID, + priority: StandardMessagePriority, + sender_entity_id: EntityID, + ttl: Optional[int] = None, + ): + super().__init__(is_wireless_message, priority, sender_entity_id, ttl) + self._fire_brigade_entity_id: Optional[EntityID] = fire_brigade.get_entity_id() + self._fire_brigade_hp: Optional[int] = fire_brigade.get_hp() or None + self._fire_brigade_buriedness: Optional[int] = fire_brigade.get_buriedness() or None + self._fire_brigade_damage: Optional[int] = fire_brigade.get_damage() or None + self._fire_brigade_position: Optional[EntityID] = ( + fire_brigade.get_position() or None + ) + self._fire_brigade_water: Optional[int] = fire_brigade.get_water() or None + self._target_entity_id: Optional[EntityID] = target_entity_id + self._action: Optional[int] = action + + def get_fire_brigade_entity_id(self) -> Optional[EntityID]: + return self._fire_brigade_entity_id + + def get_fire_brigade_hp(self) -> Optional[int]: + return self._fire_brigade_hp + + def get_fire_brigade_buriedness(self) -> Optional[int]: + return self._fire_brigade_buriedness + + def get_fire_brigade_damage(self) -> Optional[int]: + return self._fire_brigade_damage + + def get_fire_brigade_position(self) -> Optional[EntityID]: + return self._fire_brigade_position + + def get_fire_brigade_water(self) -> Optional[int]: + return self._fire_brigade_water + + def get_target_entity_id(self) -> Optional[EntityID]: + return self._target_entity_id + + def get_action(self) -> Optional[int]: + return self._action + + def get_bit_size(self) -> int: + return self.to_bits().__len__() + + def to_bits(self) -> bitarray: + bit_array = super().to_bits() + write_with_exist_flag( + bit_array, + self._fire_brigade_entity_id.get_value() + if self._fire_brigade_entity_id + else None, + self.SIZE_FIRE_BRIGADE_ENTITY_ID, + ) + write_with_exist_flag( + bit_array, + self._fire_brigade_hp, + self.SIZE_FIRE_BRIGADE_HP, + ) + write_with_exist_flag( + bit_array, + self._fire_brigade_buriedness, + self.SIZE_FIRE_BRIGADE_BURIEDNESS, + ) + write_with_exist_flag( + bit_array, + self._fire_brigade_damage, + self.SIZE_FIRE_BRIGADE_DAMAGE, + ) + write_with_exist_flag( + bit_array, + self._fire_brigade_position.get_value() if self._fire_brigade_position else None, + self.SIZE_FIRE_BRIGADE_POSITION, + ) + write_with_exist_flag( + bit_array, + self._fire_brigade_water, + self.SIZE_FIRE_BRIGADE_WATER, + ) + write_with_exist_flag( + bit_array, + self._target_entity_id.get_value() if self._target_entity_id else None, + self.SIZE_TARGET_ENTITY_ID, + ) + write_with_exist_flag(bit_array, self._action, self.SIZE_ACTION) + return bit_array + + @classmethod + def from_bits( + cls, bit_array: bitarray, is_wireless_message: bool, sender_entity_id: EntityID + ) -> MessageFireBrigade: + std_message = super().from_bits(bit_array, is_wireless_message, sender_entity_id) + fire_brigade_id = read_with_exist_flag(bit_array, cls.SIZE_FIRE_BRIGADE_ENTITY_ID) + fire_brigade_hp = read_with_exist_flag(bit_array, cls.SIZE_FIRE_BRIGADE_HP) + fire_brigade_buriedness = read_with_exist_flag( + bit_array, cls.SIZE_FIRE_BRIGADE_BURIEDNESS + ) + fire_brigade_damage = read_with_exist_flag(bit_array, cls.SIZE_FIRE_BRIGADE_DAMAGE) + raw_fire_brigade_position = read_with_exist_flag( + bit_array, cls.SIZE_FIRE_BRIGADE_POSITION + ) + fire_brigade_position = ( + EntityID(raw_fire_brigade_position) if raw_fire_brigade_position else None + ) + fire_brigade_water = read_with_exist_flag(bit_array, cls.SIZE_FIRE_BRIGADE_WATER) + raw_target_entity_id = read_with_exist_flag(bit_array, cls.SIZE_TARGET_ENTITY_ID) + target_entity_id = ( + EntityID(raw_target_entity_id) if raw_target_entity_id else EntityID(-1) + ) + action = read_with_exist_flag(bit_array, cls.SIZE_ACTION) + fire_brigade = FireBrigade( + fire_brigade_id or -1, + ) + fire_brigade.set_hp(fire_brigade_hp) + fire_brigade.set_buriedness(fire_brigade_buriedness) + fire_brigade.set_damage(fire_brigade_damage) + fire_brigade.set_position(fire_brigade_position) + fire_brigade.set_water(fire_brigade_water) + return MessageFireBrigade( + False, + fire_brigade, + action if action is not None else -1, + target_entity_id, + StandardMessagePriority.NORMAL, + sender_entity_id, + std_message.get_ttl(), + ) + + def __hash__(self) -> int: + h = super().__hash__() + return hash( + ( + h, + self._fire_brigade_entity_id, + self._fire_brigade_hp, + self._fire_brigade_buriedness, + self._fire_brigade_damage, + self._fire_brigade_position, + self._fire_brigade_water, + self._target_entity_id, + self._action, + ) + ) + + def __str__(self) -> str: + return f"MessageFireBrigade(fire_brigade_entity_id={self._fire_brigade_entity_id}, fire_brigade_hp={self._fire_brigade_hp}, fire_brigade_buriedness={self._fire_brigade_buriedness}, fire_brigade_damage={self._fire_brigade_damage}, fire_brigade_position={self._fire_brigade_position}, fire_brigade_water={self._fire_brigade_water}, target_entity_id={self._target_entity_id}, action={self._action})" diff --git a/src/adf_core_python/core/agent/communication/standard/bundle/information/message_police_force.py b/src/adf_core_python/core/agent/communication/standard/bundle/information/message_police_force.py index f4b72d0..d6f9682 100644 --- a/src/adf_core_python/core/agent/communication/standard/bundle/information/message_police_force.py +++ b/src/adf_core_python/core/agent/communication/standard/bundle/information/message_police_force.py @@ -6,175 +6,163 @@ from rcrscore.entities import EntityID, PoliceForce from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( - StandardMessage, + StandardMessage, ) from adf_core_python.core.agent.communication.standard.bundle.standard_message_priority import ( - StandardMessagePriority, + StandardMessagePriority, ) from adf_core_python.core.agent.communication.standard.utility.bitarray_with_exits_flag import ( - read_with_exist_flag, - write_with_exist_flag, + read_with_exist_flag, + write_with_exist_flag, ) class MessagePoliceForce(StandardMessage): - ACTION_REST: int = 0 - ACTION_MOVE: int = 1 - ACTION_CLEAR: int = 2 - - SIZE_POLICE_FORCE_ENTITY_ID: int = 32 - SIZE_POLICE_FORCE_HP: int = 14 - SIZE_POLICE_FORCE_BURIEDNESS: int = 13 - SIZE_POLICE_FORCE_DAMAGE: int = 14 - SIZE_POLICE_FORCE_POSITION: int = 32 - SIZE_TARGET_ENTITY_ID: int = 32 - SIZE_ACTION: int = 4 - - def __init__( - self, - is_wireless_message: bool, - police_force: PoliceForce, - action: int, - target_entity_id: EntityID, - priority: StandardMessagePriority, - sender_entity_id: EntityID, - ttl: Optional[int] = None, - ): - super().__init__(is_wireless_message, priority, sender_entity_id, ttl) - self._police_force_entity_id: Optional[EntityID] = police_force.get_entity_id() - self._police_force_hp: Optional[int] = police_force.get_hp() or None - self._police_force_buriedness: Optional[int] = ( - police_force.get_buriedness() or None - ) - self._police_force_damage: Optional[int] = police_force.get_damage() or None - self._police_force_position: Optional[EntityID] = ( - police_force.get_position() or None - ) - self._target_entity_id: Optional[EntityID] = target_entity_id - self._action: Optional[int] = action - - def get_police_force_entity_id(self) -> Optional[EntityID]: - return self._police_force_entity_id - - def get_police_force_hp(self) -> Optional[int]: - return self._police_force_hp - - def get_police_force_buriedness(self) -> Optional[int]: - return self._police_force_buriedness - - def get_police_force_damage(self) -> Optional[int]: - return self._police_force_damage - - def get_police_force_position(self) -> Optional[EntityID]: - return self._police_force_position - - def get_target_entity_id(self) -> Optional[EntityID]: - return self._target_entity_id - - def get_action(self) -> Optional[int]: - return self._action - - def get_bit_size(self) -> int: - return self.to_bits().__len__() - - def to_bits(self) -> bitarray: - bit_array = super().to_bits() - write_with_exist_flag( - bit_array, - self._police_force_entity_id.get_value() - if self._police_force_entity_id - else None, - self.SIZE_POLICE_FORCE_ENTITY_ID, - ) - write_with_exist_flag( - bit_array, - self._police_force_hp, - self.SIZE_POLICE_FORCE_HP, - ) - write_with_exist_flag( - bit_array, - self._police_force_buriedness, - self.SIZE_POLICE_FORCE_BURIEDNESS, - ) - write_with_exist_flag( - bit_array, - self._police_force_damage, - self.SIZE_POLICE_FORCE_DAMAGE, - ) - write_with_exist_flag( - bit_array, - self._police_force_position.get_value() - if self._police_force_position - else None, - self.SIZE_POLICE_FORCE_POSITION, - ) - write_with_exist_flag( - bit_array, - self._target_entity_id.get_value() if self._target_entity_id else None, - self.SIZE_TARGET_ENTITY_ID, - ) - write_with_exist_flag(bit_array, self._action, self.SIZE_ACTION) - return bit_array - - @classmethod - def from_bits( - cls, bit_array: bitarray, is_wireless_message: bool, sender_entity_id: EntityID - ) -> MessagePoliceForce: - std_message = super().from_bits( - bit_array, is_wireless_message, sender_entity_id - ) - police_force_id = read_with_exist_flag( - bit_array, cls.SIZE_POLICE_FORCE_ENTITY_ID - ) - police_force_hp = read_with_exist_flag(bit_array, cls.SIZE_POLICE_FORCE_HP) - police_force_buriedness = read_with_exist_flag( - bit_array, cls.SIZE_POLICE_FORCE_BURIEDNESS - ) - police_force_damage = read_with_exist_flag( - bit_array, cls.SIZE_POLICE_FORCE_DAMAGE - ) - raw_police_force_position = read_with_exist_flag( - bit_array, cls.SIZE_POLICE_FORCE_POSITION - ) - police_force_position = ( - EntityID(raw_police_force_position) if raw_police_force_position else None - ) - raw_target_entity_id = read_with_exist_flag( - bit_array, cls.SIZE_TARGET_ENTITY_ID - ) - target_entity_id = ( - EntityID(raw_target_entity_id) if raw_target_entity_id else EntityID(-1) - ) - action = read_with_exist_flag(bit_array, cls.SIZE_ACTION) - police_force = PoliceForce(police_force_id or -1) - police_force.set_hp(police_force_hp) - police_force.set_buriedness(police_force_buriedness) - police_force.set_damage(police_force_damage) - police_force.set_position(police_force_position) - return MessagePoliceForce( - False, - police_force, - action if action is not None else -1, - target_entity_id, - StandardMessagePriority.NORMAL, - sender_entity_id, - std_message.get_ttl(), - ) - - def __hash__(self) -> int: - h = super().__hash__() - return hash( - ( - h, - self._police_force_entity_id, - self._police_force_hp, - self._police_force_buriedness, - self._police_force_damage, - self._police_force_position, - self._target_entity_id, - self._action, - ) - ) - - def __str__(self) -> str: - return f"MessagePoliceForce(police_force_entity_id={self._police_force_entity_id}, police_force_hp={self._police_force_hp}, police_force_buriedness={self._police_force_buriedness}, police_force_damage={self._police_force_damage}, police_force_position={self._police_force_position}, target_entity_id={self._target_entity_id}, action={self._action})" + ACTION_REST: int = 0 + ACTION_MOVE: int = 1 + ACTION_CLEAR: int = 2 + + SIZE_POLICE_FORCE_ENTITY_ID: int = 32 + SIZE_POLICE_FORCE_HP: int = 14 + SIZE_POLICE_FORCE_BURIEDNESS: int = 13 + SIZE_POLICE_FORCE_DAMAGE: int = 14 + SIZE_POLICE_FORCE_POSITION: int = 32 + SIZE_TARGET_ENTITY_ID: int = 32 + SIZE_ACTION: int = 4 + + def __init__( + self, + is_wireless_message: bool, + police_force: PoliceForce, + action: int, + target_entity_id: EntityID, + priority: StandardMessagePriority, + sender_entity_id: EntityID, + ttl: Optional[int] = None, + ): + super().__init__(is_wireless_message, priority, sender_entity_id, ttl) + self._police_force_entity_id: Optional[EntityID] = police_force.get_entity_id() + self._police_force_hp: Optional[int] = police_force.get_hp() or None + self._police_force_buriedness: Optional[int] = police_force.get_buriedness() or None + self._police_force_damage: Optional[int] = police_force.get_damage() or None + self._police_force_position: Optional[EntityID] = ( + police_force.get_position() or None + ) + self._target_entity_id: Optional[EntityID] = target_entity_id + self._action: Optional[int] = action + + def get_police_force_entity_id(self) -> Optional[EntityID]: + return self._police_force_entity_id + + def get_police_force_hp(self) -> Optional[int]: + return self._police_force_hp + + def get_police_force_buriedness(self) -> Optional[int]: + return self._police_force_buriedness + + def get_police_force_damage(self) -> Optional[int]: + return self._police_force_damage + + def get_police_force_position(self) -> Optional[EntityID]: + return self._police_force_position + + def get_target_entity_id(self) -> Optional[EntityID]: + return self._target_entity_id + + def get_action(self) -> Optional[int]: + return self._action + + def get_bit_size(self) -> int: + return self.to_bits().__len__() + + def to_bits(self) -> bitarray: + bit_array = super().to_bits() + write_with_exist_flag( + bit_array, + self._police_force_entity_id.get_value() + if self._police_force_entity_id + else None, + self.SIZE_POLICE_FORCE_ENTITY_ID, + ) + write_with_exist_flag( + bit_array, + self._police_force_hp, + self.SIZE_POLICE_FORCE_HP, + ) + write_with_exist_flag( + bit_array, + self._police_force_buriedness, + self.SIZE_POLICE_FORCE_BURIEDNESS, + ) + write_with_exist_flag( + bit_array, + self._police_force_damage, + self.SIZE_POLICE_FORCE_DAMAGE, + ) + write_with_exist_flag( + bit_array, + self._police_force_position.get_value() if self._police_force_position else None, + self.SIZE_POLICE_FORCE_POSITION, + ) + write_with_exist_flag( + bit_array, + self._target_entity_id.get_value() if self._target_entity_id else None, + self.SIZE_TARGET_ENTITY_ID, + ) + write_with_exist_flag(bit_array, self._action, self.SIZE_ACTION) + return bit_array + + @classmethod + def from_bits( + cls, bit_array: bitarray, is_wireless_message: bool, sender_entity_id: EntityID + ) -> MessagePoliceForce: + std_message = super().from_bits(bit_array, is_wireless_message, sender_entity_id) + police_force_id = read_with_exist_flag(bit_array, cls.SIZE_POLICE_FORCE_ENTITY_ID) + police_force_hp = read_with_exist_flag(bit_array, cls.SIZE_POLICE_FORCE_HP) + police_force_buriedness = read_with_exist_flag( + bit_array, cls.SIZE_POLICE_FORCE_BURIEDNESS + ) + police_force_damage = read_with_exist_flag(bit_array, cls.SIZE_POLICE_FORCE_DAMAGE) + raw_police_force_position = read_with_exist_flag( + bit_array, cls.SIZE_POLICE_FORCE_POSITION + ) + police_force_position = ( + EntityID(raw_police_force_position) if raw_police_force_position else None + ) + raw_target_entity_id = read_with_exist_flag(bit_array, cls.SIZE_TARGET_ENTITY_ID) + target_entity_id = ( + EntityID(raw_target_entity_id) if raw_target_entity_id else EntityID(-1) + ) + action = read_with_exist_flag(bit_array, cls.SIZE_ACTION) + police_force = PoliceForce(police_force_id or -1) + police_force.set_hp(police_force_hp) + police_force.set_buriedness(police_force_buriedness) + police_force.set_damage(police_force_damage) + police_force.set_position(police_force_position) + return MessagePoliceForce( + False, + police_force, + action if action is not None else -1, + target_entity_id, + StandardMessagePriority.NORMAL, + sender_entity_id, + std_message.get_ttl(), + ) + + def __hash__(self) -> int: + h = super().__hash__() + return hash( + ( + h, + self._police_force_entity_id, + self._police_force_hp, + self._police_force_buriedness, + self._police_force_damage, + self._police_force_position, + self._target_entity_id, + self._action, + ) + ) + + def __str__(self) -> str: + return f"MessagePoliceForce(police_force_entity_id={self._police_force_entity_id}, police_force_hp={self._police_force_hp}, police_force_buriedness={self._police_force_buriedness}, police_force_damage={self._police_force_damage}, police_force_position={self._police_force_position}, target_entity_id={self._target_entity_id}, action={self._action})" diff --git a/src/adf_core_python/core/agent/communication/standard/bundle/information/message_road.py b/src/adf_core_python/core/agent/communication/standard/bundle/information/message_road.py index 747bfb5..d43b9d4 100644 --- a/src/adf_core_python/core/agent/communication/standard/bundle/information/message_road.py +++ b/src/adf_core_python/core/agent/communication/standard/bundle/information/message_road.py @@ -6,172 +6,164 @@ from rcrscore.entities import Blockade, EntityID, Road from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( - StandardMessage, + StandardMessage, ) from adf_core_python.core.agent.communication.standard.bundle.standard_message_priority import ( - StandardMessagePriority, + StandardMessagePriority, ) from adf_core_python.core.agent.communication.standard.utility.bitarray_with_exits_flag import ( - read_with_exist_flag, - write_with_exist_flag, + read_with_exist_flag, + write_with_exist_flag, ) class MessageRoad(StandardMessage): - ACTION_REST: int = 0 - ACTION_MOVE: int = 1 - ACTION_CLEAR: int = 2 - - SIZE_ROAD_ENTITY_ID: int = 32 - SIZE_ROAD_BLOCKADE_ENTITY_ID: int = 32 - SIZE_ROAD_BLOCKADE_REPAIR_COST: int = 32 - SIZE_ROAD_BLOCKADE_X: int = 32 - SIZE_ROAD_BLOCKADE_Y: int = 32 - SIZE_PASSABLE: int = 1 - - def __init__( - self, - is_wireless_message: bool, - road: Road, - is_send_blockade_location: bool, - is_passable: Optional[bool], - blockade: Optional[Blockade], - priority: StandardMessagePriority, - sender_entity_id: EntityID, - ttl: Optional[int] = None, - ): - super().__init__(is_wireless_message, priority, sender_entity_id, ttl) - self._road_entity_id: Optional[EntityID] = road.get_entity_id() - self._road_blockade_entity_id: Optional[EntityID] = None - self._road_blockade_repair_cost: Optional[int] = None - self._road_blockade_x: Optional[int] = None - self._road_blockade_y: Optional[int] = None - - if blockade: - self._road_blockade_entity_id = blockade.get_entity_id() - self._road_blockade_repair_cost = blockade.get_repair_cost() - if is_send_blockade_location: - self._road_blockade_x = blockade.get_x() or None - self._road_blockade_y = blockade.get_y() or None - - self._is_passable: Optional[bool] = is_passable - self._is_send_blockade_location: bool = is_send_blockade_location - - def get_road_entity_id(self) -> Optional[EntityID]: - return self._road_entity_id - - def get_road_blockade_entity_id(self) -> Optional[EntityID]: - return self._road_blockade_entity_id - - def get_road_blockade_repair_cost(self) -> Optional[int]: - return self._road_blockade_repair_cost - - def get_road_blockade_x(self) -> Optional[int]: - return self._road_blockade_x - - def get_road_blockade_y(self) -> Optional[int]: - return self._road_blockade_y - - def get_is_passable(self) -> Optional[bool]: - return self._is_passable - - def get_is_send_blockade_location(self) -> bool: - return self._is_send_blockade_location - - def get_bit_size(self) -> int: - return self.to_bits().__len__() - - def to_bits(self) -> bitarray: - bit_array = super().to_bits() - write_with_exist_flag( - bit_array, - self._road_entity_id.get_value() if self._road_entity_id else None, - self.SIZE_ROAD_ENTITY_ID, - ) - write_with_exist_flag( - bit_array, - self._road_blockade_entity_id.get_value() - if self._road_blockade_entity_id - else None, - self.SIZE_ROAD_BLOCKADE_ENTITY_ID, - ) - write_with_exist_flag( - bit_array, - self._road_blockade_repair_cost - if self._road_blockade_repair_cost - else None, - self.SIZE_ROAD_BLOCKADE_REPAIR_COST, - ) - if self._is_send_blockade_location: - write_with_exist_flag( - bit_array, - self._road_blockade_x if self._road_blockade_x else None, - self.SIZE_ROAD_BLOCKADE_X, - ) - write_with_exist_flag( - bit_array, - self._road_blockade_y if self._road_blockade_y else None, - self.SIZE_ROAD_BLOCKADE_Y, - ) - else: - write_with_exist_flag(bit_array, None, self.SIZE_ROAD_BLOCKADE_X) - write_with_exist_flag(bit_array, None, self.SIZE_ROAD_BLOCKADE_Y) - write_with_exist_flag( - bit_array, - self._is_passable if self._is_passable else None, - self.SIZE_PASSABLE, - ) - return bit_array - - @classmethod - def from_bits( - cls, bit_array: bitarray, is_wireless_message: bool, sender_entity_id: EntityID - ) -> MessageRoad: - std_message = super().from_bits( - bit_array, is_wireless_message, sender_entity_id - ) - road_id = read_with_exist_flag(bit_array, cls.SIZE_ROAD_ENTITY_ID) - road_blockade_id = read_with_exist_flag( - bit_array, cls.SIZE_ROAD_BLOCKADE_ENTITY_ID - ) - road_blockade_repair_cost = read_with_exist_flag( - bit_array, cls.SIZE_ROAD_BLOCKADE_REPAIR_COST - ) - road_blockade_x = read_with_exist_flag(bit_array, cls.SIZE_ROAD_BLOCKADE_X) - road_blockade_y = read_with_exist_flag(bit_array, cls.SIZE_ROAD_BLOCKADE_Y) - is_passable = ( - True if read_with_exist_flag(bit_array, cls.SIZE_PASSABLE) else False - ) - road = Road(road_id or -1) - blockade = Blockade(road_blockade_id or -1) - blockade.set_repair_cost(road_blockade_repair_cost) - blockade.set_x(road_blockade_x) - blockade.set_y(road_blockade_y) - return MessageRoad( - is_wireless_message, - road, - False, - is_passable, - blockade, - StandardMessagePriority.NORMAL, - sender_entity_id, - std_message.get_ttl(), - ) - - def __hash__(self) -> int: - h = super().__hash__() - return hash( - ( - h, - self._road_entity_id, - self._road_blockade_entity_id, - self._road_blockade_repair_cost, - self._road_blockade_x, - self._road_blockade_y, - self._is_passable, - self._is_send_blockade_location, - ) - ) - - def __str__(self) -> str: - return f"MessageRoad(road_entity_id={self._road_entity_id}, road_blockade_entity_id={self._road_blockade_entity_id}, road_blockade_repair_cost={self._road_blockade_repair_cost}, road_blockade_x={self._road_blockade_x}, road_blockade_y={self._road_blockade_y}, is_passable={self._is_passable}, is_send_blockade_location={self._is_send_blockade_location})" + ACTION_REST: int = 0 + ACTION_MOVE: int = 1 + ACTION_CLEAR: int = 2 + + SIZE_ROAD_ENTITY_ID: int = 32 + SIZE_ROAD_BLOCKADE_ENTITY_ID: int = 32 + SIZE_ROAD_BLOCKADE_REPAIR_COST: int = 32 + SIZE_ROAD_BLOCKADE_X: int = 32 + SIZE_ROAD_BLOCKADE_Y: int = 32 + SIZE_PASSABLE: int = 1 + + def __init__( + self, + is_wireless_message: bool, + road: Road, + is_send_blockade_location: bool, + is_passable: Optional[bool], + blockade: Optional[Blockade], + priority: StandardMessagePriority, + sender_entity_id: EntityID, + ttl: Optional[int] = None, + ): + super().__init__(is_wireless_message, priority, sender_entity_id, ttl) + self._road_entity_id: Optional[EntityID] = road.get_entity_id() + self._road_blockade_entity_id: Optional[EntityID] = None + self._road_blockade_repair_cost: Optional[int] = None + self._road_blockade_x: Optional[int] = None + self._road_blockade_y: Optional[int] = None + + if blockade: + self._road_blockade_entity_id = blockade.get_entity_id() + self._road_blockade_repair_cost = blockade.get_repair_cost() + if is_send_blockade_location: + self._road_blockade_x = blockade.get_x() or None + self._road_blockade_y = blockade.get_y() or None + + self._is_passable: Optional[bool] = is_passable + self._is_send_blockade_location: bool = is_send_blockade_location + + def get_road_entity_id(self) -> Optional[EntityID]: + return self._road_entity_id + + def get_road_blockade_entity_id(self) -> Optional[EntityID]: + return self._road_blockade_entity_id + + def get_road_blockade_repair_cost(self) -> Optional[int]: + return self._road_blockade_repair_cost + + def get_road_blockade_x(self) -> Optional[int]: + return self._road_blockade_x + + def get_road_blockade_y(self) -> Optional[int]: + return self._road_blockade_y + + def get_is_passable(self) -> Optional[bool]: + return self._is_passable + + def get_is_send_blockade_location(self) -> bool: + return self._is_send_blockade_location + + def get_bit_size(self) -> int: + return self.to_bits().__len__() + + def to_bits(self) -> bitarray: + bit_array = super().to_bits() + write_with_exist_flag( + bit_array, + self._road_entity_id.get_value() if self._road_entity_id else None, + self.SIZE_ROAD_ENTITY_ID, + ) + write_with_exist_flag( + bit_array, + self._road_blockade_entity_id.get_value() + if self._road_blockade_entity_id + else None, + self.SIZE_ROAD_BLOCKADE_ENTITY_ID, + ) + write_with_exist_flag( + bit_array, + self._road_blockade_repair_cost if self._road_blockade_repair_cost else None, + self.SIZE_ROAD_BLOCKADE_REPAIR_COST, + ) + if self._is_send_blockade_location: + write_with_exist_flag( + bit_array, + self._road_blockade_x if self._road_blockade_x else None, + self.SIZE_ROAD_BLOCKADE_X, + ) + write_with_exist_flag( + bit_array, + self._road_blockade_y if self._road_blockade_y else None, + self.SIZE_ROAD_BLOCKADE_Y, + ) + else: + write_with_exist_flag(bit_array, None, self.SIZE_ROAD_BLOCKADE_X) + write_with_exist_flag(bit_array, None, self.SIZE_ROAD_BLOCKADE_Y) + write_with_exist_flag( + bit_array, + self._is_passable if self._is_passable else None, + self.SIZE_PASSABLE, + ) + return bit_array + + @classmethod + def from_bits( + cls, bit_array: bitarray, is_wireless_message: bool, sender_entity_id: EntityID + ) -> MessageRoad: + std_message = super().from_bits(bit_array, is_wireless_message, sender_entity_id) + road_id = read_with_exist_flag(bit_array, cls.SIZE_ROAD_ENTITY_ID) + road_blockade_id = read_with_exist_flag(bit_array, cls.SIZE_ROAD_BLOCKADE_ENTITY_ID) + road_blockade_repair_cost = read_with_exist_flag( + bit_array, cls.SIZE_ROAD_BLOCKADE_REPAIR_COST + ) + road_blockade_x = read_with_exist_flag(bit_array, cls.SIZE_ROAD_BLOCKADE_X) + road_blockade_y = read_with_exist_flag(bit_array, cls.SIZE_ROAD_BLOCKADE_Y) + is_passable = True if read_with_exist_flag(bit_array, cls.SIZE_PASSABLE) else False + road = Road(road_id or -1) + blockade = Blockade(road_blockade_id or -1) + blockade.set_repair_cost(road_blockade_repair_cost) + blockade.set_x(road_blockade_x) + blockade.set_y(road_blockade_y) + return MessageRoad( + is_wireless_message, + road, + False, + is_passable, + blockade, + StandardMessagePriority.NORMAL, + sender_entity_id, + std_message.get_ttl(), + ) + + def __hash__(self) -> int: + h = super().__hash__() + return hash( + ( + h, + self._road_entity_id, + self._road_blockade_entity_id, + self._road_blockade_repair_cost, + self._road_blockade_x, + self._road_blockade_y, + self._is_passable, + self._is_send_blockade_location, + ) + ) + + def __str__(self) -> str: + return f"MessageRoad(road_entity_id={self._road_entity_id}, road_blockade_entity_id={self._road_blockade_entity_id}, road_blockade_repair_cost={self._road_blockade_repair_cost}, road_blockade_x={self._road_blockade_x}, road_blockade_y={self._road_blockade_y}, is_passable={self._is_passable}, is_send_blockade_location={self._is_send_blockade_location})" diff --git a/src/adf_core_python/core/agent/communication/standard/bundle/standard_message.py b/src/adf_core_python/core/agent/communication/standard/bundle/standard_message.py index 34ec8f9..296cfd3 100644 --- a/src/adf_core_python/core/agent/communication/standard/bundle/standard_message.py +++ b/src/adf_core_python/core/agent/communication/standard/bundle/standard_message.py @@ -6,66 +6,66 @@ from rcrscore.entities import EntityID from adf_core_python.core.agent.communication.standard.bundle.standard_message_priority import ( - StandardMessagePriority, + StandardMessagePriority, ) from adf_core_python.core.agent.communication.standard.utility.bitarray_with_exits_flag import ( - read_with_exist_flag, - write_with_exist_flag, + read_with_exist_flag, + write_with_exist_flag, ) from adf_core_python.core.component.communication.communication_message import ( - CommunicationMessage, + CommunicationMessage, ) class StandardMessage(CommunicationMessage): - SIZE_TTL: int = 3 + SIZE_TTL: int = 3 - def __init__( - self, - is_wireless_message: bool, - priority: StandardMessagePriority, - sender_entity_id: EntityID, - ttl: Optional[int] = None, - ): - super().__init__(is_wireless_message) - self._priority = priority - self._sender_entity_id = sender_entity_id - self._ttl = ttl + def __init__( + self, + is_wireless_message: bool, + priority: StandardMessagePriority, + sender_entity_id: EntityID, + ttl: Optional[int] = None, + ): + super().__init__(is_wireless_message) + self._priority = priority + self._sender_entity_id = sender_entity_id + self._ttl = ttl - def get_sender_entity_id(self) -> EntityID: - return self._sender_entity_id + def get_sender_entity_id(self) -> EntityID: + return self._sender_entity_id - def get_priority(self) -> StandardMessagePriority: - return self._priority + def get_priority(self) -> StandardMessagePriority: + return self._priority - def get_ttl(self) -> Optional[int]: - return self._ttl + def get_ttl(self) -> Optional[int]: + return self._ttl - @classmethod - def from_bits( - cls, - bit_array: bitarray, - is_wireless_message: bool, - sender_entity_id: EntityID, - ) -> StandardMessage: - ttl = read_with_exist_flag(bit_array, cls.SIZE_TTL) - return StandardMessage( - is_wireless_message, - StandardMessagePriority.NORMAL, - sender_entity_id, - ttl, - ) + @classmethod + def from_bits( + cls, + bit_array: bitarray, + is_wireless_message: bool, + sender_entity_id: EntityID, + ) -> StandardMessage: + ttl = read_with_exist_flag(bit_array, cls.SIZE_TTL) + return StandardMessage( + is_wireless_message, + StandardMessagePriority.NORMAL, + sender_entity_id, + ttl, + ) - def to_bits(self) -> bitarray: - bit_array = bitarray() - write_with_exist_flag(bit_array, self._ttl, self.SIZE_TTL) - return bit_array + def to_bits(self) -> bitarray: + bit_array = bitarray() + write_with_exist_flag(bit_array, self._ttl, self.SIZE_TTL) + return bit_array - def get_bit_size(self) -> int: - raise NotImplementedError + def get_bit_size(self) -> int: + raise NotImplementedError - def __hash__(self) -> int: - return hash((self._sender_entity_id, self._priority, self._ttl)) + def __hash__(self) -> int: + return hash((self._sender_entity_id, self._priority, self._ttl)) - def __str__(self) -> str: - return f"StandardMessage(sender_entity_id={self._sender_entity_id}, priority={self._priority}, ttl={self._ttl})" + def __str__(self) -> str: + return f"StandardMessage(sender_entity_id={self._sender_entity_id}, priority={self._priority}, ttl={self._ttl})" diff --git a/src/adf_core_python/core/agent/communication/standard/bundle/standard_message_priority.py b/src/adf_core_python/core/agent/communication/standard/bundle/standard_message_priority.py index 9e45154..357a9ac 100644 --- a/src/adf_core_python/core/agent/communication/standard/bundle/standard_message_priority.py +++ b/src/adf_core_python/core/agent/communication/standard/bundle/standard_message_priority.py @@ -2,23 +2,23 @@ class StandardMessagePriority(Enum): - """ - Standard message priorities. - """ + """ + Standard message priorities. + """ - LOW = 0 - NORMAL = 1 - HIGH = 2 + LOW = 0 + NORMAL = 1 + HIGH = 2 - def __str__(self) -> str: - return self.name.lower() + def __str__(self) -> str: + return self.name.lower() - def __lt__(self, other: object) -> bool: - if isinstance(other, StandardMessagePriority): - return self.value < other.value - return NotImplemented + def __lt__(self, other: object) -> bool: + if isinstance(other, StandardMessagePriority): + return self.value < other.value + return NotImplemented - def __le__(self, other: object) -> bool: - if isinstance(other, StandardMessagePriority): - return self.value <= other.value - return NotImplemented + def __le__(self, other: object) -> bool: + if isinstance(other, StandardMessagePriority): + return self.value <= other.value + return NotImplemented diff --git a/src/adf_core_python/core/agent/communication/standard/standard_communication_module.py b/src/adf_core_python/core/agent/communication/standard/standard_communication_module.py index f502651..1a91c03 100644 --- a/src/adf_core_python/core/agent/communication/standard/standard_communication_module.py +++ b/src/adf_core_python/core/agent/communication/standard/standard_communication_module.py @@ -8,169 +8,161 @@ from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( - StandardMessage, + StandardMessage, ) from adf_core_python.core.agent.communication.standard.utility.bitarray_with_exits_flag import ( - read_with_exist_flag, - write_with_exist_flag, + read_with_exist_flag, + write_with_exist_flag, ) from adf_core_python.core.component.communication.communication_module import ( - CommunicationModule, + CommunicationModule, ) from adf_core_python.core.logger.logger import get_logger if TYPE_CHECKING: - from adf_core_python.core.agent.agent import Agent + from adf_core_python.core.agent.agent import Agent class StandardCommunicationModule(CommunicationModule): - ESCAPE_CHAR = bitarray("11111111") - SIZE_ID: int = 5 - SIZE_TTL: int = 3 - - def receive(self, agent: Agent, message_manager: MessageManager) -> None: - heard_commands = agent._agent_info.get_heard_commands() - for command in heard_commands: - if isinstance(command, AKSpeak): - sender_entity_id = command.agent_id - if sender_entity_id == agent.get_entity_id(): - continue - data = command.message - is_wireless_message = command.channel != 0 - - if len(data) == 0: - continue - - if is_wireless_message: - bit_array = bitarray() - bit_array.frombytes(data) - self.add_received_message( - message_manager, - is_wireless_message, - sender_entity_id, - bit_array, - ) - else: - try: - voice_message = data.decode("utf-8") - if voice_message.startswith("Help") or voice_message.startswith( - "Ouch" - ): - message_manager.add_heard_agent_help_message_count() - continue - except UnicodeDecodeError: - pass - - escape_char = self.ESCAPE_CHAR.tobytes()[0] - i = 0 - bit_array = bitarray() - a = bitarray() - a.frombytes(data) - while i < len(data): - if data[i] == escape_char: - if (i + 1) >= len(data): - self.add_received_message( - message_manager, - False, - sender_entity_id, - bit_array, - ) - break - elif data[i + 1] != escape_char: - self.add_received_message( - message_manager, - False, - sender_entity_id, - bit_array, - ) - bit_array.clear() - i += 1 # Skip the next character - continue - i += 1 # Skip the escaped character - bits = bitarray() - bits.frombytes(data[i].to_bytes(1, "big")) - bit_array.extend(bits) - i += 1 - - def send(self, agent: Agent, message_manager: MessageManager) -> None: - voice_message_limit_bytes = agent._scenario_info.get_value( - "comms.channels.0.messages.size", 256 - ) - left_voice_message_limit_bits = voice_message_limit_bytes * 8 - voice_message_bit_array = bitarray() - - send_messages = message_manager.get_channel_send_message_list() - - for channel in range(len(send_messages)): - for message in send_messages[channel]: - message_class_index = message_manager.get_message_class_index( - type(message) + ESCAPE_CHAR = bitarray("11111111") + SIZE_ID: int = 5 + SIZE_TTL: int = 3 + + def receive(self, agent: Agent, message_manager: MessageManager) -> None: + heard_commands = agent._agent_info.get_heard_commands() + for command in heard_commands: + if isinstance(command, AKSpeak): + sender_entity_id = command.agent_id + if sender_entity_id == agent.get_entity_id(): + continue + data = command.message + is_wireless_message = command.channel != 0 + + if len(data) == 0: + continue + + if is_wireless_message: + bit_array = bitarray() + bit_array.frombytes(data) + self.add_received_message( + message_manager, + is_wireless_message, + sender_entity_id, + bit_array, + ) + else: + try: + voice_message = data.decode("utf-8") + if voice_message.startswith("Help") or voice_message.startswith("Ouch"): + message_manager.add_heard_agent_help_message_count() + continue + except UnicodeDecodeError: + pass + + escape_char = self.ESCAPE_CHAR.tobytes()[0] + i = 0 + bit_array = bitarray() + a = bitarray() + a.frombytes(data) + while i < len(data): + if data[i] == escape_char: + if (i + 1) >= len(data): + self.add_received_message( + message_manager, + False, + sender_entity_id, + bit_array, + ) + break + elif data[i + 1] != escape_char: + self.add_received_message( + message_manager, + False, + sender_entity_id, + bit_array, ) - bit_array = bitarray() - - write_with_exist_flag(bit_array, message_class_index, self.SIZE_ID) - - bit_array.extend(message.to_bits()) - - if channel > 0: - agent.send_speak( - agent._agent_info.get_time(), - bit_array, - channel, - ) - else: - # bit_arrayを8bitごとに区切れるようにして、エスケープ処理を行う - if len(bit_array) % 8 != 0: - bit_array.extend([False] * (8 - len(bit_array) % 8)) - message_bit_size = len(bit_array) - if message_bit_size <= left_voice_message_limit_bits: - esceped_message_data = bitarray() - for i in range(len(bit_array) // 8): - if bit_array[(i * 8) : ((i + 1) * 8)] == self.ESCAPE_CHAR: - esceped_message_data.extend(self.ESCAPE_CHAR) - esceped_message_data.extend( - bit_array[(i * 8) : ((i + 1) * 8)] - ) - esceped_message_data.extend(self.ESCAPE_CHAR) - if len(esceped_message_data) <= voice_message_limit_bytes: - left_voice_message_limit_bits -= len(esceped_message_data) - voice_message_bit_array.extend(esceped_message_data) - - if len(voice_message_bit_array) > 0: - agent.send_speak( - agent._agent_info.get_time(), - voice_message_bit_array, - 0, - ) - - def add_received_message( - self, - message_manager: MessageManager, - is_wireless_message: bool, - sender_entity_id: EntityID, - data: bitarray, - ) -> None: - message_class_index = read_with_exist_flag(data, self.SIZE_ID) - if message_class_index is None or message_class_index < 0: - get_logger( - f"{self.__class__.__module__}.{self.__class__.__qualname__}" - ).warning(f"Invalid message class index: {message_class_index}") - return - - message = message_manager.get_message_class(message_class_index) - if message is None: - get_logger( - f"{self.__class__.__module__}.{self.__class__.__qualname__}" - ).warning(f"Invalid message class index: {message_class_index}") - return - - if issubclass(message, StandardMessage): - message_instance = message.from_bits( - data, is_wireless_message, sender_entity_id - ) - message_manager.add_received_message(message_instance) + bit_array.clear() + i += 1 # Skip the next character + continue + i += 1 # Skip the escaped character + bits = bitarray() + bits.frombytes(data[i].to_bytes(1, "big")) + bit_array.extend(bits) + i += 1 + + def send(self, agent: Agent, message_manager: MessageManager) -> None: + voice_message_limit_bytes = agent._scenario_info.get_value( + "comms.channels.0.messages.size", 256 + ) + left_voice_message_limit_bits = voice_message_limit_bytes * 8 + voice_message_bit_array = bitarray() + + send_messages = message_manager.get_channel_send_message_list() + + for channel in range(len(send_messages)): + for message in send_messages[channel]: + message_class_index = message_manager.get_message_class_index(type(message)) + bit_array = bitarray() + + write_with_exist_flag(bit_array, message_class_index, self.SIZE_ID) + + bit_array.extend(message.to_bits()) + + if channel > 0: + agent.send_speak( + agent._agent_info.get_time(), + bit_array, + channel, + ) else: - get_logger( - f"{self.__class__.__module__}.{self.__class__.__qualname__}" - ).warning(f"Invalid message class: {message}") - return + # bit_arrayを8bitごとに区切れるようにして、エスケープ処理を行う + if len(bit_array) % 8 != 0: + bit_array.extend([False] * (8 - len(bit_array) % 8)) + message_bit_size = len(bit_array) + if message_bit_size <= left_voice_message_limit_bits: + esceped_message_data = bitarray() + for i in range(len(bit_array) // 8): + if bit_array[(i * 8) : ((i + 1) * 8)] == self.ESCAPE_CHAR: + esceped_message_data.extend(self.ESCAPE_CHAR) + esceped_message_data.extend(bit_array[(i * 8) : ((i + 1) * 8)]) + esceped_message_data.extend(self.ESCAPE_CHAR) + if len(esceped_message_data) <= voice_message_limit_bytes: + left_voice_message_limit_bits -= len(esceped_message_data) + voice_message_bit_array.extend(esceped_message_data) + + if len(voice_message_bit_array) > 0: + agent.send_speak( + agent._agent_info.get_time(), + voice_message_bit_array, + 0, + ) + + def add_received_message( + self, + message_manager: MessageManager, + is_wireless_message: bool, + sender_entity_id: EntityID, + data: bitarray, + ) -> None: + message_class_index = read_with_exist_flag(data, self.SIZE_ID) + if message_class_index is None or message_class_index < 0: + get_logger(f"{self.__class__.__module__}.{self.__class__.__qualname__}").warning( + f"Invalid message class index: {message_class_index}" + ) + return + + message = message_manager.get_message_class(message_class_index) + if message is None: + get_logger(f"{self.__class__.__module__}.{self.__class__.__qualname__}").warning( + f"Invalid message class index: {message_class_index}" + ) + return + + if issubclass(message, StandardMessage): + message_instance = message.from_bits(data, is_wireless_message, sender_entity_id) + message_manager.add_received_message(message_instance) + else: + get_logger(f"{self.__class__.__module__}.{self.__class__.__qualname__}").warning( + f"Invalid message class: {message}" + ) + return diff --git a/src/adf_core_python/core/agent/communication/standard/utility/apply_to_world_info.py b/src/adf_core_python/core/agent/communication/standard/utility/apply_to_world_info.py index 56b1f8f..3c0efb9 100644 --- a/src/adf_core_python/core/agent/communication/standard/utility/apply_to_world_info.py +++ b/src/adf_core_python/core/agent/communication/standard/utility/apply_to_world_info.py @@ -1,337 +1,317 @@ from rcrscore.entities import ( - AmbulanceTeam, - Blockade, - Building, - Civilian, - FireBrigade, - PoliceForce, - Road, + AmbulanceTeam, + Blockade, + Building, + Civilian, + FireBrigade, + PoliceForce, + Road, ) from adf_core_python.core.agent.communication.standard.bundle.information.message_ambulance_team import ( - MessageAmbulanceTeam, + MessageAmbulanceTeam, ) from adf_core_python.core.agent.communication.standard.bundle.information.message_building import ( - MessageBuilding, + MessageBuilding, ) from adf_core_python.core.agent.communication.standard.bundle.information.message_civilian import ( - MessageCivilian, + MessageCivilian, ) from adf_core_python.core.agent.communication.standard.bundle.information.message_fire_brigade import ( - MessageFireBrigade, + MessageFireBrigade, ) from adf_core_python.core.agent.communication.standard.bundle.information.message_police_force import ( - MessagePoliceForce, + MessagePoliceForce, ) from adf_core_python.core.agent.communication.standard.bundle.information.message_road import ( - MessageRoad, + MessageRoad, ) from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( - StandardMessage, + StandardMessage, ) from adf_core_python.core.agent.info.world_info import WorldInfo def apply_to_world_info( - world_info: WorldInfo, - standard_message: StandardMessage, + world_info: WorldInfo, + standard_message: StandardMessage, ) -> None: - """ - Apply to world info. + """ + Apply to world info. - PARAMETERS - ---------- - world_info: WorldInfo - The world info to apply to. - standard_message: StandardMessage - The standard message to apply to world info. - """ + PARAMETERS + ---------- + world_info: WorldInfo + The world info to apply to. + standard_message: StandardMessage + The standard message to apply to world info. + """ - if isinstance(standard_message, MessageAmbulanceTeam): - _apply_to_world_info_ambulance_team(world_info, standard_message) - elif isinstance(standard_message, MessageFireBrigade): - _apply_to_world_info_fire_brigade(world_info, standard_message) - elif isinstance(standard_message, MessagePoliceForce): - _apply_to_world_info_police_force(world_info, standard_message) - elif isinstance(standard_message, MessageCivilian): - _apply_to_world_info_civilian(world_info, standard_message) - elif isinstance(standard_message, MessageBuilding): - _apply_to_world_info_building(world_info, standard_message) - elif isinstance(standard_message, MessageRoad): - _apply_to_world_info_road(world_info, standard_message) - else: - return + if isinstance(standard_message, MessageAmbulanceTeam): + _apply_to_world_info_ambulance_team(world_info, standard_message) + elif isinstance(standard_message, MessageFireBrigade): + _apply_to_world_info_fire_brigade(world_info, standard_message) + elif isinstance(standard_message, MessagePoliceForce): + _apply_to_world_info_police_force(world_info, standard_message) + elif isinstance(standard_message, MessageCivilian): + _apply_to_world_info_civilian(world_info, standard_message) + elif isinstance(standard_message, MessageBuilding): + _apply_to_world_info_building(world_info, standard_message) + elif isinstance(standard_message, MessageRoad): + _apply_to_world_info_road(world_info, standard_message) + else: + return def _apply_to_world_info_ambulance_team( - world_info: WorldInfo, - message_ambulance_team: MessageAmbulanceTeam, + world_info: WorldInfo, + message_ambulance_team: MessageAmbulanceTeam, ) -> None: - """ - Apply to world info for ambulance team. + """ + Apply to world info for ambulance team. - PARAMETERS - ---------- - world_info: WorldInfo - The world info to apply to. - standard_message: StandardMessage - The standard message to apply to world info. - """ - entity_id = message_ambulance_team.get_ambulance_team_entity_id() - if entity_id is None: - return - entity = world_info.get_entity(entity_id) - if entity is None: - ambulance = AmbulanceTeam(entity_id.get_value()) - if (hp := message_ambulance_team.get_ambulance_team_hp()) is not None: - ambulance.set_hp(hp) - if (damege := message_ambulance_team.get_ambulance_team_damage()) is not None: - ambulance.set_damage(damege) - if ( - buriedness := message_ambulance_team.get_ambulance_team_buriedness() - ) is not None: - ambulance.set_buriedness(buriedness) - if ( - position := message_ambulance_team.get_ambulance_team_position() - ) is not None: - ambulance.set_position(position) - world_info.add_entity(ambulance) - else: - if isinstance(entity, AmbulanceTeam): - if (hp := message_ambulance_team.get_ambulance_team_hp()) is not None: - entity.set_hp(hp) - if ( - damege := message_ambulance_team.get_ambulance_team_damage() - ) is not None: - entity.set_damage(damege) - if ( - buriedness := message_ambulance_team.get_ambulance_team_buriedness() - ) is not None: - entity.set_buriedness(buriedness) - if ( - position := message_ambulance_team.get_ambulance_team_position() - ) is not None: - entity.set_position(position) + PARAMETERS + ---------- + world_info: WorldInfo + The world info to apply to. + standard_message: StandardMessage + The standard message to apply to world info. + """ + entity_id = message_ambulance_team.get_ambulance_team_entity_id() + if entity_id is None: + return + entity = world_info.get_entity(entity_id) + if entity is None: + ambulance = AmbulanceTeam(entity_id.get_value()) + if (hp := message_ambulance_team.get_ambulance_team_hp()) is not None: + ambulance.set_hp(hp) + if (damege := message_ambulance_team.get_ambulance_team_damage()) is not None: + ambulance.set_damage(damege) + if ( + buriedness := message_ambulance_team.get_ambulance_team_buriedness() + ) is not None: + ambulance.set_buriedness(buriedness) + if (position := message_ambulance_team.get_ambulance_team_position()) is not None: + ambulance.set_position(position) + world_info.add_entity(ambulance) + else: + if isinstance(entity, AmbulanceTeam): + if (hp := message_ambulance_team.get_ambulance_team_hp()) is not None: + entity.set_hp(hp) + if (damege := message_ambulance_team.get_ambulance_team_damage()) is not None: + entity.set_damage(damege) + if ( + buriedness := message_ambulance_team.get_ambulance_team_buriedness() + ) is not None: + entity.set_buriedness(buriedness) + if (position := message_ambulance_team.get_ambulance_team_position()) is not None: + entity.set_position(position) def _apply_to_world_info_fire_brigade( - world_info: WorldInfo, - message_fire_brigade: MessageFireBrigade, + world_info: WorldInfo, + message_fire_brigade: MessageFireBrigade, ) -> None: - """ - Apply to world info for fire brigade. + """ + Apply to world info for fire brigade. - PARAMETERS - ---------- - world_info: WorldInfo - The world info to apply to. - standard_message: StandardMessage - The standard message to apply to world info. - """ - entity_id = message_fire_brigade.get_fire_brigade_entity_id() - if entity_id is None: - return - entity = world_info.get_entity(entity_id) - if entity is None: - fire_brigade = FireBrigade(entity_id.get_value()) - if (hp := message_fire_brigade.get_fire_brigade_hp()) is not None: - fire_brigade.set_hp(hp) - if (damage := message_fire_brigade.get_fire_brigade_damage()) is not None: - fire_brigade.set_damage(damage) - if ( - buriedness := message_fire_brigade.get_fire_brigade_buriedness() - ) is not None: - fire_brigade.set_buriedness(buriedness) - if (position := message_fire_brigade.get_fire_brigade_position()) is not None: - fire_brigade.set_position(position) - if (water := message_fire_brigade.get_fire_brigade_water()) is not None: - fire_brigade.set_water(water) - world_info.add_entity(fire_brigade) - else: - if isinstance(entity, FireBrigade): - if (hp := message_fire_brigade.get_fire_brigade_hp()) is not None: - entity.set_hp(hp) - if (damage := message_fire_brigade.get_fire_brigade_damage()) is not None: - entity.set_damage(damage) - if ( - buriedness := message_fire_brigade.get_fire_brigade_buriedness() - ) is not None: - entity.set_buriedness(buriedness) - if ( - position := message_fire_brigade.get_fire_brigade_position() - ) is not None: - entity.set_position(position) - if (water := message_fire_brigade.get_fire_brigade_water()) is not None: - entity.set_water(water) + PARAMETERS + ---------- + world_info: WorldInfo + The world info to apply to. + standard_message: StandardMessage + The standard message to apply to world info. + """ + entity_id = message_fire_brigade.get_fire_brigade_entity_id() + if entity_id is None: + return + entity = world_info.get_entity(entity_id) + if entity is None: + fire_brigade = FireBrigade(entity_id.get_value()) + if (hp := message_fire_brigade.get_fire_brigade_hp()) is not None: + fire_brigade.set_hp(hp) + if (damage := message_fire_brigade.get_fire_brigade_damage()) is not None: + fire_brigade.set_damage(damage) + if (buriedness := message_fire_brigade.get_fire_brigade_buriedness()) is not None: + fire_brigade.set_buriedness(buriedness) + if (position := message_fire_brigade.get_fire_brigade_position()) is not None: + fire_brigade.set_position(position) + if (water := message_fire_brigade.get_fire_brigade_water()) is not None: + fire_brigade.set_water(water) + world_info.add_entity(fire_brigade) + else: + if isinstance(entity, FireBrigade): + if (hp := message_fire_brigade.get_fire_brigade_hp()) is not None: + entity.set_hp(hp) + if (damage := message_fire_brigade.get_fire_brigade_damage()) is not None: + entity.set_damage(damage) + if (buriedness := message_fire_brigade.get_fire_brigade_buriedness()) is not None: + entity.set_buriedness(buriedness) + if (position := message_fire_brigade.get_fire_brigade_position()) is not None: + entity.set_position(position) + if (water := message_fire_brigade.get_fire_brigade_water()) is not None: + entity.set_water(water) def _apply_to_world_info_police_force( - world_info: WorldInfo, - message_police_force: MessagePoliceForce, + world_info: WorldInfo, + message_police_force: MessagePoliceForce, ) -> None: - """ - Apply to world info for police force. + """ + Apply to world info for police force. - PARAMETERS - ---------- - world_info: WorldInfo - The world info to apply to. - standard_message: StandardMessage - The standard message to apply to world info. - """ - entity_id = message_police_force.get_police_force_entity_id() - if entity_id is None: - return - entity = world_info.get_entity(entity_id) - if entity is None: - police_force = PoliceForce(entity_id.get_value()) - if (hp := message_police_force.get_police_force_hp()) is not None: - police_force.set_hp(hp) - if (damage := message_police_force.get_police_force_damage()) is not None: - police_force.set_damage(damage) - if ( - buriedness := message_police_force.get_police_force_buriedness() - ) is not None: - police_force.set_buriedness(buriedness) - if (position := message_police_force.get_police_force_position()) is not None: - police_force.set_position(position) - world_info.add_entity(police_force) - else: - if isinstance(entity, PoliceForce): - if (hp := message_police_force.get_police_force_hp()) is not None: - entity.set_hp(hp) - if (damage := message_police_force.get_police_force_damage()) is not None: - entity.set_damage(damage) - if ( - buriedness := message_police_force.get_police_force_buriedness() - ) is not None: - entity.set_buriedness(buriedness) - if ( - position := message_police_force.get_police_force_position() - ) is not None: - entity.set_position(position) + PARAMETERS + ---------- + world_info: WorldInfo + The world info to apply to. + standard_message: StandardMessage + The standard message to apply to world info. + """ + entity_id = message_police_force.get_police_force_entity_id() + if entity_id is None: + return + entity = world_info.get_entity(entity_id) + if entity is None: + police_force = PoliceForce(entity_id.get_value()) + if (hp := message_police_force.get_police_force_hp()) is not None: + police_force.set_hp(hp) + if (damage := message_police_force.get_police_force_damage()) is not None: + police_force.set_damage(damage) + if (buriedness := message_police_force.get_police_force_buriedness()) is not None: + police_force.set_buriedness(buriedness) + if (position := message_police_force.get_police_force_position()) is not None: + police_force.set_position(position) + world_info.add_entity(police_force) + else: + if isinstance(entity, PoliceForce): + if (hp := message_police_force.get_police_force_hp()) is not None: + entity.set_hp(hp) + if (damage := message_police_force.get_police_force_damage()) is not None: + entity.set_damage(damage) + if (buriedness := message_police_force.get_police_force_buriedness()) is not None: + entity.set_buriedness(buriedness) + if (position := message_police_force.get_police_force_position()) is not None: + entity.set_position(position) def _apply_to_world_info_civilian( - world_info: WorldInfo, - message_civilian: MessageCivilian, + world_info: WorldInfo, + message_civilian: MessageCivilian, ) -> None: - """ - Apply to world info for civilian. + """ + Apply to world info for civilian. - PARAMETERS - ---------- - world_info: WorldInfo - The world info to apply to. - standard_message: StandardMessage - The standard message to apply to world info. - """ - entity_id = message_civilian.get_civilian_entity_id() - if entity_id is None: - return - entity = world_info.get_entity(entity_id) - if entity is None: - civilian = Civilian(entity_id.get_value()) - if (hp := message_civilian.get_civilian_hp()) is not None: - civilian.set_hp(hp) - if (damage := message_civilian.get_civilian_damage()) is not None: - civilian.set_damage(damage) - if (buriedness := message_civilian.get_civilian_buriedness()) is not None: - civilian.set_buriedness(buriedness) - if (position := message_civilian.get_civilian_position()) is not None: - civilian.set_position(position) - world_info.add_entity(civilian) - else: - if isinstance(entity, Civilian): - if (hp := message_civilian.get_civilian_hp()) is not None: - entity.set_hp(hp) - if (damage := message_civilian.get_civilian_damage()) is not None: - entity.set_damage(damage) - if (buriedness := message_civilian.get_civilian_buriedness()) is not None: - entity.set_buriedness(buriedness) - if (position := message_civilian.get_civilian_position()) is not None: - entity.set_position(position) + PARAMETERS + ---------- + world_info: WorldInfo + The world info to apply to. + standard_message: StandardMessage + The standard message to apply to world info. + """ + entity_id = message_civilian.get_civilian_entity_id() + if entity_id is None: + return + entity = world_info.get_entity(entity_id) + if entity is None: + civilian = Civilian(entity_id.get_value()) + if (hp := message_civilian.get_civilian_hp()) is not None: + civilian.set_hp(hp) + if (damage := message_civilian.get_civilian_damage()) is not None: + civilian.set_damage(damage) + if (buriedness := message_civilian.get_civilian_buriedness()) is not None: + civilian.set_buriedness(buriedness) + if (position := message_civilian.get_civilian_position()) is not None: + civilian.set_position(position) + world_info.add_entity(civilian) + else: + if isinstance(entity, Civilian): + if (hp := message_civilian.get_civilian_hp()) is not None: + entity.set_hp(hp) + if (damage := message_civilian.get_civilian_damage()) is not None: + entity.set_damage(damage) + if (buriedness := message_civilian.get_civilian_buriedness()) is not None: + entity.set_buriedness(buriedness) + if (position := message_civilian.get_civilian_position()) is not None: + entity.set_position(position) def _apply_to_world_info_building( - world_info: WorldInfo, - message_building: MessageBuilding, + world_info: WorldInfo, + message_building: MessageBuilding, ) -> None: - """ - Apply to world info for building. + """ + Apply to world info for building. - PARAMETERS - ---------- - world_info: WorldInfo - The world info to apply to. - standard_message: StandardMessage - The standard message to apply to world info. - """ - entity_id = message_building.get_building_entity_id() - if entity_id is None: - return - entity = world_info.get_entity(entity_id) - if entity is None: - building = Building(entity_id.get_value()) - if (fieryness := message_building.get_building_fireyness()) is not None: - building.set_fieryness(fieryness) - if (brokenness := message_building.get_building_brokenness()) is not None: - building.set_brokenness(brokenness) - if (temperature := message_building.get_building_temperature()) is not None: - building.set_temperature(temperature) - world_info.add_entity(building) - else: - if isinstance(entity, Building): - if (fieryness := message_building.get_building_fireyness()) is not None: - entity.set_fieryness(fieryness) - if (brokenness := message_building.get_building_brokenness()) is not None: - entity.set_brokenness(brokenness) - if (temperature := message_building.get_building_temperature()) is not None: - entity.set_temperature(temperature) + PARAMETERS + ---------- + world_info: WorldInfo + The world info to apply to. + standard_message: StandardMessage + The standard message to apply to world info. + """ + entity_id = message_building.get_building_entity_id() + if entity_id is None: + return + entity = world_info.get_entity(entity_id) + if entity is None: + building = Building(entity_id.get_value()) + if (fieryness := message_building.get_building_fireyness()) is not None: + building.set_fieryness(fieryness) + if (brokenness := message_building.get_building_brokenness()) is not None: + building.set_brokenness(brokenness) + if (temperature := message_building.get_building_temperature()) is not None: + building.set_temperature(temperature) + world_info.add_entity(building) + else: + if isinstance(entity, Building): + if (fieryness := message_building.get_building_fireyness()) is not None: + entity.set_fieryness(fieryness) + if (brokenness := message_building.get_building_brokenness()) is not None: + entity.set_brokenness(brokenness) + if (temperature := message_building.get_building_temperature()) is not None: + entity.set_temperature(temperature) def _apply_to_world_info_road( - world_info: WorldInfo, - message_road: MessageRoad, + world_info: WorldInfo, + message_road: MessageRoad, ) -> None: - """ - Apply to world info for road. + """ + Apply to world info for road. - PARAMETERS - ---------- - world_info: WorldInfo - The world info to apply to. - standard_message: StandardMessage - The standard message to apply to world info. - """ - entity_id = message_road.get_road_entity_id() - if entity_id is None: - return - entity = world_info.get_entity(entity_id) - if not isinstance(entity, Road): - return + PARAMETERS + ---------- + world_info: WorldInfo + The world info to apply to. + standard_message: StandardMessage + The standard message to apply to world info. + """ + entity_id = message_road.get_road_entity_id() + if entity_id is None: + return + entity = world_info.get_entity(entity_id) + if not isinstance(entity, Road): + return - blockade_entity_id = message_road.get_road_blockade_entity_id() - if blockade_entity_id is None: - return + blockade_entity_id = message_road.get_road_blockade_entity_id() + if blockade_entity_id is None: + return - blockade = world_info.get_entity(blockade_entity_id) - if blockade is None: - road_blockade = Blockade(blockade_entity_id.get_value()) - if (repair_cost := message_road.get_road_blockade_repair_cost()) is not None: - road_blockade.set_repair_cost(repair_cost) - if (x := message_road.get_road_blockade_x()) is not None: - road_blockade.set_x(x) - if (y := message_road.get_road_blockade_y()) is not None: - road_blockade.set_y(y) - world_info.add_entity(road_blockade) - else: - if isinstance(blockade, Blockade): - if ( - repair_cost := message_road.get_road_blockade_repair_cost() - ) is not None: - blockade.set_repair_cost(repair_cost) - if (x := message_road.get_road_blockade_x()) is not None: - blockade.set_x(x) - if (y := message_road.get_road_blockade_y()) is not None: - blockade.set_y(y) + blockade = world_info.get_entity(blockade_entity_id) + if blockade is None: + road_blockade = Blockade(blockade_entity_id.get_value()) + if (repair_cost := message_road.get_road_blockade_repair_cost()) is not None: + road_blockade.set_repair_cost(repair_cost) + if (x := message_road.get_road_blockade_x()) is not None: + road_blockade.set_x(x) + if (y := message_road.get_road_blockade_y()) is not None: + road_blockade.set_y(y) + world_info.add_entity(road_blockade) + else: + if isinstance(blockade, Blockade): + if (repair_cost := message_road.get_road_blockade_repair_cost()) is not None: + blockade.set_repair_cost(repair_cost) + if (x := message_road.get_road_blockade_x()) is not None: + blockade.set_x(x) + if (y := message_road.get_road_blockade_y()) is not None: + blockade.set_y(y) diff --git a/src/adf_core_python/core/agent/communication/standard/utility/bitarray_with_exits_flag.py b/src/adf_core_python/core/agent/communication/standard/utility/bitarray_with_exits_flag.py index 64ab01b..ec6b3b3 100644 --- a/src/adf_core_python/core/agent/communication/standard/utility/bitarray_with_exits_flag.py +++ b/src/adf_core_python/core/agent/communication/standard/utility/bitarray_with_exits_flag.py @@ -7,66 +7,66 @@ def write_with_exist_flag( - bit_array: bitarray, value: Optional[int], bit_size: int + bit_array: bitarray, value: Optional[int], bit_size: int ) -> None: - """ - Write value to bit_array with an exist flag. - If value is None, write IS_NOT_EXIST_FLAG to bit_array. - If value is not None, write IS_EXIST_FLAG to bit_array and then write value to bit_array. + """ + Write value to bit_array with an exist flag. + If value is None, write IS_NOT_EXIST_FLAG to bit_array. + If value is not None, write IS_EXIST_FLAG to bit_array and then write value to bit_array. - PARAMETERS - ---------- - bit_array: bitarray - The bitarray to write to. - value: Optional[int] - The value to write. - bit_size: int - The number of bits to use to write value. + PARAMETERS + ---------- + bit_array: bitarray + The bitarray to write to. + value: Optional[int] + The value to write. + bit_size: int + The number of bits to use to write value. - RAISES - ------ - ValueError - If value is too large to fit into bit_size bits. - """ - if value is None: - bit_array.extend([IS_NOT_EXIST_FLAG]) - else: - bit_array.extend([IS_EXIST_FLAG]) - bit_value = bitarray(f"{value:0{bit_size}b}") - if len(bit_value) > bit_size: - raise ValueError(f"Value {value} is too large to fit into {bit_size} bits") - bit_array.extend(bit_value) + RAISES + ------ + ValueError + If value is too large to fit into bit_size bits. + """ + if value is None: + bit_array.extend([IS_NOT_EXIST_FLAG]) + else: + bit_array.extend([IS_EXIST_FLAG]) + bit_value = bitarray(f"{value:0{bit_size}b}") + if len(bit_value) > bit_size: + raise ValueError(f"Value {value} is too large to fit into {bit_size} bits") + bit_array.extend(bit_value) def read_with_exist_flag(bit_array: bitarray, size: int) -> Optional[int]: - """ - Read value from bit_array with an exist flag. - If the first bit is IS_NOT_EXIST_FLAG, return None. - If the first bit is IS_EXIST_FLAG, read and return value from bit_array. + """ + Read value from bit_array with an exist flag. + If the first bit is IS_NOT_EXIST_FLAG, return None. + If the first bit is IS_EXIST_FLAG, read and return value from bit_array. - PARAMETERS - ---------- - bit_array: bitarray - The bitarray to read from. - size: int - The number of bits to read to get value. + PARAMETERS + ---------- + bit_array: bitarray + The bitarray to read from. + size: int + The number of bits to read to get value. - RETURNS - ------- - Optional[int] - The value read from bit_array. + RETURNS + ------- + Optional[int] + The value read from bit_array. - RAISES - ------ - ValueError - If the first bit is not IS_EXIST_FLAG or IS_NOT_EXIST_FLAG. - """ - exist_flag = bit_array.pop(0) - if exist_flag == IS_NOT_EXIST_FLAG: - return None - elif exist_flag == IS_EXIST_FLAG: - value = int(bit_array[:size].to01(), 2) - del bit_array[:size] - return value - else: - raise ValueError("Invalid exist flag") + RAISES + ------ + ValueError + If the first bit is not IS_EXIST_FLAG or IS_NOT_EXIST_FLAG. + """ + exist_flag = bit_array.pop(0) + if exist_flag == IS_NOT_EXIST_FLAG: + return None + elif exist_flag == IS_EXIST_FLAG: + value = int(bit_array[:size].to01(), 2) + del bit_array[:size] + return value + else: + raise ValueError("Invalid exist flag") diff --git a/src/adf_core_python/core/agent/config/module_config.py b/src/adf_core_python/core/agent/config/module_config.py index 7c65649..25ff869 100644 --- a/src/adf_core_python/core/agent/config/module_config.py +++ b/src/adf_core_python/core/agent/config/module_config.py @@ -5,86 +5,86 @@ class ModuleConfig(Config): - DEFAULT_CONFIG_FILE_NAME: Final[str] = "config/module.yaml" + DEFAULT_CONFIG_FILE_NAME: Final[str] = "config/module.yaml" - def __init__(self, config_file_name: str = DEFAULT_CONFIG_FILE_NAME): - """ - Constructor + def __init__(self, config_file_name: str = DEFAULT_CONFIG_FILE_NAME): + """ + Constructor - Parameters - ---------- - config_file_name : str, optional - Configuration file name, by default DEFAULT_CONFIG_FILE_NAME + Parameters + ---------- + config_file_name : str, optional + Configuration file name, by default DEFAULT_CONFIG_FILE_NAME - Raises - ------ - FileNotFoundError - If config file not found - Exception - If error reading config file + Raises + ------ + FileNotFoundError + If config file not found + Exception + If error reading config file - Examples - -------- - >>> config = ModuleConfig("config/module.yaml") - >>> config.get_value("DefaultTacticsPoliceOffice.TargetAllocator") - "sample_team.module.complex.SamplePoliceTargetAllocator" - """ - super().__init__() - data = self._read_from_yaml(config_file_name) - flatten_data = self._flatten(data) - for key, value in flatten_data.items(): - self.set_value(key, value) + Examples + -------- + >>> config = ModuleConfig("config/module.yaml") + >>> config.get_value("DefaultTacticsPoliceOffice.TargetAllocator") + "sample_team.module.complex.SamplePoliceTargetAllocator" + """ + super().__init__() + data = self._read_from_yaml(config_file_name) + flatten_data = self._flatten(data) + for key, value in flatten_data.items(): + self.set_value(key, value) - def _read_from_yaml(self, file_name: str) -> dict[str, Any]: - """ - Read configuration from yaml file + def _read_from_yaml(self, file_name: str) -> dict[str, Any]: + """ + Read configuration from yaml file - Parameters - ---------- - file_name : str - Configuration file name + Parameters + ---------- + file_name : str + Configuration file name - Returns - ------- - dict[str, Any] - Configuration data - """ - try: - with open(file_name, mode="r", encoding="utf-8") as file: - data = safe_load(file) - except FileNotFoundError: - raise FileNotFoundError(f"Config file not found: {file_name}") - except Exception as e: - raise Exception(f"Error reading config file: {file_name}, {e}") + Returns + ------- + dict[str, Any] + Configuration data + """ + try: + with open(file_name, mode="r", encoding="utf-8") as file: + data = safe_load(file) + except FileNotFoundError: + raise FileNotFoundError(f"Config file not found: {file_name}") + except Exception as e: + raise Exception(f"Error reading config file: {file_name}, {e}") - return data + return data - def _flatten( - self, data: dict[str, Any], parent_key: str = "", sep: str = "." - ) -> dict[str, Any]: - """ - Flatten nested dictionary to a single level dictionary + def _flatten( + self, data: dict[str, Any], parent_key: str = "", sep: str = "." + ) -> dict[str, Any]: + """ + Flatten nested dictionary to a single level dictionary - Parameters - ---------- - data : dict[str, Any] - Nested dictionary - parent_key : str, optional - Parent key, by default "" - sep : str, optional - Separator, by default "." + Parameters + ---------- + data : dict[str, Any] + Nested dictionary + parent_key : str, optional + Parent key, by default "" + sep : str, optional + Separator, by default "." - Returns - ------- - dict[str, Any] - Flattened dictionary - """ - flatten_data: dict[str, Any] = {} - for key, value in data.items(): - new_key = f"{parent_key}{sep}{key}" if parent_key else key - if isinstance(value, dict): - v: dict[str, Any] = value - flatten_data.update(self._flatten(v, new_key, sep=sep)) - else: - flatten_data[new_key] = value - return flatten_data + Returns + ------- + dict[str, Any] + Flattened dictionary + """ + flatten_data: dict[str, Any] = {} + for key, value in data.items(): + new_key = f"{parent_key}{sep}{key}" if parent_key else key + if isinstance(value, dict): + v: dict[str, Any] = value + flatten_data.update(self._flatten(v, new_key, sep=sep)) + else: + flatten_data[new_key] = value + return flatten_data diff --git a/src/adf_core_python/core/agent/develop/develop_data.py b/src/adf_core_python/core/agent/develop/develop_data.py index 7d7c551..35bcb13 100644 --- a/src/adf_core_python/core/agent/develop/develop_data.py +++ b/src/adf_core_python/core/agent/develop/develop_data.py @@ -3,68 +3,68 @@ class DevelopData: - DEFAULT_FILE_NAME: Final[str] = "config/develop.json" + DEFAULT_FILE_NAME: Final[str] = "config/develop.json" - def __init__( - self, is_develop_mode: bool = False, file_name: str = DEFAULT_FILE_NAME - ) -> None: - """ - Constructor - """ - self._develop_data: dict[str, Any] = self._set_data_from_json(file_name) - self._is_develop_mode: bool = is_develop_mode + def __init__( + self, is_develop_mode: bool = False, file_name: str = DEFAULT_FILE_NAME + ) -> None: + """ + Constructor + """ + self._develop_data: dict[str, Any] = self._set_data_from_json(file_name) + self._is_develop_mode: bool = is_develop_mode - self._set_data_from_json(file_name) + self._set_data_from_json(file_name) - def _set_data_from_json(self, file_name: str) -> dict[str, Any]: - """ - Set data from json + def _set_data_from_json(self, file_name: str) -> dict[str, Any]: + """ + Set data from json - Parameters - ---------- - file_name : str, optional - Develop file name, by default DEFAULT_FILE_NAME + Parameters + ---------- + file_name : str, optional + Develop file name, by default DEFAULT_FILE_NAME - Returns - ------- - dict[str, Any] - Develop data - """ - try: - with open(file_name, mode="r", encoding="utf-8") as file: - return json.load(file) - except FileNotFoundError: - raise FileNotFoundError(f"Develop file not found: {file_name}") - except Exception as e: - raise Exception(f"Error reading develop file: {file_name}, {e}") + Returns + ------- + dict[str, Any] + Develop data + """ + try: + with open(file_name, mode="r", encoding="utf-8") as file: + return json.load(file) + except FileNotFoundError: + raise FileNotFoundError(f"Develop file not found: {file_name}") + except Exception as e: + raise Exception(f"Error reading develop file: {file_name}, {e}") - def is_develop_mode(self) -> bool: - """ - Check if develop mode is enabled + def is_develop_mode(self) -> bool: + """ + Check if develop mode is enabled - Returns - ------- - bool - True if develop mode is enabled - """ - return self._is_develop_mode + Returns + ------- + bool + True if develop mode is enabled + """ + return self._is_develop_mode - def get_value(self, key: str, default_value: Any = None) -> Any: - """ - Get value from develop data - If develop mode is disabled, return default value + def get_value(self, key: str, default_value: Any = None) -> Any: + """ + Get value from develop data + If develop mode is disabled, return default value - Parameters - ---------- - key : str - Key + Parameters + ---------- + key : str + Key - Returns - ------- - Any - Value - """ - if not self._is_develop_mode: - return default_value + Returns + ------- + Any + Value + """ + if not self._is_develop_mode: + return default_value - return self._develop_data.get(key, default_value) + return self._develop_data.get(key, default_value) diff --git a/src/adf_core_python/core/agent/info/agent_info.py b/src/adf_core_python/core/agent/info/agent_info.py index 5dea6a5..20658bb 100644 --- a/src/adf_core_python/core/agent/info/agent_info.py +++ b/src/adf_core_python/core/agent/info/agent_info.py @@ -13,179 +13,179 @@ from adf_core_python.core.agent.action.action import Action if TYPE_CHECKING: - from adf_core_python.core.agent.agent import Agent + from adf_core_python.core.agent.agent import Agent class AgentInfo: - def __init__(self, agent: Agent, world_model: WorldModel): - self._agent: Agent = agent - self._world_model: WorldModel = world_model - self._time: int = 0 - self._action_history: dict[int, Action] = {} - self._heard_commands: list[Command] = [] - self._change_set: ChangeSet = ChangeSet() - self._start_think_time: float = 0.0 - - def set_time(self, time: int) -> None: - """ - Set the current time of the agent - - Parameters - ---------- - time : int - Current time - """ - self._time = time - - def get_time(self) -> int: - """ - Get the current time of the agent - - Returns - ------- - int - Current time - """ - return self._time - - def set_heard_commands(self, heard_commands: list[Command]) -> None: - """ - Set the heard commands - - Parameters - ---------- - heard_commands : list[Command] - Heard commands - """ - self._heard_commands = heard_commands - - def get_heard_commands(self) -> list[Command]: - """ - Get the heard commands - - Returns - ------- - list[Command] - Heard commands - """ - return self._heard_commands - - def get_entity_id(self) -> EntityID: - """ - Get the entity ID of the agent - - Returns - ------- - EntityID - Entity ID of the agent - """ - # TODO: Agent class should return EntityID instead of EntityID | None - return self._agent.get_entity_id() - - def get_myself(self) -> Entity | None: - """ - Get the entity of the agent - - Returns - ------- - Entity - Entity of the agent - """ - return self._world_model.get_entity(self.get_entity_id()) - - def get_position_entity_id(self) -> EntityID | None: - """ - Get the position entity ID of the agent - - Returns - ------- - EntityID - Position entity ID of the agent - """ - entity = self._world_model.get_entity(self.get_entity_id()) - if entity is None: - return None - - if isinstance(entity, Human): - return entity.get_position() - else: - return entity.get_entity_id() - - def set_change_set(self, change_set: ChangeSet) -> None: - """ - Set the change set - - Parameters - ---------- - change_set : ChangeSet - Change set - """ - self._change_set = change_set - - def get_change_set(self) -> ChangeSet: - """ - Get the change set - - Returns - ------- - ChangeSet - Change set - """ - return self._change_set - - def some_one_on_board(self) -> Human | None: - """ - Get the human if someone is on board - - Returns - ------- - Human | None - Human if someone is on board, None otherwise - """ - entity_id: EntityID = self.get_entity_id() - for entity in self._world_model.get_entities(): - if isinstance(entity, Civilian): - if entity.get_position() == entity_id: - return entity - return None - - def get_executed_action(self, time: int) -> Action | None: - """ - Get the executed action at the given time - - Parameters - ---------- - time : int - Time - """ - return self._action_history.get(time) - - def set_executed_action(self, time: int, action: Action) -> None: - """ - Set the executed action at the given time - - Parameters - ---------- - time : int - Time - action : Action - Executed action - """ - self._action_history[time] = action - - def record_think_start_time(self) -> None: - """ - Record the start time of thinking - """ - self._start_think_time = time() - - def get_think_time(self) -> float: - """ - Get the time taken for thinking - - Returns - ------- - float - Time taken for thinking - """ - return time() - self._start_think_time + def __init__(self, agent: Agent, world_model: WorldModel): + self._agent: Agent = agent + self._world_model: WorldModel = world_model + self._time: int = 0 + self._action_history: dict[int, Action] = {} + self._heard_commands: list[Command] = [] + self._change_set: ChangeSet = ChangeSet() + self._start_think_time: float = 0.0 + + def set_time(self, time: int) -> None: + """ + Set the current time of the agent + + Parameters + ---------- + time : int + Current time + """ + self._time = time + + def get_time(self) -> int: + """ + Get the current time of the agent + + Returns + ------- + int + Current time + """ + return self._time + + def set_heard_commands(self, heard_commands: list[Command]) -> None: + """ + Set the heard commands + + Parameters + ---------- + heard_commands : list[Command] + Heard commands + """ + self._heard_commands = heard_commands + + def get_heard_commands(self) -> list[Command]: + """ + Get the heard commands + + Returns + ------- + list[Command] + Heard commands + """ + return self._heard_commands + + def get_entity_id(self) -> EntityID: + """ + Get the entity ID of the agent + + Returns + ------- + EntityID + Entity ID of the agent + """ + # TODO: Agent class should return EntityID instead of EntityID | None + return self._agent.get_entity_id() + + def get_myself(self) -> Entity | None: + """ + Get the entity of the agent + + Returns + ------- + Entity + Entity of the agent + """ + return self._world_model.get_entity(self.get_entity_id()) + + def get_position_entity_id(self) -> EntityID | None: + """ + Get the position entity ID of the agent + + Returns + ------- + EntityID + Position entity ID of the agent + """ + entity = self._world_model.get_entity(self.get_entity_id()) + if entity is None: + return None + + if isinstance(entity, Human): + return entity.get_position() + else: + return entity.get_entity_id() + + def set_change_set(self, change_set: ChangeSet) -> None: + """ + Set the change set + + Parameters + ---------- + change_set : ChangeSet + Change set + """ + self._change_set = change_set + + def get_change_set(self) -> ChangeSet: + """ + Get the change set + + Returns + ------- + ChangeSet + Change set + """ + return self._change_set + + def some_one_on_board(self) -> Human | None: + """ + Get the human if someone is on board + + Returns + ------- + Human | None + Human if someone is on board, None otherwise + """ + entity_id: EntityID = self.get_entity_id() + for entity in self._world_model.get_entities(): + if isinstance(entity, Civilian): + if entity.get_position() == entity_id: + return entity + return None + + def get_executed_action(self, time: int) -> Action | None: + """ + Get the executed action at the given time + + Parameters + ---------- + time : int + Time + """ + return self._action_history.get(time) + + def set_executed_action(self, time: int, action: Action) -> None: + """ + Set the executed action at the given time + + Parameters + ---------- + time : int + Time + action : Action + Executed action + """ + self._action_history[time] = action + + def record_think_start_time(self) -> None: + """ + Record the start time of thinking + """ + self._start_think_time = time() + + def get_think_time(self) -> float: + """ + Get the time taken for thinking + + Returns + ------- + float + Time taken for thinking + """ + return time() - self._start_think_time diff --git a/src/adf_core_python/core/agent/info/scenario_info.py b/src/adf_core_python/core/agent/info/scenario_info.py index 29f4244..6e26568 100644 --- a/src/adf_core_python/core/agent/info/scenario_info.py +++ b/src/adf_core_python/core/agent/info/scenario_info.py @@ -7,111 +7,111 @@ class Mode(IntEnum): - NON_PRECOMPUTE = 0 - PRECOMPUTED = 1 - PRECOMPUTATION = 2 + NON_PRECOMPUTE = 0 + PRECOMPUTED = 1 + PRECOMPUTATION = 2 class ScenarioInfoKeys: - KERNEL_PERCEPTION = "kernel.perception" - PERCEPTION_LOS_PRECISION_HP = "perception.los.precision.hp" - CLEAR_REPAIR_RAD = "clear.repair.rad" - FIRE_TANK_REFILL_HYDRANT_RATE = "fire.tank.refill_hydrant_rate" - SCENARIO_AGENTS_PF = "scenario.agents.pf" - SCENARIO_AGENTS_FS = "scenario.agents.fs" - VOICE_MESSAGES_SIZE = "comms.channels.0.messages.size" - FIRE_TANK_REFILL_RATE = "fire.tank.refill_rate" - KERNEL_TIMESTEPS = "kernel.timesteps" - FIRE_EXTINGUISH_MAX_SUM = "fire.extinguish.max-sum" - COMMUNICATION_CHANNELS_MAX_PLATOON = "comms.channels.max.platoon" - KERNEL_AGENTS_THINK_TIME = "kernel.agents.think-time" - FIRE_TANK_MAXIMUM = "fire.tank.maximum" - CLEAR_REPAIR_RATE = "clear.repair.rate" - KERNEL_STARTUP_CONNECT_TIME = "kernel.startup.connect-time" - KERNEL_HOST = "kernel.host" - SCENARIO_AGENTS_AT = "scenario.agents.at" - PERCEPTION_LOS_MAX_DISTANCE = "perception.los.max-distance" - SCENARIO_AGENTS_FB = "scenario.agents.fb" - SCENARIO_AGENTS_PO = "scenario.agents.po" - KERNEL_COMMUNICATION_MODEL = "kernel.communication-model" - PERCEPTION_LOS_PRECISION_DAMAGE = "perception.los.precision.damage" - SCENARIO_AGENTS_AC = "scenario.agents.ac" - COMMUNICATION_CHANNELS_MAX_OFFICE = "comms.channels.max.centre" - FIRE_EXTINGUISH_MAX_DISTANCE = "fire.extinguish.max-distance" - KERNEL_AGENTS_IGNOREUNTIL = "kernel.agents.ignoreuntil" - CLEAR_REPAIR_DISTANCE = "clear.repair.distance" - COMMUNICATION_CHANNELS_COUNT = "comms.channels.count" + KERNEL_PERCEPTION = "kernel.perception" + PERCEPTION_LOS_PRECISION_HP = "perception.los.precision.hp" + CLEAR_REPAIR_RAD = "clear.repair.rad" + FIRE_TANK_REFILL_HYDRANT_RATE = "fire.tank.refill_hydrant_rate" + SCENARIO_AGENTS_PF = "scenario.agents.pf" + SCENARIO_AGENTS_FS = "scenario.agents.fs" + VOICE_MESSAGES_SIZE = "comms.channels.0.messages.size" + FIRE_TANK_REFILL_RATE = "fire.tank.refill_rate" + KERNEL_TIMESTEPS = "kernel.timesteps" + FIRE_EXTINGUISH_MAX_SUM = "fire.extinguish.max-sum" + COMMUNICATION_CHANNELS_MAX_PLATOON = "comms.channels.max.platoon" + KERNEL_AGENTS_THINK_TIME = "kernel.agents.think-time" + FIRE_TANK_MAXIMUM = "fire.tank.maximum" + CLEAR_REPAIR_RATE = "clear.repair.rate" + KERNEL_STARTUP_CONNECT_TIME = "kernel.startup.connect-time" + KERNEL_HOST = "kernel.host" + SCENARIO_AGENTS_AT = "scenario.agents.at" + PERCEPTION_LOS_MAX_DISTANCE = "perception.los.max-distance" + SCENARIO_AGENTS_FB = "scenario.agents.fb" + SCENARIO_AGENTS_PO = "scenario.agents.po" + KERNEL_COMMUNICATION_MODEL = "kernel.communication-model" + PERCEPTION_LOS_PRECISION_DAMAGE = "perception.los.precision.damage" + SCENARIO_AGENTS_AC = "scenario.agents.ac" + COMMUNICATION_CHANNELS_MAX_OFFICE = "comms.channels.max.centre" + FIRE_EXTINGUISH_MAX_DISTANCE = "fire.extinguish.max-distance" + KERNEL_AGENTS_IGNOREUNTIL = "kernel.agents.ignoreuntil" + CLEAR_REPAIR_DISTANCE = "clear.repair.distance" + COMMUNICATION_CHANNELS_COUNT = "comms.channels.count" class ScenarioInfo: - def __init__(self, config: Config, mode: Mode): - """ - Constructor - - Parameters - ---------- - config : Config - Configuration - mode : Mode - Mode of the scenario - """ - self._config: Config = config - self._mode: Mode = mode - - def set_config(self, config: Config) -> None: - """ - Set the configuration - - Parameters - ---------- - config : Config - Configuration - """ - self._config = config - - def get_config(self) -> Config: - """ - Get the configuration - - Returns - ------- - Config - Configuration - """ - return self._config - - def get_mode(self) -> Mode: - """ - Get the mode of the scenario - - Returns - ------- - Mode - Mode of the scenario - """ - return self._mode - - def get_value(self, key: str, default: T) -> T: - """ - Get the value of the configuration - - Parameters - ---------- - key : str - Key of the configuration - default : Any - Default value of the configuration - - Returns - ------- - Any - Value of the configuration - """ - value = self._config.get_value(key, default) - if not isinstance(value, type(default)): - try: - return type(default)(value) # type: ignore - except (ValueError, TypeError): - # 型変換に失敗した場合はそのままデフォルト値を返す - return default - return value + def __init__(self, config: Config, mode: Mode): + """ + Constructor + + Parameters + ---------- + config : Config + Configuration + mode : Mode + Mode of the scenario + """ + self._config: Config = config + self._mode: Mode = mode + + def set_config(self, config: Config) -> None: + """ + Set the configuration + + Parameters + ---------- + config : Config + Configuration + """ + self._config = config + + def get_config(self) -> Config: + """ + Get the configuration + + Returns + ------- + Config + Configuration + """ + return self._config + + def get_mode(self) -> Mode: + """ + Get the mode of the scenario + + Returns + ------- + Mode + Mode of the scenario + """ + return self._mode + + def get_value(self, key: str, default: T) -> T: + """ + Get the value of the configuration + + Parameters + ---------- + key : str + Key of the configuration + default : Any + Default value of the configuration + + Returns + ------- + Any + Value of the configuration + """ + value = self._config.get_value(key, default) + if not isinstance(value, type(default)): + try: + return type(default)(value) # type: ignore + except (ValueError, TypeError): + # 型変換に失敗した場合はそのままデフォルト値を返す + return default + return value diff --git a/src/adf_core_python/core/agent/info/world_info.py b/src/adf_core_python/core/agent/info/world_info.py index acea5da..0fce3a7 100644 --- a/src/adf_core_python/core/agent/info/world_info.py +++ b/src/adf_core_python/core/agent/info/world_info.py @@ -9,206 +9,204 @@ class WorldInfo: - def __init__(self, world_model: WorldModel): - self._world_model: WorldModel = world_model - self._time: int = 0 - self._is_run_rollback: bool = False - self._rollback: dict[EntityID, dict[int, dict[int, Any]]] = {} - self._change_set: ChangeSet - - def get_world_model(self) -> WorldModel: - """ - Get the world model - - Returns - ------- - WorldModel - World model - """ - return self._world_model - - def set_change_set(self, change_set: ChangeSet) -> None: - """ - Set the change set - - Parameters - ---------- - change_set : ChangeSet - Change set - """ - self._change_set = change_set - - def get_entity(self, entity_id: EntityID) -> Optional[Entity]: - """ - Get the entity - - Parameters - ---------- - entity_id : EntityID - Entity ID - - Returns - ------- - Optional[Entity] - Entity - """ - return self._world_model.get_entity(entity_id) - - def get_entity_ids_of_types( - self, entity_types: list[type[Entity]] - ) -> list[EntityID]: - """ - Get the entity IDs of the specified types - - Parameters - ---------- - entity_types : list[type[Entity]] - List of entity types - - Returns - ------- - list[EntityID] - Entity IDs - """ - entity_ids: list[EntityID] = [] - for entity in self._world_model.get_entities(): - if any(isinstance(entity, entity_type) for entity_type in entity_types): - entity_ids.append(entity.get_entity_id()) - - return entity_ids - - def get_entities_of_types(self, entity_types: list[type[Entity]]) -> list[Entity]: - """ - Get the entities of the specified types - - Parameters - ---------- - entity_types : list[type[Entity]] - List of entity types - - Returns - ------- - list[Entity] - Entities - """ - entities: list[Entity] = [] - for entity in self._world_model.get_entities(): - if any(isinstance(entity, entity_type) for entity_type in entity_types): - entities.append(entity) - - return entities - - def get_distance(self, entity_id1: EntityID, entity_id2: EntityID) -> float: - """ - Get the distance between two entities - - Parameters - ---------- - entity_id1 : EntityID - Entity ID 1 - entity_id2 : EntityID - Entity ID 2 - - Returns - ------- - float - Distance - - Raises - ------ - ValueError - If one or both entities are invalid or the location is invalid - """ - entity1: Optional[Entity] = self.get_entity(entity_id1) - entity2: Optional[Entity] = self.get_entity(entity_id2) - if entity1 is None or entity2 is None: - raise ValueError( - f"One or both entities are invalid: entity_id1={entity_id1}, entity_id2={entity_id2}, entity1={entity1}, entity2={entity2}" - ) - - location1_x, location1_y = entity1.get_x(), entity1.get_y() - location2_x, location2_y = entity2.get_x(), entity2.get_y() - if ( - location1_x is None - or location1_y is None - or location2_x is None - or location2_y is None - ): - raise ValueError( - f"Invalid location: entity_id1={entity_id1}, entity_id2={entity_id2}, location1_x={location1_x}, location1_y={location1_y}, location2_x={location2_x}, location2_y={location2_y}" - ) - - distance: float = ( - (location1_x - location2_x) ** 2 + (location1_y - location2_y) ** 2 - ) ** 0.5 - - return distance - - def get_entity_position(self, entity_id: EntityID) -> EntityID | None: - """ - Get the entity position - - Parameters - ---------- - entity_id : EntityID - Entity ID - - Returns - ------- - EntityID - Entity position - - Raises - ------ - ValueError - If the entity is invalid - """ - entity = self.get_entity(entity_id) - if entity is None: - raise ValueError(f"Invalid entity: entity_id={entity_id}, entity={entity}") - if isinstance(entity, Area): - return entity.get_entity_id() - if isinstance(entity, Human): - return entity.get_position() - if isinstance(entity, Blockade): - return entity.get_position() - raise ValueError(f"Invalid entity type: entity_id={entity_id}, entity={entity}") - - def get_change_set(self) -> ChangeSet: - """ - Get the change set - - Returns - ------- - ChangeSet - Change set - """ - return self._change_set - - def get_blockades(self, area: Area) -> set[Blockade]: - """ - Get the blockades in the area - - Returns - ------- - ChangeSet - Blockade - """ - blockades = set() - if blockade_entity_ids := area.get_blockades(): - for blockade_entity_id in blockade_entity_ids: - blockades_entity = self.get_entity(blockade_entity_id) - if isinstance(blockades_entity, Blockade): - blockades.add(blockades_entity) - return blockades - - def add_entity(self, entity: Entity) -> None: - """ - Add the entity - - Parameters - ---------- - entity : Entity - Entity - """ - self._world_model.add_entity(entity) + def __init__(self, world_model: WorldModel): + self._world_model: WorldModel = world_model + self._time: int = 0 + self._is_run_rollback: bool = False + self._rollback: dict[EntityID, dict[int, dict[int, Any]]] = {} + self._change_set: ChangeSet + + def get_world_model(self) -> WorldModel: + """ + Get the world model + + Returns + ------- + WorldModel + World model + """ + return self._world_model + + def set_change_set(self, change_set: ChangeSet) -> None: + """ + Set the change set + + Parameters + ---------- + change_set : ChangeSet + Change set + """ + self._change_set = change_set + + def get_entity(self, entity_id: EntityID) -> Optional[Entity]: + """ + Get the entity + + Parameters + ---------- + entity_id : EntityID + Entity ID + + Returns + ------- + Optional[Entity] + Entity + """ + return self._world_model.get_entity(entity_id) + + def get_entity_ids_of_types(self, entity_types: list[type[Entity]]) -> list[EntityID]: + """ + Get the entity IDs of the specified types + + Parameters + ---------- + entity_types : list[type[Entity]] + List of entity types + + Returns + ------- + list[EntityID] + Entity IDs + """ + entity_ids: list[EntityID] = [] + for entity in self._world_model.get_entities(): + if any(isinstance(entity, entity_type) for entity_type in entity_types): + entity_ids.append(entity.get_entity_id()) + + return entity_ids + + def get_entities_of_types(self, entity_types: list[type[Entity]]) -> list[Entity]: + """ + Get the entities of the specified types + + Parameters + ---------- + entity_types : list[type[Entity]] + List of entity types + + Returns + ------- + list[Entity] + Entities + """ + entities: list[Entity] = [] + for entity in self._world_model.get_entities(): + if any(isinstance(entity, entity_type) for entity_type in entity_types): + entities.append(entity) + + return entities + + def get_distance(self, entity_id1: EntityID, entity_id2: EntityID) -> float: + """ + Get the distance between two entities + + Parameters + ---------- + entity_id1 : EntityID + Entity ID 1 + entity_id2 : EntityID + Entity ID 2 + + Returns + ------- + float + Distance + + Raises + ------ + ValueError + If one or both entities are invalid or the location is invalid + """ + entity1: Optional[Entity] = self.get_entity(entity_id1) + entity2: Optional[Entity] = self.get_entity(entity_id2) + if entity1 is None or entity2 is None: + raise ValueError( + f"One or both entities are invalid: entity_id1={entity_id1}, entity_id2={entity_id2}, entity1={entity1}, entity2={entity2}" + ) + + location1_x, location1_y = entity1.get_x(), entity1.get_y() + location2_x, location2_y = entity2.get_x(), entity2.get_y() + if ( + location1_x is None + or location1_y is None + or location2_x is None + or location2_y is None + ): + raise ValueError( + f"Invalid location: entity_id1={entity_id1}, entity_id2={entity_id2}, location1_x={location1_x}, location1_y={location1_y}, location2_x={location2_x}, location2_y={location2_y}" + ) + + distance: float = ( + (location1_x - location2_x) ** 2 + (location1_y - location2_y) ** 2 + ) ** 0.5 + + return distance + + def get_entity_position(self, entity_id: EntityID) -> EntityID | None: + """ + Get the entity position + + Parameters + ---------- + entity_id : EntityID + Entity ID + + Returns + ------- + EntityID + Entity position + + Raises + ------ + ValueError + If the entity is invalid + """ + entity = self.get_entity(entity_id) + if entity is None: + raise ValueError(f"Invalid entity: entity_id={entity_id}, entity={entity}") + if isinstance(entity, Area): + return entity.get_entity_id() + if isinstance(entity, Human): + return entity.get_position() + if isinstance(entity, Blockade): + return entity.get_position() + raise ValueError(f"Invalid entity type: entity_id={entity_id}, entity={entity}") + + def get_change_set(self) -> ChangeSet: + """ + Get the change set + + Returns + ------- + ChangeSet + Change set + """ + return self._change_set + + def get_blockades(self, area: Area) -> set[Blockade]: + """ + Get the blockades in the area + + Returns + ------- + ChangeSet + Blockade + """ + blockades = set() + if blockade_entity_ids := area.get_blockades(): + for blockade_entity_id in blockade_entity_ids: + blockades_entity = self.get_entity(blockade_entity_id) + if isinstance(blockades_entity, Blockade): + blockades.add(blockades_entity) + return blockades + + def add_entity(self, entity: Entity) -> None: + """ + Add the entity + + Parameters + ---------- + entity : Entity + Entity + """ + self._world_model.add_entity(entity) diff --git a/src/adf_core_python/core/agent/module/module_manager.py b/src/adf_core_python/core/agent/module/module_manager.py index 96c506b..6eafb42 100644 --- a/src/adf_core_python/core/agent/module/module_manager.py +++ b/src/adf_core_python/core/agent/module/module_manager.py @@ -7,14 +7,14 @@ from adf_core_python.core.component.centralized.command_executor import CommandExecutor from adf_core_python.core.component.centralized.command_picker import CommandPicker from adf_core_python.core.component.communication.channel_subscriber import ( - ChannelSubscriber, + ChannelSubscriber, ) from adf_core_python.core.component.communication.message_coordinator import ( - MessageCoordinator, + MessageCoordinator, ) from adf_core_python.core.component.module.abstract_module import AbstractModule from adf_core_python.core.gateway.component.module.gateway_abstract_module import ( - GatewayAbstractModule, + GatewayAbstractModule, ) from adf_core_python.core.gateway.gateway_agent import GatewayAgent from adf_core_python.core.gateway.gateway_module import GatewayModule @@ -22,248 +22,248 @@ from adf_core_python.core.logger.logger import get_agent_logger if TYPE_CHECKING: - from adf_core_python.core.agent.config.module_config import ModuleConfig - 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 ScenarioInfo - from adf_core_python.core.agent.info.world_info import WorldInfo + from adf_core_python.core.agent.config.module_config import ModuleConfig + 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 ScenarioInfo + from adf_core_python.core.agent.info.world_info import WorldInfo class ModuleManager: - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_config: ModuleConfig, - develop_data: DevelopData, - gateway_agent: Optional[GatewayAgent] = None, - ) -> None: - self._agent_info = agent_info - self._world_info = world_info - self._scenario_info = scenario_info - self._module_config = module_config - self._develop_data = develop_data - self._gateway_agent = gateway_agent - self._modules: dict[str, AbstractModule] = {} - self._actions: dict[str, ExtendAction] = {} - - self._executors: dict[str, Any] = {} - self._pickers: dict[str, Any] = {} - self._channel_subscribers: dict[str, Any] = {} - self._message_coordinators: dict[str, Any] = {} - - self._module_dict: ModuleDict = ModuleDict() - - self._logger = get_agent_logger( - f"{self.__class__.__module__}.{self.__class__.__qualname__}", + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_config: ModuleConfig, + develop_data: DevelopData, + gateway_agent: Optional[GatewayAgent] = None, + ) -> None: + self._agent_info = agent_info + self._world_info = world_info + self._scenario_info = scenario_info + self._module_config = module_config + self._develop_data = develop_data + self._gateway_agent = gateway_agent + self._modules: dict[str, AbstractModule] = {} + self._actions: dict[str, ExtendAction] = {} + + self._executors: dict[str, Any] = {} + self._pickers: dict[str, Any] = {} + self._channel_subscribers: dict[str, Any] = {} + self._message_coordinators: dict[str, Any] = {} + + self._module_dict: ModuleDict = ModuleDict() + + self._logger = get_agent_logger( + f"{self.__class__.__module__}.{self.__class__.__qualname__}", + self._agent_info, + ) + + def get_module( + self, module_name: str, default_module_class_name: str + ) -> AbstractModule: + instance = self._modules.get(module_name) + if instance is not None: + return instance + + class_name = self._module_config.get_value(module_name) + if class_name is None: + self._logger.warning( + f"Module {module_name} not found in config. Using default module {default_module_class_name}" + ) + + if class_name is not None: + try: + module_class: type = self._load_module(class_name) + if issubclass(module_class, AbstractModule): + instance = module_class( self._agent_info, + self._world_info, + self._scenario_info, + self, + self._develop_data, + ) + self._modules[module_name] = instance + return instance + except ModuleNotFoundError: + self._logger.warning( + f"Module {module_name} not found in python. " + f"If gateway flag is active, using module {module_name} in java" ) - def get_module( - self, module_name: str, default_module_class_name: str - ) -> AbstractModule: - instance = self._modules.get(module_name) - if instance is not None: - return instance - - class_name = self._module_config.get_value(module_name) - if class_name is None: - self._logger.warning( - f"Module {module_name} not found in config. Using default module {default_module_class_name}" - ) - - if class_name is not None: - try: - module_class: type = self._load_module(class_name) - if issubclass(module_class, AbstractModule): - instance = module_class( - self._agent_info, - self._world_info, - self._scenario_info, - self, - self._develop_data, - ) - self._modules[module_name] = instance - return instance - except ModuleNotFoundError: - self._logger.warning( - f"Module {module_name} not found in python. " - f"If gateway flag is active, using module {module_name} in java" - ) - - if isinstance(self._gateway_agent, GatewayAgent): - gateway_module = GatewayModule(self._gateway_agent) - java_class_name = gateway_module.initialize(module_name, "") - class_name = self._module_dict[java_class_name] - if class_name is not None: - module_class = self._load_module(class_name) - if issubclass(module_class, GatewayAbstractModule): - instance = module_class( - self._agent_info, - self._world_info, - self._scenario_info, - self, - self._develop_data, - gateway_module, - ) - self._modules[module_name] = instance - return instance - - class_name = default_module_class_name + if isinstance(self._gateway_agent, GatewayAgent): + gateway_module = GatewayModule(self._gateway_agent) + java_class_name = gateway_module.initialize(module_name, "") + class_name = self._module_dict[java_class_name] if class_name is not None: - module_class = self._load_module(class_name) - if issubclass(module_class, AbstractModule): - instance = module_class( - self._agent_info, - self._world_info, - self._scenario_info, - self, - self._develop_data, - ) - self._modules[module_name] = instance - return instance - - raise RuntimeError(f"Module {class_name} is not a subclass of AbstractModule") - - def get_extend_action( - self, action_name: str, default_action_class_name: str - ) -> ExtendAction: - class_name = self._module_config.get_value(action_name) - if class_name is None: - self._logger.warning( - f"Action {action_name} not found in config. Using default action {default_action_class_name}" - ) - class_name = default_action_class_name - - action_class: type = self._load_module(class_name) - - instance = self._actions.get(action_name) - if instance is not None: - return instance - - if issubclass(action_class, ExtendAction): - instance = action_class( - self._agent_info, - self._world_info, - self._scenario_info, - self, - self._develop_data, - ) - self._actions[action_name] = instance - return instance - - raise RuntimeError(f"Action {class_name} is not a subclass of ExtendAction") - - def get_channel_subscriber( - self, channel_subscriber_name: str, default_channel_subscriber_name: str - ) -> ChannelSubscriber: - class_name = self._module_config.get_value(channel_subscriber_name) - if class_name is None: - self._logger.warning( - f"Channel subscriber {channel_subscriber_name} not found in config. Using default channel subscriber {default_channel_subscriber_name}" - ) - class_name = default_channel_subscriber_name - - channel_subscriber_class: type = self._load_module(class_name) - - instance = self._channel_subscribers.get(channel_subscriber_name) - if instance is not None: - return instance - - if issubclass(channel_subscriber_class, ChannelSubscriber): - instance = channel_subscriber_class() - self._channel_subscribers[channel_subscriber_name] = instance - return instance - - raise RuntimeError( - f"Channel subscriber {class_name} is not a subclass of ChannelSubscriber" - ) - - def get_message_coordinator( - self, message_coordinator_name: str, default_message_coordinator_name: str - ) -> MessageCoordinator: - class_name = self._module_config.get_value(message_coordinator_name) - if class_name is None: - self._logger.warning( - f"Channel subscriber {message_coordinator_name} not found in config. Using default channel subscriber {default_message_coordinator_name}" + module_class = self._load_module(class_name) + if issubclass(module_class, GatewayAbstractModule): + instance = module_class( + self._agent_info, + self._world_info, + self._scenario_info, + self, + self._develop_data, + gateway_module, ) - class_name = default_message_coordinator_name - - message_coordinator_class: type = self._load_module(class_name) - - instance = self._message_coordinators.get(message_coordinator_name) - if instance is not None: - return instance - - if issubclass(message_coordinator_class, MessageCoordinator): - instance = message_coordinator_class() - self._message_coordinators[message_coordinator_name] = instance + self._modules[module_name] = instance return instance - raise RuntimeError( - f"Message coordinator {class_name} is not a subclass of MessageCoordinator" + class_name = default_module_class_name + if class_name is not None: + module_class = self._load_module(class_name) + if issubclass(module_class, AbstractModule): + instance = module_class( + self._agent_info, + self._world_info, + self._scenario_info, + self, + self._develop_data, ) + self._modules[module_name] = instance + return instance + + raise RuntimeError(f"Module {class_name} is not a subclass of AbstractModule") + + def get_extend_action( + self, action_name: str, default_action_class_name: str + ) -> ExtendAction: + class_name = self._module_config.get_value(action_name) + if class_name is None: + self._logger.warning( + f"Action {action_name} not found in config. Using default action {default_action_class_name}" + ) + class_name = default_action_class_name + + action_class: type = self._load_module(class_name) + + instance = self._actions.get(action_name) + if instance is not None: + return instance + + if issubclass(action_class, ExtendAction): + instance = action_class( + self._agent_info, + self._world_info, + self._scenario_info, + self, + self._develop_data, + ) + self._actions[action_name] = instance + return instance + + raise RuntimeError(f"Action {class_name} is not a subclass of ExtendAction") + + def get_channel_subscriber( + self, channel_subscriber_name: str, default_channel_subscriber_name: str + ) -> ChannelSubscriber: + class_name = self._module_config.get_value(channel_subscriber_name) + if class_name is None: + self._logger.warning( + f"Channel subscriber {channel_subscriber_name} not found in config. Using default channel subscriber {default_channel_subscriber_name}" + ) + class_name = default_channel_subscriber_name + + channel_subscriber_class: type = self._load_module(class_name) + + instance = self._channel_subscribers.get(channel_subscriber_name) + if instance is not None: + return instance + + if issubclass(channel_subscriber_class, ChannelSubscriber): + instance = channel_subscriber_class() + self._channel_subscribers[channel_subscriber_name] = instance + return instance + + raise RuntimeError( + f"Channel subscriber {class_name} is not a subclass of ChannelSubscriber" + ) + + def get_message_coordinator( + self, message_coordinator_name: str, default_message_coordinator_name: str + ) -> MessageCoordinator: + class_name = self._module_config.get_value(message_coordinator_name) + if class_name is None: + self._logger.warning( + f"Channel subscriber {message_coordinator_name} not found in config. Using default channel subscriber {default_message_coordinator_name}" + ) + class_name = default_message_coordinator_name + + message_coordinator_class: type = self._load_module(class_name) + + instance = self._message_coordinators.get(message_coordinator_name) + if instance is not None: + return instance + + if issubclass(message_coordinator_class, MessageCoordinator): + instance = message_coordinator_class() + self._message_coordinators[message_coordinator_name] = instance + return instance + + raise RuntimeError( + f"Message coordinator {class_name} is not a subclass of MessageCoordinator" + ) + + def get_command_executor( + self, command_executor_name: str, default_command_executor_name: str + ) -> CommandExecutor: + class_name = self._module_config.get_value(command_executor_name) + if class_name is None: + self._logger.warning( + f"Command executor {command_executor_name} not found in config. Using default command executor {default_command_executor_name}" + ) + class_name = default_command_executor_name + + command_executor_class: type = self._load_module(class_name) + + instance = self._executors.get(command_executor_name) + if instance is not None: + return instance + + if issubclass(command_executor_class, CommandExecutor): + instance = command_executor_class( + self._agent_info, + self._world_info, + self._scenario_info, + self, + self._develop_data, + ) + self._executors[command_executor_name] = instance + return instance + + raise RuntimeError(f"Command executor {class_name} is not a subclass of object") + + def get_command_picker( + self, command_picker_name: str, default_command_picker_name: str + ) -> CommandPicker: + class_name = self._module_config.get_value(command_picker_name) + if class_name is None: + self._logger.warning( + f"Command picker {command_picker_name} not found in config. Using default command picker {default_command_picker_name}" + ) + class_name = default_command_picker_name + + command_picker_class: type = self._load_module(class_name) + + instance = self._pickers.get(command_picker_name) + if instance is not None: + return instance + + if issubclass(command_picker_class, CommandPicker): + instance = command_picker_class( + self._agent_info, + self._world_info, + self._scenario_info, + self, + self._develop_data, + ) + self._pickers[command_picker_name] = instance + return instance - def get_command_executor( - self, command_executor_name: str, default_command_executor_name: str - ) -> CommandExecutor: - class_name = self._module_config.get_value(command_executor_name) - if class_name is None: - self._logger.warning( - f"Command executor {command_executor_name} not found in config. Using default command executor {default_command_executor_name}" - ) - class_name = default_command_executor_name - - command_executor_class: type = self._load_module(class_name) - - instance = self._executors.get(command_executor_name) - if instance is not None: - return instance - - if issubclass(command_executor_class, CommandExecutor): - instance = command_executor_class( - self._agent_info, - self._world_info, - self._scenario_info, - self, - self._develop_data, - ) - self._executors[command_executor_name] = instance - return instance - - raise RuntimeError(f"Command executor {class_name} is not a subclass of object") - - def get_command_picker( - self, command_picker_name: str, default_command_picker_name: str - ) -> CommandPicker: - class_name = self._module_config.get_value(command_picker_name) - if class_name is None: - self._logger.warning( - f"Command picker {command_picker_name} not found in config. Using default command picker {default_command_picker_name}" - ) - class_name = default_command_picker_name - - command_picker_class: type = self._load_module(class_name) - - instance = self._pickers.get(command_picker_name) - if instance is not None: - return instance - - if issubclass(command_picker_class, CommandPicker): - instance = command_picker_class( - self._agent_info, - self._world_info, - self._scenario_info, - self, - self._develop_data, - ) - self._pickers[command_picker_name] = instance - return instance - - raise RuntimeError(f"Command picker {class_name} is not a subclass of object") + raise RuntimeError(f"Command picker {class_name} is not a subclass of object") - def _load_module(self, class_name: str) -> type: - module_name, module_class_name = class_name.rsplit(".", 1) - module = importlib.import_module(module_name) - return getattr(module, module_class_name) + def _load_module(self, class_name: str) -> type: + module_name, module_class_name = class_name.rsplit(".", 1) + module = importlib.import_module(module_name) + return getattr(module, module_class_name) diff --git a/src/adf_core_python/core/agent/office/office.py b/src/adf_core_python/core/agent/office/office.py index ea9a3b8..12b2a8f 100644 --- a/src/adf_core_python/core/agent/office/office.py +++ b/src/adf_core_python/core/agent/office/office.py @@ -14,120 +14,120 @@ class Office(Agent): - def __init__( - self, - tactics_center: TacticsCenter, - team_name: str, - is_precompute: bool, - is_debug: bool, - data_storage_name: str, - module_config: ModuleConfig, - develop_data: DevelopData, - finish_post_connect_event: Event, - gateway_agent: Optional[GatewayAgent], - ) -> None: - super().__init__( - is_precompute, - self.__class__.__qualname__, - is_debug, - team_name, - data_storage_name, - module_config, - develop_data, - finish_post_connect_event, - gateway_agent, - ) - self._tactics_center = tactics_center - self._team_name = team_name - self._is_precompute = is_precompute - self._is_debug = is_debug - self._data_storage_name = data_storage_name - self._module_config = module_config - self._develop_data = develop_data + def __init__( + self, + tactics_center: TacticsCenter, + team_name: str, + is_precompute: bool, + is_debug: bool, + data_storage_name: str, + module_config: ModuleConfig, + develop_data: DevelopData, + finish_post_connect_event: Event, + gateway_agent: Optional[GatewayAgent], + ) -> None: + super().__init__( + is_precompute, + self.__class__.__qualname__, + is_debug, + team_name, + data_storage_name, + module_config, + develop_data, + finish_post_connect_event, + gateway_agent, + ) + self._tactics_center = tactics_center + self._team_name = team_name + self._is_precompute = is_precompute + self._is_debug = is_debug + self._data_storage_name = data_storage_name + self._module_config = module_config + self._develop_data = develop_data - def post_connect(self) -> None: - super().post_connect() - self.precompute_data: PrecomputeData = PrecomputeData(self._data_storage_name) + def post_connect(self) -> None: + super().post_connect() + self.precompute_data: PrecomputeData = PrecomputeData(self._data_storage_name) - self._logger = get_agent_logger( - f"{self.__class__.__module__}.{self.__class__.__qualname__}", - self._agent_info, - ) + self._logger = get_agent_logger( + f"{self.__class__.__module__}.{self.__class__.__qualname__}", + self._agent_info, + ) - self._module_manager: ModuleManager = ModuleManager( - self._agent_info, - self._world_info, - self._scenario_info, - self._module_config, - self._develop_data, - ) + self._module_manager: ModuleManager = ModuleManager( + self._agent_info, + self._world_info, + self._scenario_info, + self._module_config, + self._develop_data, + ) - self._message_manager.set_channel_subscriber( - self._module_manager.get_channel_subscriber( - "MessageManager.PlatoonChannelSubscriber", - "adf_core_python.implement.module.communication.default_channel_subscriber.DefaultChannelSubscriber", - ) - ) - self._message_manager.set_message_coordinator( - self._module_manager.get_message_coordinator( - "MessageManager.PlatoonMessageCoordinator", - "adf_core_python.implement.module.communication.default_message_coordinator.DefaultMessageCoordinator", - ) - ) + self._message_manager.set_channel_subscriber( + self._module_manager.get_channel_subscriber( + "MessageManager.PlatoonChannelSubscriber", + "adf_core_python.implement.module.communication.default_channel_subscriber.DefaultChannelSubscriber", + ) + ) + self._message_manager.set_message_coordinator( + self._module_manager.get_message_coordinator( + "MessageManager.PlatoonMessageCoordinator", + "adf_core_python.implement.module.communication.default_message_coordinator.DefaultMessageCoordinator", + ) + ) - self._tactics_center.initialize( - self._agent_info, - self._world_info, - self._scenario_info, - self._module_manager, - self._precompute_data, - self._message_manager, - self._develop_data, - ) - - match self._scenario_info.get_mode(): - case Mode.PRECOMPUTATION: - 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: - 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, - self._world_info, - self._scenario_info, - self._module_manager, - self.precompute_data, - self._develop_data, - ) + self._tactics_center.initialize( + self._agent_info, + self._world_info, + self._scenario_info, + self._module_manager, + self._precompute_data, + self._message_manager, + self._develop_data, + ) - def think(self) -> None: - self._tactics_center.think( - self._agent_info, - self._world_info, - self._scenario_info, - self._module_manager, - self._precompute_data, - self._message_manager, - self._develop_data, + match self._scenario_info.get_mode(): + case Mode.PRECOMPUTATION: + 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, ) - self.send_msg( - ActionRest() - .get_command(self.agent_id, self._agent_info.get_time()) - .to_message_proto() + case Mode.PRECOMPUTED: + 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, + self._world_info, + self._scenario_info, + self._module_manager, + self.precompute_data, + self._develop_data, + ) + + def think(self) -> None: + self._tactics_center.think( + self._agent_info, + self._world_info, + self._scenario_info, + self._module_manager, + self._precompute_data, + self._message_manager, + self._develop_data, + ) + self.send_msg( + ActionRest() + .get_command(self.agent_id, self._agent_info.get_time()) + .to_message_proto() + ) diff --git a/src/adf_core_python/core/agent/office/office_ambulance.py b/src/adf_core_python/core/agent/office/office_ambulance.py index 1df7e5e..6653faa 100644 --- a/src/adf_core_python/core/agent/office/office_ambulance.py +++ b/src/adf_core_python/core/agent/office/office_ambulance.py @@ -11,32 +11,32 @@ class OfficeAmbulance(Office): - def __init__( - self, - tactics_center: TacticsCenter, - team_name: str, - is_precompute: bool, - is_debug: bool, - data_storage_name: str, - module_config: ModuleConfig, - develop_data: DevelopData, - finish_post_connect_event: Event, - gateway_agent: Optional[GatewayAgent], - ) -> None: - super().__init__( - tactics_center, - team_name, - is_precompute, - is_debug, - data_storage_name, - module_config, - develop_data, - finish_post_connect_event, - gateway_agent, - ) + def __init__( + self, + tactics_center: TacticsCenter, + team_name: str, + is_precompute: bool, + is_debug: bool, + data_storage_name: str, + module_config: ModuleConfig, + develop_data: DevelopData, + finish_post_connect_event: Event, + gateway_agent: Optional[GatewayAgent], + ) -> None: + super().__init__( + tactics_center, + team_name, + is_precompute, + is_debug, + data_storage_name, + module_config, + develop_data, + finish_post_connect_event, + gateway_agent, + ) - def precompute(self) -> None: - pass + def precompute(self) -> None: + pass - def get_requested_entities(self) -> list[EntityURN]: - return [EntityURN.AMBULANCE_CENTER] + def get_requested_entities(self) -> list[EntityURN]: + return [EntityURN.AMBULANCE_CENTER] diff --git a/src/adf_core_python/core/agent/office/office_fire.py b/src/adf_core_python/core/agent/office/office_fire.py index 766e35a..3ec3237 100644 --- a/src/adf_core_python/core/agent/office/office_fire.py +++ b/src/adf_core_python/core/agent/office/office_fire.py @@ -11,29 +11,29 @@ class OfficeFire(Office): - def __init__( - self, - tactics_center: TacticsCenter, - team_name: str, - is_precompute: bool, - is_debug: bool, - data_storage_name: str, - module_config: ModuleConfig, - develop_data: DevelopData, - finish_post_connect_event: Event, - gateway_agent: Optional[GatewayAgent], - ) -> None: - super().__init__( - tactics_center, - team_name, - is_precompute, - is_debug, - data_storage_name, - module_config, - develop_data, - finish_post_connect_event, - gateway_agent, - ) + def __init__( + self, + tactics_center: TacticsCenter, + team_name: str, + is_precompute: bool, + is_debug: bool, + data_storage_name: str, + module_config: ModuleConfig, + develop_data: DevelopData, + finish_post_connect_event: Event, + gateway_agent: Optional[GatewayAgent], + ) -> None: + super().__init__( + tactics_center, + team_name, + is_precompute, + is_debug, + data_storage_name, + module_config, + develop_data, + finish_post_connect_event, + gateway_agent, + ) - def get_requested_entities(self) -> list[EntityURN]: - return [EntityURN.FIRE_STATION] + def get_requested_entities(self) -> list[EntityURN]: + return [EntityURN.FIRE_STATION] diff --git a/src/adf_core_python/core/agent/office/office_police.py b/src/adf_core_python/core/agent/office/office_police.py index 67d4cc3..0aada9d 100644 --- a/src/adf_core_python/core/agent/office/office_police.py +++ b/src/adf_core_python/core/agent/office/office_police.py @@ -11,29 +11,29 @@ class OfficePolice(Office): - def __init__( - self, - tactics_center: TacticsCenter, - team_name: str, - is_precompute: bool, - is_debug: bool, - data_storage_name: str, - module_config: ModuleConfig, - develop_data: DevelopData, - finish_post_connect_event: Event, - gateway_agent: Optional[GatewayAgent], - ) -> None: - super().__init__( - tactics_center, - team_name, - is_precompute, - is_debug, - data_storage_name, - module_config, - develop_data, - finish_post_connect_event, - gateway_agent, - ) + def __init__( + self, + tactics_center: TacticsCenter, + team_name: str, + is_precompute: bool, + is_debug: bool, + data_storage_name: str, + module_config: ModuleConfig, + develop_data: DevelopData, + finish_post_connect_event: Event, + gateway_agent: Optional[GatewayAgent], + ) -> None: + super().__init__( + tactics_center, + team_name, + is_precompute, + is_debug, + data_storage_name, + module_config, + develop_data, + finish_post_connect_event, + gateway_agent, + ) - def get_requested_entities(self) -> list[EntityURN]: - return [EntityURN.POLICE_OFFICE] + def get_requested_entities(self) -> list[EntityURN]: + return [EntityURN.POLICE_OFFICE] diff --git a/src/adf_core_python/core/agent/platoon/platoon.py b/src/adf_core_python/core/agent/platoon/platoon.py index 8e9788c..0f56dfd 100644 --- a/src/adf_core_python/core/agent/platoon/platoon.py +++ b/src/adf_core_python/core/agent/platoon/platoon.py @@ -14,124 +14,124 @@ class Platoon(Agent): - def __init__( - self, - tactics_agent: TacticsAgent, - team_name: str, - is_precompute: bool, - is_debug: bool, - data_storage_name: str, - module_config: ModuleConfig, - develop_data: DevelopData, - finish_post_connect_event: Event, - gateway_agent: Optional[GatewayAgent], - ) -> None: - super().__init__( - is_precompute, - self.__class__.__qualname__, - is_debug, - team_name, - data_storage_name, - module_config, - develop_data, - finish_post_connect_event, - gateway_agent, - ) - self._tactics_agent = tactics_agent - self._team_name = team_name - self._is_precompute = is_precompute - self._is_debug = is_debug - self._data_storage_name = data_storage_name - self._module_config = module_config - self._develop_data = develop_data - self._gateway_agent = gateway_agent + def __init__( + self, + tactics_agent: TacticsAgent, + team_name: str, + is_precompute: bool, + is_debug: bool, + data_storage_name: str, + module_config: ModuleConfig, + develop_data: DevelopData, + finish_post_connect_event: Event, + gateway_agent: Optional[GatewayAgent], + ) -> None: + super().__init__( + is_precompute, + self.__class__.__qualname__, + is_debug, + team_name, + data_storage_name, + module_config, + develop_data, + finish_post_connect_event, + gateway_agent, + ) + self._tactics_agent = tactics_agent + self._team_name = team_name + self._is_precompute = is_precompute + self._is_debug = is_debug + self._data_storage_name = data_storage_name + self._module_config = module_config + self._develop_data = develop_data + self._gateway_agent = gateway_agent - def post_connect(self) -> None: - super().post_connect() - self.precompute_data: PrecomputeData = PrecomputeData(self._data_storage_name) + def post_connect(self) -> None: + super().post_connect() + self.precompute_data: PrecomputeData = PrecomputeData(self._data_storage_name) - self._logger = get_agent_logger( - f"{self.__class__.__module__}.{self.__class__.__qualname__}", - self._agent_info, - ) + self._logger = get_agent_logger( + f"{self.__class__.__module__}.{self.__class__.__qualname__}", + self._agent_info, + ) - self._module_manager: ModuleManager = ModuleManager( - self._agent_info, - self._world_info, - self._scenario_info, - self._module_config, - self._develop_data, - self._gateway_agent, - ) + self._module_manager: ModuleManager = ModuleManager( + self._agent_info, + self._world_info, + self._scenario_info, + self._module_config, + self._develop_data, + self._gateway_agent, + ) + + self._message_manager.set_channel_subscriber( + self._module_manager.get_channel_subscriber( + "MessageManager.PlatoonChannelSubscriber", + "adf_core_python.implement.module.communication.default_channel_subscriber.DefaultChannelSubscriber", + ) + ) + self._message_manager.set_message_coordinator( + self._module_manager.get_message_coordinator( + "MessageManager.PlatoonMessageCoordinator", + "adf_core_python.implement.module.communication.default_message_coordinator.DefaultMessageCoordinator", + ) + ) - self._message_manager.set_channel_subscriber( - self._module_manager.get_channel_subscriber( - "MessageManager.PlatoonChannelSubscriber", - "adf_core_python.implement.module.communication.default_channel_subscriber.DefaultChannelSubscriber", - ) + self._tactics_agent.initialize( + self._agent_info, + self._world_info, + self._scenario_info, + self._module_manager, + self._precompute_data, + self._message_manager, + self._develop_data, + ) + + match self._scenario_info.get_mode(): + case Mode.PRECOMPUTATION: + 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, ) - self._message_manager.set_message_coordinator( - self._module_manager.get_message_coordinator( - "MessageManager.PlatoonMessageCoordinator", - "adf_core_python.implement.module.communication.default_message_coordinator.DefaultMessageCoordinator", - ) + case Mode.PRECOMPUTED: + 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, ) - - self._tactics_agent.initialize( - 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, + self._world_info, + self._scenario_info, + self._module_manager, + self.precompute_data, + self._develop_data, ) - match self._scenario_info.get_mode(): - case Mode.PRECOMPUTATION: - 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: - 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, - self._world_info, - self._scenario_info, - self._module_manager, - self.precompute_data, - self._develop_data, - ) - - def think(self) -> None: - action: Action = self._tactics_agent.think( - self._agent_info, - self._world_info, - self._scenario_info, - self._module_manager, - self._precompute_data, - self._message_manager, - self._develop_data, - ) - if action is not None and self.agent_id is not None: - self._agent_info.set_executed_action(self._agent_info.get_time(), action) - self.send_msg( - action.get_command( - self.agent_id, self._agent_info.get_time() - ).to_message_proto() - ) + def think(self) -> None: + action: Action = self._tactics_agent.think( + self._agent_info, + self._world_info, + self._scenario_info, + self._module_manager, + self._precompute_data, + self._message_manager, + self._develop_data, + ) + if action is not None and self.agent_id is not None: + self._agent_info.set_executed_action(self._agent_info.get_time(), action) + self.send_msg( + action.get_command( + self.agent_id, self._agent_info.get_time() + ).to_message_proto() + ) diff --git a/src/adf_core_python/core/agent/platoon/platoon_ambulance.py b/src/adf_core_python/core/agent/platoon/platoon_ambulance.py index 16a1127..e55de88 100644 --- a/src/adf_core_python/core/agent/platoon/platoon_ambulance.py +++ b/src/adf_core_python/core/agent/platoon/platoon_ambulance.py @@ -11,29 +11,29 @@ class PlatoonAmbulance(Platoon): - def __init__( - self, - tactics_agent: TacticsAgent, - team_name: str, - is_precompute: bool, - is_debug: bool, - data_storage_name: str, - module_config: ModuleConfig, - develop_data: DevelopData, - finish_post_connect_event: Event, - gateway_agent: Optional[GatewayAgent], - ): - super().__init__( - tactics_agent, - team_name, - is_precompute, - is_debug, - data_storage_name, - module_config, - develop_data, - finish_post_connect_event, - gateway_agent, - ) + def __init__( + self, + tactics_agent: TacticsAgent, + team_name: str, + is_precompute: bool, + is_debug: bool, + data_storage_name: str, + module_config: ModuleConfig, + develop_data: DevelopData, + finish_post_connect_event: Event, + gateway_agent: Optional[GatewayAgent], + ): + super().__init__( + tactics_agent, + team_name, + is_precompute, + is_debug, + data_storage_name, + module_config, + develop_data, + finish_post_connect_event, + gateway_agent, + ) - def get_requested_entities(self) -> list[EntityURN]: - return [EntityURN.AMBULANCE_TEAM] + def get_requested_entities(self) -> list[EntityURN]: + return [EntityURN.AMBULANCE_TEAM] diff --git a/src/adf_core_python/core/agent/platoon/platoon_fire.py b/src/adf_core_python/core/agent/platoon/platoon_fire.py index 13db7e0..b5cc288 100644 --- a/src/adf_core_python/core/agent/platoon/platoon_fire.py +++ b/src/adf_core_python/core/agent/platoon/platoon_fire.py @@ -11,29 +11,29 @@ class PlatoonFire(Platoon): - def __init__( - self, - tactics_agent: TacticsAgent, - team_name: str, - is_precompute: bool, - is_debug: bool, - data_storage_name: str, - module_config: ModuleConfig, - develop_data: DevelopData, - finish_post_connect_event: Event, - gateway_agent: Optional[GatewayAgent], - ): - super().__init__( - tactics_agent, - team_name, - is_precompute, - is_debug, - data_storage_name, - module_config, - develop_data, - finish_post_connect_event, - gateway_agent, - ) + def __init__( + self, + tactics_agent: TacticsAgent, + team_name: str, + is_precompute: bool, + is_debug: bool, + data_storage_name: str, + module_config: ModuleConfig, + develop_data: DevelopData, + finish_post_connect_event: Event, + gateway_agent: Optional[GatewayAgent], + ): + super().__init__( + tactics_agent, + team_name, + is_precompute, + is_debug, + data_storage_name, + module_config, + develop_data, + finish_post_connect_event, + gateway_agent, + ) - def get_requested_entities(self) -> list[EntityURN]: - return [EntityURN.FIRE_BRIGADE] + def get_requested_entities(self) -> list[EntityURN]: + return [EntityURN.FIRE_BRIGADE] diff --git a/src/adf_core_python/core/agent/platoon/platoon_police.py b/src/adf_core_python/core/agent/platoon/platoon_police.py index 8f9c33a..8a27047 100644 --- a/src/adf_core_python/core/agent/platoon/platoon_police.py +++ b/src/adf_core_python/core/agent/platoon/platoon_police.py @@ -11,29 +11,29 @@ class PlatoonPolice(Platoon): - def __init__( - self, - tactics_agent: TacticsAgent, - team_name: str, - is_precompute: bool, - is_debug: bool, - data_storage_name: str, - module_config: ModuleConfig, - develop_data: DevelopData, - finish_post_connect_event: Event, - gateway_agent: Optional[GatewayAgent], - ): - super().__init__( - tactics_agent, - team_name, - is_precompute, - is_debug, - data_storage_name, - module_config, - develop_data, - finish_post_connect_event, - gateway_agent, - ) + def __init__( + self, + tactics_agent: TacticsAgent, + team_name: str, + is_precompute: bool, + is_debug: bool, + data_storage_name: str, + module_config: ModuleConfig, + develop_data: DevelopData, + finish_post_connect_event: Event, + gateway_agent: Optional[GatewayAgent], + ): + super().__init__( + tactics_agent, + team_name, + is_precompute, + is_debug, + data_storage_name, + module_config, + develop_data, + finish_post_connect_event, + gateway_agent, + ) - def get_requested_entities(self) -> list[EntityURN]: - return [EntityURN.POLICE_FORCE] + def get_requested_entities(self) -> list[EntityURN]: + return [EntityURN.POLICE_FORCE] diff --git a/src/adf_core_python/core/component/abstract_loader.py b/src/adf_core_python/core/component/abstract_loader.py index dc0feae..4cc859a 100644 --- a/src/adf_core_python/core/component/abstract_loader.py +++ b/src/adf_core_python/core/component/abstract_loader.py @@ -2,52 +2,52 @@ from typing import Optional from adf_core_python.core.component.tactics.tactics_ambulance_center import ( - TacticsAmbulanceCenter, + TacticsAmbulanceCenter, ) from adf_core_python.core.component.tactics.tactics_ambulance_team import ( - TacticsAmbulanceTeam, + TacticsAmbulanceTeam, ) from adf_core_python.core.component.tactics.tactics_fire_brigade import ( - TacticsFireBrigade, + TacticsFireBrigade, ) from adf_core_python.core.component.tactics.tactics_fire_station import ( - TacticsFireStation, + TacticsFireStation, ) from adf_core_python.core.component.tactics.tactics_police_force import ( - TacticsPoliceForce, + TacticsPoliceForce, ) from adf_core_python.core.component.tactics.tactics_police_office import ( - TacticsPoliceOffice, + TacticsPoliceOffice, ) class AbstractLoader(ABC): - def __init__(self, team_name: Optional[str] = None): - self._team_name: str = "" if team_name is None else team_name + def __init__(self, team_name: Optional[str] = None): + self._team_name: str = "" if team_name is None else team_name - def get_team_name(self) -> str: - return self._team_name + def get_team_name(self) -> str: + return self._team_name - @abstractmethod - def get_tactics_ambulance_team(self) -> TacticsAmbulanceTeam: - raise NotImplementedError + @abstractmethod + def get_tactics_ambulance_team(self) -> TacticsAmbulanceTeam: + raise NotImplementedError - @abstractmethod - def get_tactics_fire_brigade(self) -> TacticsFireBrigade: - raise NotImplementedError + @abstractmethod + def get_tactics_fire_brigade(self) -> TacticsFireBrigade: + raise NotImplementedError - @abstractmethod - def get_tactics_police_force(self) -> TacticsPoliceForce: - raise NotImplementedError + @abstractmethod + def get_tactics_police_force(self) -> TacticsPoliceForce: + raise NotImplementedError - @abstractmethod - def get_tactics_ambulance_center(self) -> TacticsAmbulanceCenter: - raise NotImplementedError + @abstractmethod + def get_tactics_ambulance_center(self) -> TacticsAmbulanceCenter: + raise NotImplementedError - @abstractmethod - def get_tactics_fire_station(self) -> TacticsFireStation: - raise NotImplementedError + @abstractmethod + def get_tactics_fire_station(self) -> TacticsFireStation: + raise NotImplementedError - @abstractmethod - def get_tactics_police_office(self) -> TacticsPoliceOffice: - raise NotImplementedError + @abstractmethod + def get_tactics_police_office(self) -> TacticsPoliceOffice: + raise NotImplementedError diff --git a/src/adf_core_python/core/component/action/extend_action.py b/src/adf_core_python/core/component/action/extend_action.py index 1688e62..054f433 100644 --- a/src/adf_core_python/core/component/action/extend_action.py +++ b/src/adf_core_python/core/component/action/extend_action.py @@ -4,86 +4,86 @@ from typing import TYPE_CHECKING, Optional if TYPE_CHECKING: - from rcrscore.entities import EntityID + from rcrscore.entities import EntityID - from adf_core_python.core.agent.action.action import Action - 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 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.agent.action.action import Action + 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 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 class ExtendAction(ABC): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ): - self.world_info = world_info - self.agent_info = agent_info - self.scenario_info = scenario_info - self.module_manager = module_manager - self.develop_data = develop_data - self.result: Optional[Action] = None - self.count_precompute: int = 0 - self.count_resume: int = 0 - self.count_prepare: int = 0 - self.count_update_info: int = 0 - self.count_update_info_current_time: int = 0 - - @abstractmethod - def set_target_entity_id(self, target_entity_id: EntityID) -> ExtendAction: - raise NotImplementedError - - @abstractmethod - def calculate(self) -> ExtendAction: - raise NotImplementedError - - def get_action(self) -> Optional[Action]: - return self.result - - def precompute(self, precompute_data: PrecomputeData) -> ExtendAction: - self.count_precompute += 1 - return self - - def resume(self, precompute_data: PrecomputeData) -> ExtendAction: - self.count_resume += 1 - return self - - def prepare(self) -> ExtendAction: - self.count_prepare += 1 - return self - - def update_info(self, message_manager: MessageManager) -> ExtendAction: - self.count_update_info += 1 - return self - - def get_count_precompute(self) -> int: - return self.count_precompute - - def get_count_resume(self) -> int: - return self.count_resume - - def get_count_prepare(self) -> int: - return self.count_prepare - - def get_count_update_info(self) -> int: - return self.count_update_info - - def reset_count_precompute(self) -> None: - self.count_precompute = 0 - - def reset_count_resume(self) -> None: - self.count_resume = 0 - - def reset_count_prepare(self) -> None: - self.count_prepare = 0 - - def reset_count_update_info(self) -> None: - self.count_update_info = 0 + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ): + self.world_info = world_info + self.agent_info = agent_info + self.scenario_info = scenario_info + self.module_manager = module_manager + self.develop_data = develop_data + self.result: Optional[Action] = None + self.count_precompute: int = 0 + self.count_resume: int = 0 + self.count_prepare: int = 0 + self.count_update_info: int = 0 + self.count_update_info_current_time: int = 0 + + @abstractmethod + def set_target_entity_id(self, target_entity_id: EntityID) -> ExtendAction: + raise NotImplementedError + + @abstractmethod + def calculate(self) -> ExtendAction: + raise NotImplementedError + + def get_action(self) -> Optional[Action]: + return self.result + + def precompute(self, precompute_data: PrecomputeData) -> ExtendAction: + self.count_precompute += 1 + return self + + def resume(self, precompute_data: PrecomputeData) -> ExtendAction: + self.count_resume += 1 + return self + + def prepare(self) -> ExtendAction: + self.count_prepare += 1 + return self + + def update_info(self, message_manager: MessageManager) -> ExtendAction: + self.count_update_info += 1 + return self + + def get_count_precompute(self) -> int: + return self.count_precompute + + def get_count_resume(self) -> int: + return self.count_resume + + def get_count_prepare(self) -> int: + return self.count_prepare + + def get_count_update_info(self) -> int: + return self.count_update_info + + def reset_count_precompute(self) -> None: + self.count_precompute = 0 + + def reset_count_resume(self) -> None: + self.count_resume = 0 + + def reset_count_prepare(self) -> None: + self.count_prepare = 0 + + def reset_count_update_info(self) -> None: + self.count_update_info = 0 diff --git a/src/adf_core_python/core/component/centralized/command_executor.py b/src/adf_core_python/core/component/centralized/command_executor.py index ebd501f..6b9bd8c 100644 --- a/src/adf_core_python/core/component/centralized/command_executor.py +++ b/src/adf_core_python/core/component/centralized/command_executor.py @@ -4,94 +4,94 @@ from typing import TYPE_CHECKING, Generic, Optional, TypeVar if TYPE_CHECKING: - 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 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.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 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.agent.action.action import Action from adf_core_python.core.component.communication.communication_message import ( - CommunicationMessage, + CommunicationMessage, ) T = TypeVar("T", bound=CommunicationMessage) class CommandExecutor(ABC, Generic[T]): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - self._agent_info = agent_info - self._world_info = world_info - self._scenario_info = scenario_info - self._module_manager = module_manager - self._develop_data = develop_data - - self._result: Optional[Action] = None - - self._count_precompute: int = 0 - self._count_prepare: int = 0 - self._count_resume: int = 0 - self._count_update_info: int = 0 - self._count_update_info_current_time: int = 0 - - @abstractmethod - def set_command(self, command: T) -> CommandExecutor: - pass - - @abstractmethod - def calculate(self) -> CommandExecutor: - pass - - def get_action(self) -> Optional[Action]: - return self._result - - def precompute(self, precompute_data: PrecomputeData) -> CommandExecutor: - self._count_precompute += 1 - return self - - def prepare(self) -> CommandExecutor: - self._count_prepare += 1 - return self - - def resume(self, precompute_data: PrecomputeData) -> CommandExecutor: - self._count_resume += 1 - return self - - def update_info(self, message_manager: MessageManager) -> CommandExecutor: - if self._count_update_info_current_time != self._agent_info.get_time(): - self._count_update_info_current_time = self._agent_info.get_time() - self._count_update_info += 1 - return self - - def get_count_precompute(self) -> int: - return self._count_precompute - - def get_count_prepare(self) -> int: - return self._count_prepare - - def get_count_resume(self) -> int: - return self._count_resume - - def get_count_update_info(self) -> int: - return self._count_update_info - - def reset_count_precompute(self) -> None: - self._count_precompute = 0 - - def reset_count_prepare(self) -> None: - self._count_prepare = 0 - - def reset_count_resume(self) -> None: - self._count_resume = 0 - - def reset_count_update_info(self) -> None: - self._count_update_info = 0 + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + self._agent_info = agent_info + self._world_info = world_info + self._scenario_info = scenario_info + self._module_manager = module_manager + self._develop_data = develop_data + + self._result: Optional[Action] = None + + self._count_precompute: int = 0 + self._count_prepare: int = 0 + self._count_resume: int = 0 + self._count_update_info: int = 0 + self._count_update_info_current_time: int = 0 + + @abstractmethod + def set_command(self, command: T) -> CommandExecutor: + pass + + @abstractmethod + def calculate(self) -> CommandExecutor: + pass + + def get_action(self) -> Optional[Action]: + return self._result + + def precompute(self, precompute_data: PrecomputeData) -> CommandExecutor: + self._count_precompute += 1 + return self + + def prepare(self) -> CommandExecutor: + self._count_prepare += 1 + return self + + def resume(self, precompute_data: PrecomputeData) -> CommandExecutor: + self._count_resume += 1 + return self + + def update_info(self, message_manager: MessageManager) -> CommandExecutor: + if self._count_update_info_current_time != self._agent_info.get_time(): + self._count_update_info_current_time = self._agent_info.get_time() + self._count_update_info += 1 + return self + + def get_count_precompute(self) -> int: + return self._count_precompute + + def get_count_prepare(self) -> int: + return self._count_prepare + + def get_count_resume(self) -> int: + return self._count_resume + + def get_count_update_info(self) -> int: + return self._count_update_info + + def reset_count_precompute(self) -> None: + self._count_precompute = 0 + + def reset_count_prepare(self) -> None: + self._count_prepare = 0 + + def reset_count_resume(self) -> None: + self._count_resume = 0 + + def reset_count_update_info(self) -> None: + self._count_update_info = 0 diff --git a/src/adf_core_python/core/component/centralized/command_picker.py b/src/adf_core_python/core/component/centralized/command_picker.py index 8fcea2f..a78c05d 100644 --- a/src/adf_core_python/core/component/centralized/command_picker.py +++ b/src/adf_core_python/core/component/centralized/command_picker.py @@ -6,95 +6,95 @@ from rcrscore.entities import EntityID if TYPE_CHECKING: - 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 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.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 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.communication.message_manager import MessageManager from adf_core_python.core.agent.precompute.precompute_data import PrecomputeData from adf_core_python.core.component.communication.communication_message import ( - CommunicationMessage, + CommunicationMessage, ) class CommandPicker(ABC): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - self._agent_info = agent_info - self._world_info = world_info - self._scenario_info = scenario_info - self._module_manager = module_manager - self._develop_data = develop_data - self._count_precompute: int = 0 - self._count_prepare: int = 0 - self._count_resume: int = 0 - self._count_update_info: int = 0 - self._count_update_info_current_time: int = 0 - - @abstractmethod - def set_allocator_result( - self, allocation_data: dict[EntityID, EntityID] - ) -> CommandPicker: - pass - - @abstractmethod - def calculate(self) -> CommandPicker: - pass - - @abstractmethod - def get_result(self) -> list[CommunicationMessage]: - pass - - def precompute(self, precompute_data: PrecomputeData) -> CommandPicker: - self._count_precompute += 1 - return self - - def prepare(self) -> CommandPicker: - self._count_prepare += 1 - return self - - def resume(self, precompute_data: PrecomputeData) -> CommandPicker: - self._count_resume += 1 - return self - - def update_info(self, message_manager: MessageManager) -> CommandPicker: - if self._count_update_info_current_time != self._agent_info.get_time(): - self._count_update_info_current_time = self._agent_info.get_time() - self._count_update_info = 0 - self._count_update_info += 1 - return self - - def get_count_precompute(self) -> int: - return self._count_precompute - - def get_count_prepare(self) -> int: - return self._count_prepare - - def get_count_resume(self) -> int: - return self._count_resume - - def get_count_update_info(self) -> int: - return self._count_update_info - - def get_count_update_info_current_time(self) -> int: - return self._count_update_info_current_time - - def reset_count_precompute(self) -> None: - self._count_precompute = 0 - - def reset_count_prepare(self) -> None: - self._count_prepare = 0 - - def reset_count_resume(self) -> None: - self._count_resume = 0 - - def reset_count_update_info(self) -> None: - self._count_update_info = 0 + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + self._agent_info = agent_info + self._world_info = world_info + self._scenario_info = scenario_info + self._module_manager = module_manager + self._develop_data = develop_data + self._count_precompute: int = 0 + self._count_prepare: int = 0 + self._count_resume: int = 0 + self._count_update_info: int = 0 + self._count_update_info_current_time: int = 0 + + @abstractmethod + def set_allocator_result( + self, allocation_data: dict[EntityID, EntityID] + ) -> CommandPicker: + pass + + @abstractmethod + def calculate(self) -> CommandPicker: + pass + + @abstractmethod + def get_result(self) -> list[CommunicationMessage]: + pass + + def precompute(self, precompute_data: PrecomputeData) -> CommandPicker: + self._count_precompute += 1 + return self + + def prepare(self) -> CommandPicker: + self._count_prepare += 1 + return self + + def resume(self, precompute_data: PrecomputeData) -> CommandPicker: + self._count_resume += 1 + return self + + def update_info(self, message_manager: MessageManager) -> CommandPicker: + if self._count_update_info_current_time != self._agent_info.get_time(): + self._count_update_info_current_time = self._agent_info.get_time() + self._count_update_info = 0 + self._count_update_info += 1 + return self + + def get_count_precompute(self) -> int: + return self._count_precompute + + def get_count_prepare(self) -> int: + return self._count_prepare + + def get_count_resume(self) -> int: + return self._count_resume + + def get_count_update_info(self) -> int: + return self._count_update_info + + def get_count_update_info_current_time(self) -> int: + return self._count_update_info_current_time + + def reset_count_precompute(self) -> None: + self._count_precompute = 0 + + def reset_count_prepare(self) -> None: + self._count_prepare = 0 + + def reset_count_resume(self) -> None: + self._count_resume = 0 + + def reset_count_update_info(self) -> None: + self._count_update_info = 0 diff --git a/src/adf_core_python/core/component/communication/channel_subscriber.py b/src/adf_core_python/core/component/communication/channel_subscriber.py index d2da83f..9e1acd4 100644 --- a/src/adf_core_python/core/component/communication/channel_subscriber.py +++ b/src/adf_core_python/core/component/communication/channel_subscriber.py @@ -4,34 +4,34 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: - from adf_core_python.core.agent.info.agent_info import AgentInfo - 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.info.agent_info import AgentInfo + from adf_core_python.core.agent.info.scenario_info import ScenarioInfo + from adf_core_python.core.agent.info.world_info import WorldInfo class ChannelSubscriber(ABC): - @abstractmethod - def subscribe( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - ) -> list[int]: - """ - Subscribe to the channel. + @abstractmethod + def subscribe( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + ) -> list[int]: + """ + Subscribe to the channel. - Parameters - ---------- - agent_info : AgentInfo - The agent info. - world_info : WorldInfo - The world info. - scenario_info : ScenarioInfo - The scenario info. + Parameters + ---------- + agent_info : AgentInfo + The agent info. + world_info : WorldInfo + The world info. + scenario_info : ScenarioInfo + The scenario info. - Returns - ------- - list[int] - The list of subscribed channels. - """ - pass + Returns + ------- + list[int] + The list of subscribed channels. + """ + pass diff --git a/src/adf_core_python/core/component/communication/communication_message.py b/src/adf_core_python/core/component/communication/communication_message.py index 60972ff..5538b40 100644 --- a/src/adf_core_python/core/component/communication/communication_message.py +++ b/src/adf_core_python/core/component/communication/communication_message.py @@ -6,20 +6,20 @@ class CommunicationMessage(ABC): - def __init__(self, is_wireless_message: bool) -> None: - self._is_wireless_message = is_wireless_message + def __init__(self, is_wireless_message: bool) -> None: + self._is_wireless_message = is_wireless_message - def is_wireless_message(self) -> bool: - return self._is_wireless_message + def is_wireless_message(self) -> bool: + return self._is_wireless_message - @abstractmethod - def get_bit_size(self) -> int: - raise NotImplementedError + @abstractmethod + def get_bit_size(self) -> int: + raise NotImplementedError - @abstractmethod - def to_bits(self) -> bitarray: - raise NotImplementedError + @abstractmethod + def to_bits(self) -> bitarray: + raise NotImplementedError - @abstractmethod - def __hash__(self) -> int: - raise NotImplementedError + @abstractmethod + def __hash__(self) -> int: + raise NotImplementedError diff --git a/src/adf_core_python/core/component/communication/communication_module.py b/src/adf_core_python/core/component/communication/communication_module.py index 2e87e31..0959f6c 100644 --- a/src/adf_core_python/core/component/communication/communication_module.py +++ b/src/adf_core_python/core/component/communication/communication_module.py @@ -4,15 +4,15 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: - from adf_core_python.core.agent.agent import Agent - from adf_core_python.core.agent.communication.message_manager import MessageManager + from adf_core_python.core.agent.agent import Agent + from adf_core_python.core.agent.communication.message_manager import MessageManager class CommunicationModule(ABC): - @abstractmethod - def receive(self, agent: Agent, message_manager: MessageManager) -> None: - pass + @abstractmethod + def receive(self, agent: Agent, message_manager: MessageManager) -> None: + pass - @abstractmethod - def send(self, agent: Agent, message_manager: MessageManager) -> None: - pass + @abstractmethod + def send(self, agent: Agent, message_manager: MessageManager) -> None: + pass diff --git a/src/adf_core_python/core/component/communication/message_coordinator.py b/src/adf_core_python/core/component/communication/message_coordinator.py index 9d8cb1b..86e93f1 100644 --- a/src/adf_core_python/core/component/communication/message_coordinator.py +++ b/src/adf_core_python/core/component/communication/message_coordinator.py @@ -4,24 +4,24 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: - from adf_core_python.core.agent.communication.message_manager import MessageManager - from adf_core_python.core.agent.info.agent_info import AgentInfo - 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.component.communication.communication_message import ( - CommunicationMessage, - ) + from adf_core_python.core.agent.communication.message_manager import MessageManager + from adf_core_python.core.agent.info.agent_info import AgentInfo + 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.component.communication.communication_message import ( + CommunicationMessage, + ) class MessageCoordinator(ABC): - @abstractmethod - def coordinate( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - message_manager: MessageManager, - send_message_list: list[CommunicationMessage], - channel_send_message_list: list[list[CommunicationMessage]], - ) -> None: - pass + @abstractmethod + def coordinate( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + message_manager: MessageManager, + send_message_list: list[CommunicationMessage], + channel_send_message_list: list[list[CommunicationMessage]], + ) -> None: + pass diff --git a/src/adf_core_python/core/component/module/abstract_module.py b/src/adf_core_python/core/component/module/abstract_module.py index 4a3f317..8f9e466 100644 --- a/src/adf_core_python/core/component/module/abstract_module.py +++ b/src/adf_core_python/core/component/module/abstract_module.py @@ -7,99 +7,99 @@ from adf_core_python.core.logger.logger import get_agent_logger if TYPE_CHECKING: - 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 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.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 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 class AbstractModule(ABC): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - self._agent_info = agent_info - self._world_info = world_info - self._scenario_info = scenario_info - self._module_manager = module_manager - self._develop_data = develop_data - self._count_precompute: int = 0 - self._count_resume: int = 0 - self._count_prepare: int = 0 - self._count_update_info: int = 0 - self._count_update_info_current_time: int = 0 - self._logger = get_agent_logger( - f"{self.__class__.__module__}.{self.__class__.__qualname__}", - self._agent_info, - ) - - self._sub_modules: list[AbstractModule] = [] - - def register_sub_module(self, sub_module: AbstractModule) -> None: - self._sub_modules.append(sub_module) - - def unregister_sub_module(self, sub_module: AbstractModule) -> None: - self._sub_modules.remove(sub_module) - - def precompute(self, precompute_data: PrecomputeData) -> AbstractModule: - self._count_precompute += 1 - for sub_module in self._sub_modules: - sub_module.precompute(precompute_data) - return self - - def resume(self, precompute_data: PrecomputeData) -> AbstractModule: - self._count_resume += 1 - for sub_module in self._sub_modules: - sub_module.resume(precompute_data) - return self - - def prepare(self) -> AbstractModule: - self._count_prepare += 1 - for sub_module in self._sub_modules: - start_time = time.time() - sub_module.prepare() - self._logger.debug( - f"{self.__class__.__name__}'s sub_module {sub_module.__class__.__name__} prepare time: {time.time() - start_time:.3f}", - ) - return self - - def update_info(self, message_manager: MessageManager) -> AbstractModule: - self._count_update_info += 1 - for sub_module in self._sub_modules: - sub_module.update_info(message_manager) - return self - - @abstractmethod - def calculate(self) -> AbstractModule: - raise NotImplementedError - - def get_count_precompute(self) -> int: - return self._count_precompute - - def get_count_resume(self) -> int: - return self._count_resume - - def get_count_prepare(self) -> int: - return self._count_prepare - - def get_count_update_info(self) -> int: - return self._count_update_info - - def reset_count_precompute(self) -> None: - self._count_precompute = 0 - - def reset_count_resume(self) -> None: - self._count_resume = 0 - - def reset_count_prepare(self) -> None: - self._count_prepare = 0 - - def reset_count_update_info(self) -> None: - self._count_update_info = 0 + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + self._agent_info = agent_info + self._world_info = world_info + self._scenario_info = scenario_info + self._module_manager = module_manager + self._develop_data = develop_data + self._count_precompute: int = 0 + self._count_resume: int = 0 + self._count_prepare: int = 0 + self._count_update_info: int = 0 + self._count_update_info_current_time: int = 0 + self._logger = get_agent_logger( + f"{self.__class__.__module__}.{self.__class__.__qualname__}", + self._agent_info, + ) + + self._sub_modules: list[AbstractModule] = [] + + def register_sub_module(self, sub_module: AbstractModule) -> None: + self._sub_modules.append(sub_module) + + def unregister_sub_module(self, sub_module: AbstractModule) -> None: + self._sub_modules.remove(sub_module) + + def precompute(self, precompute_data: PrecomputeData) -> AbstractModule: + self._count_precompute += 1 + for sub_module in self._sub_modules: + sub_module.precompute(precompute_data) + return self + + def resume(self, precompute_data: PrecomputeData) -> AbstractModule: + self._count_resume += 1 + for sub_module in self._sub_modules: + sub_module.resume(precompute_data) + return self + + def prepare(self) -> AbstractModule: + self._count_prepare += 1 + for sub_module in self._sub_modules: + start_time = time.time() + sub_module.prepare() + self._logger.debug( + f"{self.__class__.__name__}'s sub_module {sub_module.__class__.__name__} prepare time: {time.time() - start_time:.3f}", + ) + return self + + def update_info(self, message_manager: MessageManager) -> AbstractModule: + self._count_update_info += 1 + for sub_module in self._sub_modules: + sub_module.update_info(message_manager) + return self + + @abstractmethod + def calculate(self) -> AbstractModule: + raise NotImplementedError + + def get_count_precompute(self) -> int: + return self._count_precompute + + def get_count_resume(self) -> int: + return self._count_resume + + def get_count_prepare(self) -> int: + return self._count_prepare + + def get_count_update_info(self) -> int: + return self._count_update_info + + def reset_count_precompute(self) -> None: + self._count_precompute = 0 + + def reset_count_resume(self) -> None: + self._count_resume = 0 + + def reset_count_prepare(self) -> None: + self._count_prepare = 0 + + def reset_count_update_info(self) -> None: + self._count_update_info = 0 diff --git a/src/adf_core_python/core/component/module/algorithm/clustering.py b/src/adf_core_python/core/component/module/algorithm/clustering.py index 2594cb9..7a0331b 100644 --- a/src/adf_core_python/core/component/module/algorithm/clustering.py +++ b/src/adf_core_python/core/component/module/algorithm/clustering.py @@ -6,63 +6,63 @@ from adf_core_python.core.component.module.abstract_module import AbstractModule if TYPE_CHECKING: - from rcrscore.entities import EntityID - from rcrscore.entities.entity import Entity + from rcrscore.entities import EntityID + from rcrscore.entities.entity import Entity - 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 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.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 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 class Clustering(AbstractModule): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) - @abstractmethod - def get_cluster_number(self) -> int: - pass + @abstractmethod + def get_cluster_number(self) -> int: + pass - @abstractmethod - def get_cluster_index(self, entity_id: EntityID) -> int: - pass + @abstractmethod + def get_cluster_index(self, entity_id: EntityID) -> int: + pass - @abstractmethod - def get_cluster_entities(self, cluster_index: int) -> list[Entity]: - pass + @abstractmethod + def get_cluster_entities(self, cluster_index: int) -> list[Entity]: + pass - @abstractmethod - def get_cluster_entity_ids(self, cluster_index: int) -> list[EntityID]: - pass + @abstractmethod + def get_cluster_entity_ids(self, cluster_index: int) -> list[EntityID]: + pass - @abstractmethod - def calculate(self) -> Clustering: - pass + @abstractmethod + def calculate(self) -> Clustering: + pass - def precompute(self, precompute_data: PrecomputeData) -> Clustering: - super().precompute(precompute_data) - return self + def precompute(self, precompute_data: PrecomputeData) -> Clustering: + super().precompute(precompute_data) + return self - def resume(self, precompute_data: PrecomputeData) -> Clustering: - super().resume(precompute_data) - return self + def resume(self, precompute_data: PrecomputeData) -> Clustering: + super().resume(precompute_data) + return self - def prepare(self) -> Clustering: - super().prepare() - return self + def prepare(self) -> Clustering: + super().prepare() + return self - def update_info(self, message_manager: MessageManager) -> Clustering: - super().update_info(message_manager) - return self + def update_info(self, message_manager: MessageManager) -> Clustering: + super().update_info(message_manager) + return self diff --git a/src/adf_core_python/core/component/module/algorithm/path_planning.py b/src/adf_core_python/core/component/module/algorithm/path_planning.py index d7318f1..4a36bbb 100644 --- a/src/adf_core_python/core/component/module/algorithm/path_planning.py +++ b/src/adf_core_python/core/component/module/algorithm/path_planning.py @@ -6,62 +6,62 @@ from adf_core_python.core.component.module.abstract_module import AbstractModule if TYPE_CHECKING: - from rcrscore.entities import EntityID + from rcrscore.entities import EntityID - 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 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.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 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 class PathPlanning(AbstractModule): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) - @abstractmethod - def get_path( - self, from_entity_id: EntityID, to_entity_id: EntityID - ) -> list[EntityID]: - pass + @abstractmethod + def get_path( + self, from_entity_id: EntityID, to_entity_id: EntityID + ) -> list[EntityID]: + pass - @abstractmethod - def get_path_to_multiple_destinations( - self, from_entity_id: EntityID, destination_entity_ids: set[EntityID] - ) -> list[EntityID]: - pass + @abstractmethod + def get_path_to_multiple_destinations( + self, from_entity_id: EntityID, destination_entity_ids: set[EntityID] + ) -> list[EntityID]: + pass - @abstractmethod - def get_distance(self, from_entity_id: EntityID, to_entity_id: EntityID) -> float: - pass + @abstractmethod + def get_distance(self, from_entity_id: EntityID, to_entity_id: EntityID) -> float: + pass - def precompute(self, precompute_data: PrecomputeData) -> PathPlanning: - super().precompute(precompute_data) - return self + def precompute(self, precompute_data: PrecomputeData) -> PathPlanning: + super().precompute(precompute_data) + return self - def resume(self, precompute_data: PrecomputeData) -> PathPlanning: - super().resume(precompute_data) - return self + def resume(self, precompute_data: PrecomputeData) -> PathPlanning: + super().resume(precompute_data) + return self - def prepare(self) -> PathPlanning: - super().prepare() - return self + def prepare(self) -> PathPlanning: + super().prepare() + return self - def update_info(self, message_manager: MessageManager) -> PathPlanning: - super().update_info(message_manager) - return self + def update_info(self, message_manager: MessageManager) -> PathPlanning: + super().update_info(message_manager) + return self - @abstractmethod - def calculate(self) -> PathPlanning: - pass + @abstractmethod + def calculate(self) -> PathPlanning: + pass diff --git a/src/adf_core_python/core/component/module/complex/ambulance_target_allocator.py b/src/adf_core_python/core/component/module/complex/ambulance_target_allocator.py index 63e5a5f..8956ea9 100644 --- a/src/adf_core_python/core/component/module/complex/ambulance_target_allocator.py +++ b/src/adf_core_python/core/component/module/complex/ambulance_target_allocator.py @@ -4,54 +4,54 @@ from typing import TYPE_CHECKING from adf_core_python.core.component.module.complex.target_allocator import ( - TargetAllocator, + TargetAllocator, ) if TYPE_CHECKING: - from rcrscore.entities import EntityID + from rcrscore.entities import EntityID - 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 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.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 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 class AmbulanceTargetAllocator(TargetAllocator): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - - @abstractmethod - def get_result(self) -> dict[EntityID, EntityID]: - pass - - @abstractmethod - def calculate(self) -> AmbulanceTargetAllocator: - pass - - def precompute(self, precompute_data: PrecomputeData) -> AmbulanceTargetAllocator: - super().precompute(precompute_data) - return self - - def resume(self, precompute_data: PrecomputeData) -> AmbulanceTargetAllocator: - super().resume(precompute_data) - return self - - def prepare(self) -> AmbulanceTargetAllocator: - super().prepare() - return self - - def update_info(self, message_manager: MessageManager) -> AmbulanceTargetAllocator: - super().update_info(message_manager) - return self + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + + @abstractmethod + def get_result(self) -> dict[EntityID, EntityID]: + pass + + @abstractmethod + def calculate(self) -> AmbulanceTargetAllocator: + pass + + def precompute(self, precompute_data: PrecomputeData) -> AmbulanceTargetAllocator: + super().precompute(precompute_data) + return self + + def resume(self, precompute_data: PrecomputeData) -> AmbulanceTargetAllocator: + super().resume(precompute_data) + return self + + def prepare(self) -> AmbulanceTargetAllocator: + super().prepare() + return self + + def update_info(self, message_manager: MessageManager) -> AmbulanceTargetAllocator: + super().update_info(message_manager) + return self diff --git a/src/adf_core_python/core/component/module/complex/fire_target_allocator.py b/src/adf_core_python/core/component/module/complex/fire_target_allocator.py index 2cf3ec2..79d1905 100644 --- a/src/adf_core_python/core/component/module/complex/fire_target_allocator.py +++ b/src/adf_core_python/core/component/module/complex/fire_target_allocator.py @@ -4,54 +4,54 @@ from typing import TYPE_CHECKING from adf_core_python.core.component.module.complex.target_allocator import ( - TargetAllocator, + TargetAllocator, ) if TYPE_CHECKING: - from rcrscore.entities import EntityID + from rcrscore.entities import EntityID - 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 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.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 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 class FireTargetAllocator(TargetAllocator): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - - @abstractmethod - def get_result(self) -> dict[EntityID, EntityID]: - pass - - @abstractmethod - def calculate(self) -> FireTargetAllocator: - pass - - def precompute(self, precompute_data: PrecomputeData) -> FireTargetAllocator: - super().precompute(precompute_data) - return self - - def resume(self, precompute_data: PrecomputeData) -> FireTargetAllocator: - super().resume(precompute_data) - return self - - def prepare(self) -> FireTargetAllocator: - super().prepare() - return self - - def update_info(self, message_manager: MessageManager) -> FireTargetAllocator: - super().update_info(message_manager) - return self + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + + @abstractmethod + def get_result(self) -> dict[EntityID, EntityID]: + pass + + @abstractmethod + def calculate(self) -> FireTargetAllocator: + pass + + def precompute(self, precompute_data: PrecomputeData) -> FireTargetAllocator: + super().precompute(precompute_data) + return self + + def resume(self, precompute_data: PrecomputeData) -> FireTargetAllocator: + super().resume(precompute_data) + return self + + def prepare(self) -> FireTargetAllocator: + super().prepare() + return self + + def update_info(self, message_manager: MessageManager) -> FireTargetAllocator: + super().update_info(message_manager) + return self diff --git a/src/adf_core_python/core/component/module/complex/human_detector.py b/src/adf_core_python/core/component/module/complex/human_detector.py index 0e7ae6c..a0619b3 100644 --- a/src/adf_core_python/core/component/module/complex/human_detector.py +++ b/src/adf_core_python/core/component/module/complex/human_detector.py @@ -6,43 +6,43 @@ from rcrscore.entities.human import Human from adf_core_python.core.component.module.complex.target_detector import ( - TargetDetector, + TargetDetector, ) if TYPE_CHECKING: - 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 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.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 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 class HumanDetector(TargetDetector[Human]): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - - def precompute(self, precompute_data: PrecomputeData) -> HumanDetector: - super().precompute(precompute_data) - return self - - def resume(self, precompute_data: PrecomputeData) -> HumanDetector: - super().resume(precompute_data) - return self - - def prepare(self) -> HumanDetector: - super().prepare() - return self - - @abstractmethod - def calculate(self) -> HumanDetector: - return self + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + + def precompute(self, precompute_data: PrecomputeData) -> HumanDetector: + super().precompute(precompute_data) + return self + + def resume(self, precompute_data: PrecomputeData) -> HumanDetector: + super().resume(precompute_data) + return self + + def prepare(self) -> HumanDetector: + super().prepare() + return self + + @abstractmethod + def calculate(self) -> HumanDetector: + return self diff --git a/src/adf_core_python/core/component/module/complex/police_target_allocator.py b/src/adf_core_python/core/component/module/complex/police_target_allocator.py index a066304..540a60b 100644 --- a/src/adf_core_python/core/component/module/complex/police_target_allocator.py +++ b/src/adf_core_python/core/component/module/complex/police_target_allocator.py @@ -4,54 +4,54 @@ from typing import TYPE_CHECKING from adf_core_python.core.component.module.complex.target_allocator import ( - TargetAllocator, + TargetAllocator, ) if TYPE_CHECKING: - from rcrscore.entities import EntityID + from rcrscore.entities import EntityID - 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 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.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 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 class PoliceTargetAllocator(TargetAllocator): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - - @abstractmethod - def get_result(self) -> dict[EntityID, EntityID]: - pass - - @abstractmethod - def calculate(self) -> PoliceTargetAllocator: - pass - - def precompute(self, precompute_data: PrecomputeData) -> PoliceTargetAllocator: - super().precompute(precompute_data) - return self - - def resume(self, precompute_data: PrecomputeData) -> PoliceTargetAllocator: - super().resume(precompute_data) - return self - - def prepare(self) -> PoliceTargetAllocator: - super().prepare() - return self - - def update_info(self, message_manager: MessageManager) -> PoliceTargetAllocator: - super().update_info(message_manager) - return self + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + + @abstractmethod + def get_result(self) -> dict[EntityID, EntityID]: + pass + + @abstractmethod + def calculate(self) -> PoliceTargetAllocator: + pass + + def precompute(self, precompute_data: PrecomputeData) -> PoliceTargetAllocator: + super().precompute(precompute_data) + return self + + def resume(self, precompute_data: PrecomputeData) -> PoliceTargetAllocator: + super().resume(precompute_data) + return self + + def prepare(self) -> PoliceTargetAllocator: + super().prepare() + return self + + def update_info(self, message_manager: MessageManager) -> PoliceTargetAllocator: + super().update_info(message_manager) + return self diff --git a/src/adf_core_python/core/component/module/complex/road_detector.py b/src/adf_core_python/core/component/module/complex/road_detector.py index 888ea96..f742b2d 100644 --- a/src/adf_core_python/core/component/module/complex/road_detector.py +++ b/src/adf_core_python/core/component/module/complex/road_detector.py @@ -6,43 +6,43 @@ from rcrscore.entities.road import Road from adf_core_python.core.component.module.complex.target_detector import ( - TargetDetector, + TargetDetector, ) if TYPE_CHECKING: - 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 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.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 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 class RoadDetector(TargetDetector[Road]): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - - def precompute(self, precompute_data: PrecomputeData) -> RoadDetector: - super().precompute(precompute_data) - return self - - def resume(self, precompute_data: PrecomputeData) -> RoadDetector: - super().resume(precompute_data) - return self - - def prepare(self) -> RoadDetector: - super().prepare() - return self - - @abstractmethod - def calculate(self) -> RoadDetector: - return self + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + + def precompute(self, precompute_data: PrecomputeData) -> RoadDetector: + super().precompute(precompute_data) + return self + + def resume(self, precompute_data: PrecomputeData) -> RoadDetector: + super().resume(precompute_data) + return self + + def prepare(self) -> RoadDetector: + super().prepare() + return self + + @abstractmethod + def calculate(self) -> RoadDetector: + return self diff --git a/src/adf_core_python/core/component/module/complex/search.py b/src/adf_core_python/core/component/module/complex/search.py index bfeddef..59c4fde 100644 --- a/src/adf_core_python/core/component/module/complex/search.py +++ b/src/adf_core_python/core/component/module/complex/search.py @@ -6,43 +6,43 @@ from rcrscore.entities.area import Area from adf_core_python.core.component.module.complex.target_detector import ( - TargetDetector, + TargetDetector, ) if TYPE_CHECKING: - 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 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.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 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 class Search(TargetDetector[Area]): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - - def precompute(self, precompute_data: PrecomputeData) -> Search: - super().precompute(precompute_data) - return self - - def resume(self, precompute_data: PrecomputeData) -> Search: - super().resume(precompute_data) - return self - - def prepare(self) -> Search: - super().prepare() - return self - - @abstractmethod - def calculate(self) -> Search: - return self + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + + def precompute(self, precompute_data: PrecomputeData) -> Search: + super().precompute(precompute_data) + return self + + def resume(self, precompute_data: PrecomputeData) -> Search: + super().resume(precompute_data) + return self + + def prepare(self) -> Search: + super().prepare() + return self + + @abstractmethod + def calculate(self) -> Search: + return self diff --git a/src/adf_core_python/core/component/module/complex/target_allocator.py b/src/adf_core_python/core/component/module/complex/target_allocator.py index 88ef50f..6979966 100644 --- a/src/adf_core_python/core/component/module/complex/target_allocator.py +++ b/src/adf_core_python/core/component/module/complex/target_allocator.py @@ -6,50 +6,50 @@ from adf_core_python.core.component.module.abstract_module import AbstractModule if TYPE_CHECKING: - from rcrscore.entities import EntityID + from rcrscore.entities import EntityID - 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 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.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 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 class TargetAllocator(AbstractModule): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - - @abstractmethod - def get_result(self) -> dict[EntityID, EntityID]: - pass - - @abstractmethod - def calculate(self) -> TargetAllocator: - pass - - def precompute(self, precompute_data: PrecomputeData) -> TargetAllocator: - super().precompute(precompute_data) - return self - - def resume(self, precompute_data: PrecomputeData) -> TargetAllocator: - super().resume(precompute_data) - return self - - def prepare(self) -> TargetAllocator: - super().prepare() - return self - - def update_info(self, message_manager: MessageManager) -> TargetAllocator: - super().update_info(message_manager) - return self + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + + @abstractmethod + def get_result(self) -> dict[EntityID, EntityID]: + pass + + @abstractmethod + def calculate(self) -> TargetAllocator: + pass + + def precompute(self, precompute_data: PrecomputeData) -> TargetAllocator: + super().precompute(precompute_data) + return self + + def resume(self, precompute_data: PrecomputeData) -> TargetAllocator: + super().resume(precompute_data) + return self + + def prepare(self) -> TargetAllocator: + super().prepare() + return self + + def update_info(self, message_manager: MessageManager) -> TargetAllocator: + super().update_info(message_manager) + return self diff --git a/src/adf_core_python/core/component/module/complex/target_detector.py b/src/adf_core_python/core/component/module/complex/target_detector.py index 21a79e4..7e7285d 100644 --- a/src/adf_core_python/core/component/module/complex/target_detector.py +++ b/src/adf_core_python/core/component/module/complex/target_detector.py @@ -8,52 +8,52 @@ from adf_core_python.core.component.module.abstract_module import AbstractModule if TYPE_CHECKING: - from rcrscore.entities import EntityID + from rcrscore.entities import EntityID - 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 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.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 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 T = TypeVar("T", bound=Entity) class TargetDetector(AbstractModule, Generic[T]): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - - @abstractmethod - def get_target_entity_id(self) -> Optional[EntityID]: - pass - - @abstractmethod - def calculate(self) -> TargetDetector[T]: - pass - - def precompute(self, precompute_data: PrecomputeData) -> TargetDetector[T]: - super().precompute(precompute_data) - return self - - def resume(self, precompute_data: PrecomputeData) -> TargetDetector[T]: - super().resume(precompute_data) - return self - - def prepare(self) -> TargetDetector[T]: - super().prepare() - return self - - def update_info(self, message_manager: MessageManager) -> TargetDetector[T]: - super().update_info(message_manager) - return self + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + + @abstractmethod + def get_target_entity_id(self) -> Optional[EntityID]: + pass + + @abstractmethod + def calculate(self) -> TargetDetector[T]: + pass + + def precompute(self, precompute_data: PrecomputeData) -> TargetDetector[T]: + super().precompute(precompute_data) + return self + + def resume(self, precompute_data: PrecomputeData) -> TargetDetector[T]: + super().resume(precompute_data) + return self + + def prepare(self) -> TargetDetector[T]: + super().prepare() + return self + + def update_info(self, message_manager: MessageManager) -> TargetDetector[T]: + super().update_info(message_manager) + return self diff --git a/src/adf_core_python/core/component/tactics/tactics_agent.py b/src/adf_core_python/core/component/tactics/tactics_agent.py index 3f1343e..9502a2c 100644 --- a/src/adf_core_python/core/component/tactics/tactics_agent.py +++ b/src/adf_core_python/core/component/tactics/tactics_agent.py @@ -8,165 +8,165 @@ from adf_core_python.core.logger.logger import get_agent_logger if TYPE_CHECKING: - from adf_core_python.core.agent.action.action import Action - 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 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.action.extend_action import ExtendAction - from adf_core_python.core.component.module.abstract_module import AbstractModule + from adf_core_python.core.agent.action.action import Action + 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 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.action.extend_action import ExtendAction + from adf_core_python.core.component.module.abstract_module import AbstractModule class TacticsAgent(ABC): - def __init__(self, parent: Optional[TacticsAgent] = None) -> None: - self._parent = parent - self._modules: list[AbstractModule] = [] - self._actions: list[ExtendAction] = [] - self._command_executor: list[CommandExecutor] = [] - - @abstractmethod - def initialize( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - precompute_data: PrecomputeData, - message_manager: MessageManager, - develop_data: DevelopData, - ) -> None: - self._logger = get_agent_logger( - f"{self.__class__.__module__}.{self.__class__.__qualname__}", agent_info - ) - - @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 resume( - 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, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - precompute_data: PrecomputeData, - develop_data: DevelopData, - ) -> None: - raise NotImplementedError - - @abstractmethod - def think( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - precompute_data: PrecomputeData, - message_manager: MessageManager, - develop_data: DevelopData, - ) -> Action: - raise NotImplementedError - - def get_parent_tactics(self) -> Optional[TacticsAgent]: - return self._parent - - def register_module(self, module: AbstractModule) -> None: - self._modules.append(module) - - def unregister_module(self, module: AbstractModule) -> None: - self._modules.remove(module) - - def register_action(self, action: ExtendAction) -> None: - self._actions.append(action) - - def unregister_action(self, action: ExtendAction) -> None: - self._actions.remove(action) - - def register_command_executor(self, command_executor: CommandExecutor) -> None: - self._command_executor.append(command_executor) - - def unregister_command_executor(self, command_executor: CommandExecutor) -> None: - self._command_executor.remove(command_executor) - - def module_precompute(self, precompute_data: PrecomputeData) -> None: - for module in self._modules: - module.precompute(precompute_data) - for action in self._actions: - action.precompute(precompute_data) - for executor in self._command_executor: - executor.precompute(precompute_data) - - def module_resume(self, precompute_data: PrecomputeData) -> None: - for module in self._modules: - module.resume(precompute_data) - for action in self._actions: - action.resume(precompute_data) - for executor in self._command_executor: - executor.resume(precompute_data) - - def module_prepare(self) -> None: - for module in self._modules: - start_time = time.time() - module.prepare() - self._logger.debug( - f"module {module.__class__.__name__} prepare time: {time.time() - start_time:.3f}", - ) - for action in self._actions: - start_time = time.time() - action.prepare() - self._logger.debug( - f"module {action.__class__.__name__} prepare time: {time.time() - start_time:.3f}", - ) - for executor in self._command_executor: - executor.prepare() - - def module_update_info(self, message_manager: MessageManager) -> None: - for module in self._modules: - module.update_info(message_manager) - for action in self._actions: - action.update_info(message_manager) - for executor in self._command_executor: - executor.update_info(message_manager) - - def reset_count(self) -> None: - for module in self._modules: - module.reset_count_precompute() - module.reset_count_resume() - module.reset_count_prepare() - module.reset_count_update_info() - for action in self._actions: - action.reset_count_precompute() - action.reset_count_resume() - action.reset_count_prepare() - action.reset_count_update_info() - for executor in self._command_executor: - executor.reset_count_precompute() - executor.reset_count_resume() - executor.reset_count_prepare() - executor.reset_count_update_info() + def __init__(self, parent: Optional[TacticsAgent] = None) -> None: + self._parent = parent + self._modules: list[AbstractModule] = [] + self._actions: list[ExtendAction] = [] + self._command_executor: list[CommandExecutor] = [] + + @abstractmethod + def initialize( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + message_manager: MessageManager, + develop_data: DevelopData, + ) -> None: + self._logger = get_agent_logger( + f"{self.__class__.__module__}.{self.__class__.__qualname__}", agent_info + ) + + @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 resume( + 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, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + develop_data: DevelopData, + ) -> None: + raise NotImplementedError + + @abstractmethod + def think( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + message_manager: MessageManager, + develop_data: DevelopData, + ) -> Action: + raise NotImplementedError + + def get_parent_tactics(self) -> Optional[TacticsAgent]: + return self._parent + + def register_module(self, module: AbstractModule) -> None: + self._modules.append(module) + + def unregister_module(self, module: AbstractModule) -> None: + self._modules.remove(module) + + def register_action(self, action: ExtendAction) -> None: + self._actions.append(action) + + def unregister_action(self, action: ExtendAction) -> None: + self._actions.remove(action) + + def register_command_executor(self, command_executor: CommandExecutor) -> None: + self._command_executor.append(command_executor) + + def unregister_command_executor(self, command_executor: CommandExecutor) -> None: + self._command_executor.remove(command_executor) + + def module_precompute(self, precompute_data: PrecomputeData) -> None: + for module in self._modules: + module.precompute(precompute_data) + for action in self._actions: + action.precompute(precompute_data) + for executor in self._command_executor: + executor.precompute(precompute_data) + + def module_resume(self, precompute_data: PrecomputeData) -> None: + for module in self._modules: + module.resume(precompute_data) + for action in self._actions: + action.resume(precompute_data) + for executor in self._command_executor: + executor.resume(precompute_data) + + def module_prepare(self) -> None: + for module in self._modules: + start_time = time.time() + module.prepare() + self._logger.debug( + f"module {module.__class__.__name__} prepare time: {time.time() - start_time:.3f}", + ) + for action in self._actions: + start_time = time.time() + action.prepare() + self._logger.debug( + f"module {action.__class__.__name__} prepare time: {time.time() - start_time:.3f}", + ) + for executor in self._command_executor: + executor.prepare() + + def module_update_info(self, message_manager: MessageManager) -> None: + for module in self._modules: + module.update_info(message_manager) + for action in self._actions: + action.update_info(message_manager) + for executor in self._command_executor: + executor.update_info(message_manager) + + def reset_count(self) -> None: + for module in self._modules: + module.reset_count_precompute() + module.reset_count_resume() + module.reset_count_prepare() + module.reset_count_update_info() + for action in self._actions: + action.reset_count_precompute() + action.reset_count_resume() + action.reset_count_prepare() + action.reset_count_update_info() + for executor in self._command_executor: + executor.reset_count_precompute() + executor.reset_count_resume() + executor.reset_count_prepare() + executor.reset_count_update_info() diff --git a/src/adf_core_python/core/component/tactics/tactics_ambulance_center.py b/src/adf_core_python/core/component/tactics/tactics_ambulance_center.py index da9b2b8..04eba00 100644 --- a/src/adf_core_python/core/component/tactics/tactics_ambulance_center.py +++ b/src/adf_core_python/core/component/tactics/tactics_ambulance_center.py @@ -6,5 +6,5 @@ class TacticsAmbulanceCenter(TacticsCenter): - def __init__(self, parent: Optional[TacticsAmbulanceCenter] = None) -> None: - super().__init__(parent) + def __init__(self, parent: Optional[TacticsAmbulanceCenter] = None) -> None: + super().__init__(parent) diff --git a/src/adf_core_python/core/component/tactics/tactics_ambulance_team.py b/src/adf_core_python/core/component/tactics/tactics_ambulance_team.py index c5ad2b4..5e2257b 100644 --- a/src/adf_core_python/core/component/tactics/tactics_ambulance_team.py +++ b/src/adf_core_python/core/component/tactics/tactics_ambulance_team.py @@ -6,5 +6,5 @@ class TacticsAmbulanceTeam(TacticsAgent): - def __init__(self, parent: Optional[TacticsAmbulanceTeam] = None) -> None: - super().__init__(parent) + def __init__(self, parent: Optional[TacticsAmbulanceTeam] = None) -> None: + super().__init__(parent) diff --git a/src/adf_core_python/core/component/tactics/tactics_center.py b/src/adf_core_python/core/component/tactics/tactics_center.py index 0e76a79..3e35bde 100644 --- a/src/adf_core_python/core/component/tactics/tactics_center.py +++ b/src/adf_core_python/core/component/tactics/tactics_center.py @@ -6,121 +6,121 @@ from adf_core_python.core.component.centralized.command_picker import CommandPicker if TYPE_CHECKING: - 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 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.abstract_module import AbstractModule + 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 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.abstract_module import AbstractModule class TacticsCenter(ABC): - def __init__(self, parent: Optional[TacticsCenter] = None) -> None: - self._parent = parent - self._modules: list[AbstractModule] = [] - self._command_pickers: list[CommandPicker] = [] - - @abstractmethod - def initialize( - 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 resume( - 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 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, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - precompute_data: PrecomputeData, - develop_data: DevelopData, - ) -> None: - raise NotImplementedError - - @abstractmethod - def think( - 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 - - def get_parent_tactics(self) -> Optional[TacticsCenter]: - return self._parent - - def register_module(self, module: AbstractModule) -> None: - self._modules.append(module) - - def unregister_module(self, module: AbstractModule) -> None: - self._modules.remove(module) - - def register_command_picker(self, command_picker: Any) -> None: - self._command_pickers.append(command_picker) - - def unregister_command_picker(self, command_picker: Any) -> None: - self._command_pickers.remove(command_picker) - - def module_precompute(self, precompute_data: PrecomputeData) -> None: - for module in self._modules: - module.precompute(precompute_data) - for command_picker in self._command_pickers: - command_picker.precompute(precompute_data) - - def module_resume(self, precompute_data: PrecomputeData) -> None: - for module in self._modules: - module.resume(precompute_data) - for command_picker in self._command_pickers: - command_picker.resume(precompute_data) - - def module_prepare(self) -> None: - for module in self._modules: - module.prepare() - for command_picker in self._command_pickers: - command_picker.prepare() - - def module_update_info(self, message_manager: MessageManager) -> None: - for module in self._modules: - module.update_info(message_manager) - for command_picker in self._command_pickers: - command_picker.update_info(message_manager) + def __init__(self, parent: Optional[TacticsCenter] = None) -> None: + self._parent = parent + self._modules: list[AbstractModule] = [] + self._command_pickers: list[CommandPicker] = [] + + @abstractmethod + def initialize( + 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 resume( + 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 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, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + develop_data: DevelopData, + ) -> None: + raise NotImplementedError + + @abstractmethod + def think( + 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 + + def get_parent_tactics(self) -> Optional[TacticsCenter]: + return self._parent + + def register_module(self, module: AbstractModule) -> None: + self._modules.append(module) + + def unregister_module(self, module: AbstractModule) -> None: + self._modules.remove(module) + + def register_command_picker(self, command_picker: Any) -> None: + self._command_pickers.append(command_picker) + + def unregister_command_picker(self, command_picker: Any) -> None: + self._command_pickers.remove(command_picker) + + def module_precompute(self, precompute_data: PrecomputeData) -> None: + for module in self._modules: + module.precompute(precompute_data) + for command_picker in self._command_pickers: + command_picker.precompute(precompute_data) + + def module_resume(self, precompute_data: PrecomputeData) -> None: + for module in self._modules: + module.resume(precompute_data) + for command_picker in self._command_pickers: + command_picker.resume(precompute_data) + + def module_prepare(self) -> None: + for module in self._modules: + module.prepare() + for command_picker in self._command_pickers: + command_picker.prepare() + + def module_update_info(self, message_manager: MessageManager) -> None: + for module in self._modules: + module.update_info(message_manager) + for command_picker in self._command_pickers: + command_picker.update_info(message_manager) diff --git a/src/adf_core_python/core/component/tactics/tactics_fire_brigade.py b/src/adf_core_python/core/component/tactics/tactics_fire_brigade.py index 1df16b3..75bc6b6 100644 --- a/src/adf_core_python/core/component/tactics/tactics_fire_brigade.py +++ b/src/adf_core_python/core/component/tactics/tactics_fire_brigade.py @@ -6,5 +6,5 @@ class TacticsFireBrigade(TacticsAgent): - def __init__(self, parent: Optional[TacticsFireBrigade] = None) -> None: - super().__init__(parent) + def __init__(self, parent: Optional[TacticsFireBrigade] = None) -> None: + super().__init__(parent) diff --git a/src/adf_core_python/core/component/tactics/tactics_fire_station.py b/src/adf_core_python/core/component/tactics/tactics_fire_station.py index 0b6ed40..acd2563 100644 --- a/src/adf_core_python/core/component/tactics/tactics_fire_station.py +++ b/src/adf_core_python/core/component/tactics/tactics_fire_station.py @@ -6,5 +6,5 @@ class TacticsFireStation(TacticsCenter): - def __init__(self, parent: Optional[TacticsFireStation] = None) -> None: - super().__init__(parent) + def __init__(self, parent: Optional[TacticsFireStation] = None) -> None: + super().__init__(parent) diff --git a/src/adf_core_python/core/component/tactics/tactics_police_force.py b/src/adf_core_python/core/component/tactics/tactics_police_force.py index a098128..750e6f2 100644 --- a/src/adf_core_python/core/component/tactics/tactics_police_force.py +++ b/src/adf_core_python/core/component/tactics/tactics_police_force.py @@ -6,5 +6,5 @@ class TacticsPoliceForce(TacticsAgent): - def __init__(self, parent: Optional[TacticsPoliceForce] = None) -> None: - super().__init__(parent) + def __init__(self, parent: Optional[TacticsPoliceForce] = None) -> None: + super().__init__(parent) diff --git a/src/adf_core_python/core/component/tactics/tactics_police_office.py b/src/adf_core_python/core/component/tactics/tactics_police_office.py index 70950e1..a47debd 100644 --- a/src/adf_core_python/core/component/tactics/tactics_police_office.py +++ b/src/adf_core_python/core/component/tactics/tactics_police_office.py @@ -6,5 +6,5 @@ class TacticsPoliceOffice(TacticsCenter): - def __init__(self, parent: Optional[TacticsPoliceOffice] = None) -> None: - super().__init__(parent) + def __init__(self, parent: Optional[TacticsPoliceOffice] = None) -> None: + super().__init__(parent) diff --git a/src/adf_core_python/core/config/config.py b/src/adf_core_python/core/config/config.py index 5f55aea..a2f98a7 100644 --- a/src/adf_core_python/core/config/config.py +++ b/src/adf_core_python/core/config/config.py @@ -4,40 +4,40 @@ class Config: - def __init__(self, config_file: Optional[str] = None) -> None: - self.config: dict[str, Any] = {} - if config_file: - self.config = self.read_from_yaml(config_file) - self.config = self.flatten(self.config) - - def set_value(self, key: str, value: Any) -> None: - self.config[key] = value - - def get_value(self, key: str, default: Any = None) -> Any: - return self.config.get(key, default) - - def read_from_yaml(self, file_name: str) -> dict[str, Any]: - try: - with open(file_name, mode="r", encoding="utf-8") as file: - data = safe_load(file) - except FileNotFoundError: - raise FileNotFoundError(f"Config file not found: {file_name}") - except Exception as e: - raise Exception(f"Error reading config file: {file_name}, {e}") - - return data - - def flatten( - self, data: dict[str, Any], parent_key: str = "", sep: str = "." - ) -> dict[str, Any]: - flatten_data = {} - for key, value in data.items(): - new_key = f"{parent_key}{sep}{key}" if parent_key else key - if isinstance(value, dict): - flatten_data.update(self.flatten(value, new_key, sep=sep)) - else: - flatten_data[new_key] = value - return flatten_data - - def __str__(self) -> str: - return str(self.config) + def __init__(self, config_file: Optional[str] = None) -> None: + self.config: dict[str, Any] = {} + if config_file: + self.config = self.read_from_yaml(config_file) + self.config = self.flatten(self.config) + + def set_value(self, key: str, value: Any) -> None: + self.config[key] = value + + def get_value(self, key: str, default: Any = None) -> Any: + return self.config.get(key, default) + + def read_from_yaml(self, file_name: str) -> dict[str, Any]: + try: + with open(file_name, mode="r", encoding="utf-8") as file: + data = safe_load(file) + except FileNotFoundError: + raise FileNotFoundError(f"Config file not found: {file_name}") + except Exception as e: + raise Exception(f"Error reading config file: {file_name}, {e}") + + return data + + def flatten( + self, data: dict[str, Any], parent_key: str = "", sep: str = "." + ) -> dict[str, Any]: + flatten_data = {} + for key, value in data.items(): + new_key = f"{parent_key}{sep}{key}" if parent_key else key + if isinstance(value, dict): + flatten_data.update(self.flatten(value, new_key, sep=sep)) + else: + flatten_data[new_key] = value + return flatten_data + + def __str__(self) -> str: + return str(self.config) diff --git a/src/adf_core_python/core/gateway/component/module/algorithm/gateway_clustering.py b/src/adf_core_python/core/gateway/component/module/algorithm/gateway_clustering.py index c01047f..8f0c902 100644 --- a/src/adf_core_python/core/gateway/component/module/algorithm/gateway_clustering.py +++ b/src/adf_core_python/core/gateway/component/module/algorithm/gateway_clustering.py @@ -7,88 +7,88 @@ from adf_core_python.core.component.module.algorithm.clustering import Clustering from adf_core_python.core.gateway.component.module.gateway_abstract_module import ( - GatewayAbstractModule, + GatewayAbstractModule, ) if TYPE_CHECKING: - from rcrscore.entities.entity import Entity + from rcrscore.entities.entity import Entity - 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 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.gateway.gateway_module import GatewayModule + 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 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.gateway.gateway_module import GatewayModule class GatewayClustering(GatewayAbstractModule, Clustering): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - gateway_module: GatewayModule, - ) -> None: - super().__init__( - agent_info, - world_info, - scenario_info, - module_manager, - develop_data, - gateway_module, - ) - - def precompute(self, precompute_data: PrecomputeData) -> GatewayClustering: - super().precompute(precompute_data) - return self - - def resume(self, precompute_data: PrecomputeData) -> GatewayClustering: - super().resume(precompute_data) - return self - - def prepare(self) -> GatewayClustering: - super().prepare() - return self - - def update_info(self, message_manager: MessageManager) -> GatewayClustering: - super().update_info(message_manager) - return self - - def calculate(self) -> GatewayClustering: - super().calculate() - return self - - def get_cluster_number(self) -> int: - result = self._gateway_module.execute("getClusterNumber") - return int(result.get_value("ClusterNumber") or 0) - - def get_cluster_index(self, entity_id: EntityID) -> int: - arguments: dict[str, str] = {"EntityID": str(entity_id.get_value())} - result = self._gateway_module.execute("getClusterIndex(EntityID)", arguments) - return int(result.get_value("ClusterIndex") or 0) - - def get_cluster_entities(self, cluster_index: int) -> list[Entity]: - arguments: dict[str, str] = {"Index": str(cluster_index)} - result = self._gateway_module.execute("getClusterEntities(int)", arguments) - json_str = result.get_value("EntityIDs") or "[]" - entity_ids: list[int] = json.loads(json_str) - entities: list[Entity] = [] - for entity_id in entity_ids: - entity = self._world_info.get_entity(EntityID(entity_id)) - if entity is not None: - entities.append(entity) - return entities - - def get_cluster_entity_ids(self, cluster_index: int) -> list[EntityID]: - arguments: dict[str, str] = {"Index": str(cluster_index)} - result = self._gateway_module.execute("getClusterEntityIDs(int)", arguments) - json_str = result.get_value("EntityIDs") or "[]" - raw_entity_ids: list[int] = json.loads(json_str) - entity_ids: list[EntityID] = [] - for entity_id in raw_entity_ids: - entity_ids.append(EntityID(entity_id)) - return entity_ids + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + gateway_module: GatewayModule, + ) -> None: + super().__init__( + agent_info, + world_info, + scenario_info, + module_manager, + develop_data, + gateway_module, + ) + + def precompute(self, precompute_data: PrecomputeData) -> GatewayClustering: + super().precompute(precompute_data) + return self + + def resume(self, precompute_data: PrecomputeData) -> GatewayClustering: + super().resume(precompute_data) + return self + + def prepare(self) -> GatewayClustering: + super().prepare() + return self + + def update_info(self, message_manager: MessageManager) -> GatewayClustering: + super().update_info(message_manager) + return self + + def calculate(self) -> GatewayClustering: + super().calculate() + return self + + def get_cluster_number(self) -> int: + result = self._gateway_module.execute("getClusterNumber") + return int(result.get_value("ClusterNumber") or 0) + + def get_cluster_index(self, entity_id: EntityID) -> int: + arguments: dict[str, str] = {"EntityID": str(entity_id.get_value())} + result = self._gateway_module.execute("getClusterIndex(EntityID)", arguments) + return int(result.get_value("ClusterIndex") or 0) + + def get_cluster_entities(self, cluster_index: int) -> list[Entity]: + arguments: dict[str, str] = {"Index": str(cluster_index)} + result = self._gateway_module.execute("getClusterEntities(int)", arguments) + json_str = result.get_value("EntityIDs") or "[]" + entity_ids: list[int] = json.loads(json_str) + entities: list[Entity] = [] + for entity_id in entity_ids: + entity = self._world_info.get_entity(EntityID(entity_id)) + if entity is not None: + entities.append(entity) + return entities + + def get_cluster_entity_ids(self, cluster_index: int) -> list[EntityID]: + arguments: dict[str, str] = {"Index": str(cluster_index)} + result = self._gateway_module.execute("getClusterEntityIDs(int)", arguments) + json_str = result.get_value("EntityIDs") or "[]" + raw_entity_ids: list[int] = json.loads(json_str) + entity_ids: list[EntityID] = [] + for entity_id in raw_entity_ids: + entity_ids.append(EntityID(entity_id)) + return entity_ids diff --git a/src/adf_core_python/core/gateway/component/module/algorithm/gateway_path_planning.py b/src/adf_core_python/core/gateway/component/module/algorithm/gateway_path_planning.py index ef4df09..76a146d 100644 --- a/src/adf_core_python/core/gateway/component/module/algorithm/gateway_path_planning.py +++ b/src/adf_core_python/core/gateway/component/module/algorithm/gateway_path_planning.py @@ -7,101 +7,97 @@ from adf_core_python.core.component.module.algorithm.path_planning import PathPlanning from adf_core_python.core.gateway.component.module.gateway_abstract_module import ( - GatewayAbstractModule, + GatewayAbstractModule, ) if TYPE_CHECKING: - 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 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.gateway.gateway_module import GatewayModule + 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 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.gateway.gateway_module import GatewayModule class GatewayPathPlanning(GatewayAbstractModule, PathPlanning): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - gateway_module: GatewayModule, - ) -> None: - super().__init__( - agent_info, - world_info, - scenario_info, - module_manager, - develop_data, - gateway_module, - ) + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + gateway_module: GatewayModule, + ) -> None: + super().__init__( + agent_info, + world_info, + scenario_info, + module_manager, + develop_data, + gateway_module, + ) - def precompute(self, precompute_data: PrecomputeData) -> GatewayPathPlanning: - super().precompute(precompute_data) - return self + def precompute(self, precompute_data: PrecomputeData) -> GatewayPathPlanning: + super().precompute(precompute_data) + return self - def resume(self, precompute_data: PrecomputeData) -> GatewayPathPlanning: - super().resume(precompute_data) - return self + def resume(self, precompute_data: PrecomputeData) -> GatewayPathPlanning: + super().resume(precompute_data) + return self - def prepare(self) -> GatewayPathPlanning: - super().prepare() - return self + def prepare(self) -> GatewayPathPlanning: + super().prepare() + return self - def update_info(self, message_manager: MessageManager) -> GatewayPathPlanning: - super().update_info(message_manager) - return self + def update_info(self, message_manager: MessageManager) -> GatewayPathPlanning: + super().update_info(message_manager) + return self - def calculate(self) -> GatewayPathPlanning: - super().calculate() - return self + def calculate(self) -> GatewayPathPlanning: + super().calculate() + return self - def get_path( - self, from_entity_id: EntityID, to_entity_id: EntityID - ) -> list[EntityID]: - arguments: dict[str, str] = { - "From": str(from_entity_id.get_value()), - "To": str(to_entity_id.get_value()), - } - result = self._gateway_module.execute( - "getResult(EntityID, EntityID)", arguments - ) - json_str = result.get_value("Result") or "[]" - raw_entity_ids: list[int] = json.loads(json_str) - entity_ids: list[EntityID] = [] - for entity_id in raw_entity_ids: - entity_ids.append(EntityID(entity_id)) - return entity_ids + def get_path( + self, from_entity_id: EntityID, to_entity_id: EntityID + ) -> list[EntityID]: + arguments: dict[str, str] = { + "From": str(from_entity_id.get_value()), + "To": str(to_entity_id.get_value()), + } + result = self._gateway_module.execute("getResult(EntityID, EntityID)", arguments) + json_str = result.get_value("Result") or "[]" + raw_entity_ids: list[int] = json.loads(json_str) + entity_ids: list[EntityID] = [] + for entity_id in raw_entity_ids: + entity_ids.append(EntityID(entity_id)) + return entity_ids - def get_path_to_multiple_destinations( - self, from_entity_id: EntityID, destination_entity_ids: set[EntityID] - ) -> list[EntityID]: - arguments: dict[str, str] = { - "From": str(from_entity_id.get_value()), - "Destinations": json.dumps( - [entity_id.get_value() for entity_id in destination_entity_ids] - ), - } - result = self._gateway_module.execute( - "getResult(EntityID, List[EntityID])", arguments - ) - json_str = result.get_value("Result") or "[]" - raw_entity_ids: list[int] = json.loads(json_str) - entity_ids: list[EntityID] = [] - for entity_id in raw_entity_ids: - entity_ids.append(EntityID(entity_id)) - return entity_ids + def get_path_to_multiple_destinations( + self, from_entity_id: EntityID, destination_entity_ids: set[EntityID] + ) -> list[EntityID]: + arguments: dict[str, str] = { + "From": str(from_entity_id.get_value()), + "Destinations": json.dumps( + [entity_id.get_value() for entity_id in destination_entity_ids] + ), + } + result = self._gateway_module.execute( + "getResult(EntityID, List[EntityID])", arguments + ) + json_str = result.get_value("Result") or "[]" + raw_entity_ids: list[int] = json.loads(json_str) + entity_ids: list[EntityID] = [] + for entity_id in raw_entity_ids: + entity_ids.append(EntityID(entity_id)) + return entity_ids - def get_distance(self, from_entity_id: EntityID, to_entity_id: EntityID) -> float: - arguments: dict[str, str] = { - "From": str(from_entity_id.get_value()), - "To": str(to_entity_id.get_value()), - } - result = self._gateway_module.execute( - "getDistance(EntityID, EntityID)", arguments - ) - return float(result.get_value("Result") or 0.0) + def get_distance(self, from_entity_id: EntityID, to_entity_id: EntityID) -> float: + arguments: dict[str, str] = { + "From": str(from_entity_id.get_value()), + "To": str(to_entity_id.get_value()), + } + result = self._gateway_module.execute("getDistance(EntityID, EntityID)", arguments) + return float(result.get_value("Result") or 0.0) diff --git a/src/adf_core_python/core/gateway/component/module/complex/gateway_ambulance_target_allocator.py b/src/adf_core_python/core/gateway/component/module/complex/gateway_ambulance_target_allocator.py index f570436..fcd4902 100644 --- a/src/adf_core_python/core/gateway/component/module/complex/gateway_ambulance_target_allocator.py +++ b/src/adf_core_python/core/gateway/component/module/complex/gateway_ambulance_target_allocator.py @@ -3,64 +3,62 @@ from typing import TYPE_CHECKING from adf_core_python.core.component.module.complex.ambulance_target_allocator import ( - AmbulanceTargetAllocator, + AmbulanceTargetAllocator, ) from adf_core_python.core.gateway.component.module.complex.gateway_target_allocator import ( - GatewayTargetAllocator, + GatewayTargetAllocator, ) if TYPE_CHECKING: - 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 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.gateway.gateway_module import GatewayModule + 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 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.gateway.gateway_module import GatewayModule class GatewayAmbulanceTargetAllocator(GatewayTargetAllocator, AmbulanceTargetAllocator): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - gateway_module: GatewayModule, - ) -> None: - super().__init__( - agent_info, - world_info, - scenario_info, - module_manager, - develop_data, - gateway_module, - ) + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + gateway_module: GatewayModule, + ) -> None: + super().__init__( + agent_info, + world_info, + scenario_info, + module_manager, + develop_data, + gateway_module, + ) - def precompute( - self, precompute_data: PrecomputeData - ) -> GatewayAmbulanceTargetAllocator: - super().precompute(precompute_data) - return self + def precompute( + self, precompute_data: PrecomputeData + ) -> GatewayAmbulanceTargetAllocator: + super().precompute(precompute_data) + return self - def resume( - self, precompute_data: PrecomputeData - ) -> GatewayAmbulanceTargetAllocator: - super().resume(precompute_data) - return self + def resume(self, precompute_data: PrecomputeData) -> GatewayAmbulanceTargetAllocator: + super().resume(precompute_data) + return self - def prepare(self) -> GatewayAmbulanceTargetAllocator: - super().prepare() - return self + def prepare(self) -> GatewayAmbulanceTargetAllocator: + super().prepare() + return self - def update_info( - self, message_manager: MessageManager - ) -> GatewayAmbulanceTargetAllocator: - super().update_info(message_manager) - return self + def update_info( + self, message_manager: MessageManager + ) -> GatewayAmbulanceTargetAllocator: + super().update_info(message_manager) + return self - def calculate(self) -> GatewayAmbulanceTargetAllocator: - super().calculate() - return self + def calculate(self) -> GatewayAmbulanceTargetAllocator: + super().calculate() + return self diff --git a/src/adf_core_python/core/gateway/component/module/complex/gateway_fire_target_allocator.py b/src/adf_core_python/core/gateway/component/module/complex/gateway_fire_target_allocator.py index 69fb643..c3b4a78 100644 --- a/src/adf_core_python/core/gateway/component/module/complex/gateway_fire_target_allocator.py +++ b/src/adf_core_python/core/gateway/component/module/complex/gateway_fire_target_allocator.py @@ -3,60 +3,58 @@ from typing import TYPE_CHECKING from adf_core_python.core.component.module.complex.fire_target_allocator import ( - FireTargetAllocator, + FireTargetAllocator, ) from adf_core_python.core.gateway.component.module.complex.gateway_target_allocator import ( - GatewayTargetAllocator, + GatewayTargetAllocator, ) if TYPE_CHECKING: - 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 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.gateway.gateway_module import GatewayModule + 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 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.gateway.gateway_module import GatewayModule class GatewayFireTargetAllocator(GatewayTargetAllocator, FireTargetAllocator): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - gateway_module: GatewayModule, - ) -> None: - super().__init__( - agent_info, - world_info, - scenario_info, - module_manager, - develop_data, - gateway_module, - ) - - def precompute(self, precompute_data: PrecomputeData) -> GatewayFireTargetAllocator: - super().precompute(precompute_data) - return self - - def resume(self, precompute_data: PrecomputeData) -> GatewayFireTargetAllocator: - super().resume(precompute_data) - return self - - def prepare(self) -> GatewayFireTargetAllocator: - super().prepare() - return self - - def update_info( - self, message_manager: MessageManager - ) -> GatewayFireTargetAllocator: - super().update_info(message_manager) - return self - - def calculate(self) -> GatewayFireTargetAllocator: - super().calculate() - return self + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + gateway_module: GatewayModule, + ) -> None: + super().__init__( + agent_info, + world_info, + scenario_info, + module_manager, + develop_data, + gateway_module, + ) + + def precompute(self, precompute_data: PrecomputeData) -> GatewayFireTargetAllocator: + super().precompute(precompute_data) + return self + + def resume(self, precompute_data: PrecomputeData) -> GatewayFireTargetAllocator: + super().resume(precompute_data) + return self + + def prepare(self) -> GatewayFireTargetAllocator: + super().prepare() + return self + + def update_info(self, message_manager: MessageManager) -> GatewayFireTargetAllocator: + super().update_info(message_manager) + return self + + def calculate(self) -> GatewayFireTargetAllocator: + super().calculate() + return self diff --git a/src/adf_core_python/core/gateway/component/module/complex/gateway_human_detector.py b/src/adf_core_python/core/gateway/component/module/complex/gateway_human_detector.py index 7692f07..41b1520 100644 --- a/src/adf_core_python/core/gateway/component/module/complex/gateway_human_detector.py +++ b/src/adf_core_python/core/gateway/component/module/complex/gateway_human_detector.py @@ -5,58 +5,58 @@ from rcrscore.entities.human import Human from adf_core_python.core.component.module.complex.human_detector import ( - HumanDetector, + HumanDetector, ) from adf_core_python.core.gateway.component.module.complex.gateway_target_detector import ( - GatewayTargetDetector, + GatewayTargetDetector, ) if TYPE_CHECKING: - 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 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.gateway.gateway_module import GatewayModule + 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 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.gateway.gateway_module import GatewayModule class GatewayHumanDetector(GatewayTargetDetector[Human], HumanDetector): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - gateway_module: GatewayModule, - ) -> None: - super().__init__( - agent_info, - world_info, - scenario_info, - module_manager, - develop_data, - gateway_module, - ) - - def precompute(self, precompute_data: PrecomputeData) -> GatewayHumanDetector: - super().precompute(precompute_data) - return self - - def resume(self, precompute_data: PrecomputeData) -> GatewayHumanDetector: - super().resume(precompute_data) - return self - - def prepare(self) -> GatewayHumanDetector: - super().prepare() - return self - - def update_info(self, message_manager: MessageManager) -> GatewayHumanDetector: - super().update_info(message_manager) - return self - - def calculate(self) -> GatewayHumanDetector: - super().calculate() - return self + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + gateway_module: GatewayModule, + ) -> None: + super().__init__( + agent_info, + world_info, + scenario_info, + module_manager, + develop_data, + gateway_module, + ) + + def precompute(self, precompute_data: PrecomputeData) -> GatewayHumanDetector: + super().precompute(precompute_data) + return self + + def resume(self, precompute_data: PrecomputeData) -> GatewayHumanDetector: + super().resume(precompute_data) + return self + + def prepare(self) -> GatewayHumanDetector: + super().prepare() + return self + + def update_info(self, message_manager: MessageManager) -> GatewayHumanDetector: + super().update_info(message_manager) + return self + + def calculate(self) -> GatewayHumanDetector: + super().calculate() + return self diff --git a/src/adf_core_python/core/gateway/component/module/complex/gateway_police_target_allocator.py b/src/adf_core_python/core/gateway/component/module/complex/gateway_police_target_allocator.py index bacc0bb..a9ea780 100644 --- a/src/adf_core_python/core/gateway/component/module/complex/gateway_police_target_allocator.py +++ b/src/adf_core_python/core/gateway/component/module/complex/gateway_police_target_allocator.py @@ -3,62 +3,60 @@ from typing import TYPE_CHECKING from adf_core_python.core.component.module.complex.police_target_allocator import ( - PoliceTargetAllocator, + PoliceTargetAllocator, ) from adf_core_python.core.gateway.component.module.complex.gateway_target_allocator import ( - GatewayTargetAllocator, + GatewayTargetAllocator, ) if TYPE_CHECKING: - 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 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.gateway.gateway_module import GatewayModule + 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 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.gateway.gateway_module import GatewayModule class GatewayPoliceTargetAllocator(GatewayTargetAllocator, PoliceTargetAllocator): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - gateway_module: GatewayModule, - ) -> None: - super().__init__( - agent_info, - world_info, - scenario_info, - module_manager, - develop_data, - gateway_module, - ) - - def precompute( - self, precompute_data: PrecomputeData - ) -> GatewayPoliceTargetAllocator: - super().precompute(precompute_data) - return self - - def resume(self, precompute_data: PrecomputeData) -> GatewayPoliceTargetAllocator: - super().resume(precompute_data) - return self - - def prepare(self) -> GatewayPoliceTargetAllocator: - super().prepare() - return self - - def update_info( - self, message_manager: MessageManager - ) -> GatewayPoliceTargetAllocator: - super().update_info(message_manager) - return self - - def calculate(self) -> GatewayPoliceTargetAllocator: - super().calculate() - return self + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + gateway_module: GatewayModule, + ) -> None: + super().__init__( + agent_info, + world_info, + scenario_info, + module_manager, + develop_data, + gateway_module, + ) + + def precompute(self, precompute_data: PrecomputeData) -> GatewayPoliceTargetAllocator: + super().precompute(precompute_data) + return self + + def resume(self, precompute_data: PrecomputeData) -> GatewayPoliceTargetAllocator: + super().resume(precompute_data) + return self + + def prepare(self) -> GatewayPoliceTargetAllocator: + super().prepare() + return self + + def update_info( + self, message_manager: MessageManager + ) -> GatewayPoliceTargetAllocator: + super().update_info(message_manager) + return self + + def calculate(self) -> GatewayPoliceTargetAllocator: + super().calculate() + return self diff --git a/src/adf_core_python/core/gateway/component/module/complex/gateway_road_detector.py b/src/adf_core_python/core/gateway/component/module/complex/gateway_road_detector.py index bfceb81..e5b478a 100644 --- a/src/adf_core_python/core/gateway/component/module/complex/gateway_road_detector.py +++ b/src/adf_core_python/core/gateway/component/module/complex/gateway_road_detector.py @@ -7,54 +7,54 @@ from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.component.module.complex.road_detector import RoadDetector from adf_core_python.core.gateway.component.module.complex.gateway_target_detector import ( - GatewayTargetDetector, + GatewayTargetDetector, ) if TYPE_CHECKING: - 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 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.gateway.gateway_module import GatewayModule + 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 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.gateway.gateway_module import GatewayModule class GatewayRoadDetector(GatewayTargetDetector[Road], RoadDetector): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - gateway_module: GatewayModule, - ) -> None: - super().__init__( - agent_info, - world_info, - scenario_info, - module_manager, - develop_data, - gateway_module, - ) - - def precompute(self, precompute_data: PrecomputeData) -> GatewayRoadDetector: - super().precompute(precompute_data) - return self - - def resume(self, precompute_data: PrecomputeData) -> GatewayRoadDetector: - super().resume(precompute_data) - return self - - def prepare(self) -> GatewayRoadDetector: - super().prepare() - return self - - def update_info(self, message_manager: MessageManager) -> GatewayRoadDetector: - super().update_info(message_manager) - return self - - def calculate(self) -> GatewayRoadDetector: - super().calculate() - return self + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + gateway_module: GatewayModule, + ) -> None: + super().__init__( + agent_info, + world_info, + scenario_info, + module_manager, + develop_data, + gateway_module, + ) + + def precompute(self, precompute_data: PrecomputeData) -> GatewayRoadDetector: + super().precompute(precompute_data) + return self + + def resume(self, precompute_data: PrecomputeData) -> GatewayRoadDetector: + super().resume(precompute_data) + return self + + def prepare(self) -> GatewayRoadDetector: + super().prepare() + return self + + def update_info(self, message_manager: MessageManager) -> GatewayRoadDetector: + super().update_info(message_manager) + return self + + def calculate(self) -> GatewayRoadDetector: + super().calculate() + return self diff --git a/src/adf_core_python/core/gateway/component/module/complex/gateway_search.py b/src/adf_core_python/core/gateway/component/module/complex/gateway_search.py index bf37e2c..083f3cc 100644 --- a/src/adf_core_python/core/gateway/component/module/complex/gateway_search.py +++ b/src/adf_core_python/core/gateway/component/module/complex/gateway_search.py @@ -4,55 +4,55 @@ from adf_core_python.core.component.module.complex.search import Search from adf_core_python.core.gateway.component.module.complex.gateway_target_detector import ( - GatewayTargetDetector, + GatewayTargetDetector, ) if TYPE_CHECKING: - 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 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.gateway.gateway_module import GatewayModule + 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 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.gateway.gateway_module import GatewayModule class GatewaySearch(GatewayTargetDetector, Search): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - gateway_module: GatewayModule, - ) -> None: - super().__init__( - agent_info, - world_info, - scenario_info, - module_manager, - develop_data, - gateway_module, - ) - - def precompute(self, precompute_data: PrecomputeData) -> GatewaySearch: - super().precompute(precompute_data) - return self - - def resume(self, precompute_data: PrecomputeData) -> GatewaySearch: - super().resume(precompute_data) - return self - - def prepare(self) -> GatewaySearch: - super().prepare() - return self - - def update_info(self, message_manager: MessageManager) -> GatewaySearch: - super().update_info(message_manager) - return self - - def calculate(self) -> GatewaySearch: - super().calculate() - return self + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + gateway_module: GatewayModule, + ) -> None: + super().__init__( + agent_info, + world_info, + scenario_info, + module_manager, + develop_data, + gateway_module, + ) + + def precompute(self, precompute_data: PrecomputeData) -> GatewaySearch: + super().precompute(precompute_data) + return self + + def resume(self, precompute_data: PrecomputeData) -> GatewaySearch: + super().resume(precompute_data) + return self + + def prepare(self) -> GatewaySearch: + super().prepare() + return self + + def update_info(self, message_manager: MessageManager) -> GatewaySearch: + super().update_info(message_manager) + return self + + def calculate(self) -> GatewaySearch: + super().calculate() + return self diff --git a/src/adf_core_python/core/gateway/component/module/complex/gateway_target_allocator.py b/src/adf_core_python/core/gateway/component/module/complex/gateway_target_allocator.py index df35491..1765c47 100644 --- a/src/adf_core_python/core/gateway/component/module/complex/gateway_target_allocator.py +++ b/src/adf_core_python/core/gateway/component/module/complex/gateway_target_allocator.py @@ -5,70 +5,68 @@ from rcrscore.entities import EntityID from adf_core_python.core.component.module.complex.target_allocator import ( - TargetAllocator, + TargetAllocator, ) from adf_core_python.core.gateway.component.module.gateway_abstract_module import ( - GatewayAbstractModule, + GatewayAbstractModule, ) if TYPE_CHECKING: - 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 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.gateway.gateway_module import GatewayModule + 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 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.gateway.gateway_module import GatewayModule class GatewayTargetAllocator(GatewayAbstractModule, TargetAllocator): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - gateway_module: GatewayModule, - ) -> None: - super().__init__( - agent_info, - world_info, - scenario_info, - module_manager, - develop_data, - gateway_module, - ) + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + gateway_module: GatewayModule, + ) -> None: + super().__init__( + agent_info, + world_info, + scenario_info, + module_manager, + develop_data, + gateway_module, + ) - def precompute(self, precompute_data: PrecomputeData) -> GatewayTargetAllocator: - super().precompute(precompute_data) - return self + def precompute(self, precompute_data: PrecomputeData) -> GatewayTargetAllocator: + super().precompute(precompute_data) + return self - def resume(self, precompute_data: PrecomputeData) -> GatewayTargetAllocator: - super().resume(precompute_data) - return self + def resume(self, precompute_data: PrecomputeData) -> GatewayTargetAllocator: + super().resume(precompute_data) + return self - def prepare(self) -> GatewayTargetAllocator: - super().prepare() - return self + def prepare(self) -> GatewayTargetAllocator: + super().prepare() + return self - def update_info(self, message_manager: MessageManager) -> GatewayTargetAllocator: - super().update_info(message_manager) - return self + def update_info(self, message_manager: MessageManager) -> GatewayTargetAllocator: + super().update_info(message_manager) + return self - def calculate(self) -> GatewayTargetAllocator: - super().calculate() - return self + def calculate(self) -> GatewayTargetAllocator: + super().calculate() + return self - def get_result(self) -> dict[EntityID, EntityID]: - response = self._gateway_module.execute("getResult") - response_keys = response.data.keys() - result: dict[EntityID, EntityID] = {} - for key in response_keys: - value = response.get_value(key) - result[EntityID(int(key))] = EntityID( - int(value if value is not None else "-1") - ) + def get_result(self) -> dict[EntityID, EntityID]: + response = self._gateway_module.execute("getResult") + response_keys = response.data.keys() + result: dict[EntityID, EntityID] = {} + for key in response_keys: + value = response.get_value(key) + result[EntityID(int(key))] = EntityID(int(value if value is not None else "-1")) - return result + return result diff --git a/src/adf_core_python/core/gateway/component/module/complex/gateway_target_detector.py b/src/adf_core_python/core/gateway/component/module/complex/gateway_target_detector.py index 1f50383..4de8f36 100644 --- a/src/adf_core_python/core/gateway/component/module/complex/gateway_target_detector.py +++ b/src/adf_core_python/core/gateway/component/module/complex/gateway_target_detector.py @@ -7,64 +7,64 @@ from adf_core_python.core.component.module.complex.target_detector import TargetDetector from adf_core_python.core.gateway.component.module.gateway_abstract_module import ( - GatewayAbstractModule, + GatewayAbstractModule, ) if TYPE_CHECKING: - 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 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.gateway.gateway_module import GatewayModule + 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 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.gateway.gateway_module import GatewayModule T = TypeVar("T", bound=Entity) class GatewayTargetDetector(GatewayAbstractModule, TargetDetector, Generic[T]): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - gateway_module: GatewayModule, - ) -> None: - super().__init__( - agent_info, - world_info, - scenario_info, - module_manager, - develop_data, - gateway_module, - ) + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + gateway_module: GatewayModule, + ) -> None: + super().__init__( + agent_info, + world_info, + scenario_info, + module_manager, + develop_data, + gateway_module, + ) - def precompute(self, precompute_data: PrecomputeData) -> GatewayTargetDetector[T]: - super().precompute(precompute_data) - return self + def precompute(self, precompute_data: PrecomputeData) -> GatewayTargetDetector[T]: + super().precompute(precompute_data) + return self - def resume(self, precompute_data: PrecomputeData) -> GatewayTargetDetector[T]: - super().resume(precompute_data) - return self + def resume(self, precompute_data: PrecomputeData) -> GatewayTargetDetector[T]: + super().resume(precompute_data) + return self - def prepare(self) -> GatewayTargetDetector[T]: - super().prepare() - return self + def prepare(self) -> GatewayTargetDetector[T]: + super().prepare() + return self - def update_info(self, message_manager: MessageManager) -> GatewayTargetDetector[T]: - super().update_info(message_manager) - return self + def update_info(self, message_manager: MessageManager) -> GatewayTargetDetector[T]: + super().update_info(message_manager) + return self - def calculate(self) -> GatewayTargetDetector[T]: - super().calculate() - return self + def calculate(self) -> GatewayTargetDetector[T]: + super().calculate() + return self - def get_target_entity_id(self) -> Optional[EntityID]: - result = self._gateway_module.execute("getTarget") - entity_id_str = result.get_value("EntityID") or "-1" - if entity_id_str == "-1": - return None - return EntityID(int(entity_id_str)) + def get_target_entity_id(self) -> Optional[EntityID]: + result = self._gateway_module.execute("getTarget") + entity_id_str = result.get_value("EntityID") or "-1" + if entity_id_str == "-1": + return None + return EntityID(int(entity_id_str)) diff --git a/src/adf_core_python/core/gateway/component/module/gateway_abstract_module.py b/src/adf_core_python/core/gateway/component/module/gateway_abstract_module.py index 857977b..0f740a0 100644 --- a/src/adf_core_python/core/gateway/component/module/gateway_abstract_module.py +++ b/src/adf_core_python/core/gateway/component/module/gateway_abstract_module.py @@ -5,51 +5,51 @@ from adf_core_python.core.component.module.abstract_module import AbstractModule if TYPE_CHECKING: - 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 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.gateway.gateway_module import GatewayModule + 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 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.gateway.gateway_module import GatewayModule class GatewayAbstractModule(AbstractModule): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - gateway_module: GatewayModule, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - self._gateway_module = gateway_module - - def precompute(self, precompute_data: PrecomputeData) -> GatewayAbstractModule: - super().precompute(precompute_data) - self._gateway_module.execute("precompute") - return self - - def resume(self, precompute_data: PrecomputeData) -> GatewayAbstractModule: - super().resume(precompute_data) - self._gateway_module.execute("resume") - return self - - def prepare(self) -> GatewayAbstractModule: - super().prepare() - self._gateway_module.execute("preparate") - return self - - def update_info(self, message_manager: MessageManager) -> GatewayAbstractModule: - super().update_info(message_manager) - self._gateway_module.execute("updateInfo") - return self - - def calculate(self) -> GatewayAbstractModule: - self._gateway_module.execute("calc") - return self + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + gateway_module: GatewayModule, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + self._gateway_module = gateway_module + + def precompute(self, precompute_data: PrecomputeData) -> GatewayAbstractModule: + super().precompute(precompute_data) + self._gateway_module.execute("precompute") + return self + + def resume(self, precompute_data: PrecomputeData) -> GatewayAbstractModule: + super().resume(precompute_data) + self._gateway_module.execute("resume") + return self + + def prepare(self) -> GatewayAbstractModule: + super().prepare() + self._gateway_module.execute("preparate") + return self + + def update_info(self, message_manager: MessageManager) -> GatewayAbstractModule: + super().update_info(message_manager) + self._gateway_module.execute("updateInfo") + return self + + def calculate(self) -> GatewayAbstractModule: + self._gateway_module.execute("calc") + return self diff --git a/src/adf_core_python/core/gateway/gateway_agent.py b/src/adf_core_python/core/gateway/gateway_agent.py index 7f04e19..7e886d7 100644 --- a/src/adf_core_python/core/gateway/gateway_agent.py +++ b/src/adf_core_python/core/gateway/gateway_agent.py @@ -12,108 +12,106 @@ from adf_core_python.core.gateway.message.am_update import AMUpdate from adf_core_python.core.gateway.message.ma_exec_response import MAExecResponse from adf_core_python.core.gateway.message.ma_module_response import ( - MAModuleResponse, + MAModuleResponse, ) from adf_core_python.core.gateway.message.moduleMessageFactory import ( - ModuleMessageFactory, + ModuleMessageFactory, ) from adf_core_python.core.logger.logger import get_logger if TYPE_CHECKING: - from adf_core_python.core.gateway.gateway_launcher import GatewayLauncher - from adf_core_python.core.gateway.gateway_module import GatewayModule + from adf_core_python.core.gateway.gateway_launcher import GatewayLauncher + from adf_core_python.core.gateway.gateway_module import GatewayModule class GatewayAgent: - def __init__(self, gateway_launcher: GatewayLauncher) -> None: - self._gateway_launcher = gateway_launcher - self.send_msg: Optional[Callable] = None - self._is_initialized = False - self._agent_info: Optional[AgentInfo] = None - self._world_info: Optional[WorldInfo] = None - self._scenario_info: Optional[ScenarioInfo] = None - self._gateway_modules: dict[str, GatewayModule] = {} - self._logger = get_logger(__name__) - - def get_module_count(self) -> int: - return len(self._gateway_modules) - - def add_gateway_module(self, gateway_module: GatewayModule) -> None: - self._gateway_modules[gateway_module.get_module_id()] = gateway_module - - def is_initialized(self) -> bool: - return self._is_initialized - - def set_initialize_data( - self, agent_info: AgentInfo, world_info: WorldInfo, scenario_info: ScenarioInfo - ) -> None: - self._agent_info = agent_info - self._world_info = world_info - self._scenario_info = scenario_info - - def initialize(self) -> None: - if self.send_msg is None: - raise RuntimeError("send_msg is None") - if ( - self._agent_info is None - or self._world_info is None - or self._scenario_info is None - ): - raise RuntimeError( - "Required variables is None, " - "You must exec set_initialized_data() before calling initialize()" - ) - - am_agent = AMAgent() - self.send_msg( - am_agent.write( - self._agent_info.get_entity_id(), - list(self._world_info.get_world_model().get_entities()), - self._scenario_info.get_config().config, - int(self._scenario_info.get_mode()), - ) - ) - self._is_initialized = True - - def update(self) -> None: - if self.send_msg is None: - raise RuntimeError("send_msg is None") - if self._agent_info is None or self._world_info is None: - raise RuntimeError( - "Required variables is None, " - "You must exec set_initialized_data() before calling update()" - ) - - am_update = AMUpdate() - self.send_msg( - am_update.write( - self._agent_info.get_time(), - self._world_info.get_change_set(), - self._agent_info.get_heard_commands(), - ) - ) - - def set_send_msg(self, connection_send_func: Callable) -> None: - self.send_msg = connection_send_func - - def message_received(self, msg: RCRSProto_pb2.MessageProto) -> None: - c_msg = ModuleMessageFactory().make_message(msg) - if isinstance(c_msg, MAModuleResponse): - if c_msg.module_id is None or c_msg.class_name is None: - raise RuntimeError("Failed to receive message") - - self._gateway_modules[c_msg.module_id].set_gateway_class_name( - c_msg.class_name - ) - self._gateway_modules[c_msg.module_id].set_is_initialized(True) - if isinstance(c_msg, MAExecResponse): - if c_msg.module_id is None: - raise RuntimeError("Failed to receive message") - - self._gateway_modules[c_msg.module_id].set_execute_response(c_msg.result) - self._gateway_modules[c_msg.module_id].set_is_executed(True) - - if msg.urn == CommandURN.AK_SPEAK: - if self.send_msg is None: - raise RuntimeError("send_msg is None") - self.send_msg(msg) + def __init__(self, gateway_launcher: GatewayLauncher) -> None: + self._gateway_launcher = gateway_launcher + self.send_msg: Optional[Callable] = None + self._is_initialized = False + self._agent_info: Optional[AgentInfo] = None + self._world_info: Optional[WorldInfo] = None + self._scenario_info: Optional[ScenarioInfo] = None + self._gateway_modules: dict[str, GatewayModule] = {} + self._logger = get_logger(__name__) + + def get_module_count(self) -> int: + return len(self._gateway_modules) + + def add_gateway_module(self, gateway_module: GatewayModule) -> None: + self._gateway_modules[gateway_module.get_module_id()] = gateway_module + + def is_initialized(self) -> bool: + return self._is_initialized + + def set_initialize_data( + self, agent_info: AgentInfo, world_info: WorldInfo, scenario_info: ScenarioInfo + ) -> None: + self._agent_info = agent_info + self._world_info = world_info + self._scenario_info = scenario_info + + def initialize(self) -> None: + if self.send_msg is None: + raise RuntimeError("send_msg is None") + if ( + self._agent_info is None + or self._world_info is None + or self._scenario_info is None + ): + raise RuntimeError( + "Required variables is None, " + "You must exec set_initialized_data() before calling initialize()" + ) + + am_agent = AMAgent() + self.send_msg( + am_agent.write( + self._agent_info.get_entity_id(), + list(self._world_info.get_world_model().get_entities()), + self._scenario_info.get_config().config, + int(self._scenario_info.get_mode()), + ) + ) + self._is_initialized = True + + def update(self) -> None: + if self.send_msg is None: + raise RuntimeError("send_msg is None") + if self._agent_info is None or self._world_info is None: + raise RuntimeError( + "Required variables is None, " + "You must exec set_initialized_data() before calling update()" + ) + + am_update = AMUpdate() + self.send_msg( + am_update.write( + self._agent_info.get_time(), + self._world_info.get_change_set(), + self._agent_info.get_heard_commands(), + ) + ) + + def set_send_msg(self, connection_send_func: Callable) -> None: + self.send_msg = connection_send_func + + def message_received(self, msg: RCRSProto_pb2.MessageProto) -> None: + c_msg = ModuleMessageFactory().make_message(msg) + if isinstance(c_msg, MAModuleResponse): + if c_msg.module_id is None or c_msg.class_name is None: + raise RuntimeError("Failed to receive message") + + self._gateway_modules[c_msg.module_id].set_gateway_class_name(c_msg.class_name) + self._gateway_modules[c_msg.module_id].set_is_initialized(True) + if isinstance(c_msg, MAExecResponse): + if c_msg.module_id is None: + raise RuntimeError("Failed to receive message") + + self._gateway_modules[c_msg.module_id].set_execute_response(c_msg.result) + self._gateway_modules[c_msg.module_id].set_is_executed(True) + + if msg.urn == CommandURN.AK_SPEAK: + if self.send_msg is None: + raise RuntimeError("send_msg is None") + self.send_msg(msg) diff --git a/src/adf_core_python/core/gateway/gateway_launcher.py b/src/adf_core_python/core/gateway/gateway_launcher.py index e320d24..47053c6 100644 --- a/src/adf_core_python/core/gateway/gateway_launcher.py +++ b/src/adf_core_python/core/gateway/gateway_launcher.py @@ -7,39 +7,39 @@ class GatewayLauncher: - def __init__(self, host: str, port: int, logger: BoundLogger) -> None: - self.host = host - self.port = port - self.logger = logger - pass - - def make_connection(self) -> Connection: - return Connection(self.host, self.port) - - def connect(self, gateway_agent: GatewayAgent) -> None: + def __init__(self, host: str, port: int, logger: BoundLogger) -> None: + self.host = host + self.port = port + self.logger = logger + pass + + def make_connection(self) -> Connection: + return Connection(self.host, self.port) + + def connect(self, gateway_agent: GatewayAgent) -> None: + self.logger.info( + f"{gateway_agent.__class__.__name__} connecting to {self.host}:{self.port}" + ) + connection = self.make_connection() + try: + connection.connect() + # ソケットが使用しているPORT番号を取得 + if connection.socket is not None: self.logger.info( - f"{gateway_agent.__class__.__name__} connecting to {self.host}:{self.port}" + f"Connected to {self.host}:{self.port} on port {connection.socket.getsockname()[1]}" ) - connection = self.make_connection() - try: - connection.connect() - # ソケットが使用しているPORT番号を取得 - if connection.socket is not None: - self.logger.info( - f"Connected to {self.host}:{self.port} on port {connection.socket.getsockname()[1]}" - ) - except socket.timeout: - self.logger.warning(f"Connection to {self.host}:{self.port} timed out") - return - except socket.error as e: - self.logger.error(f"Failed to connect to {self.host}:{self.port}") - self.logger.error(e) - return - - connection.message_received(gateway_agent.message_received) - gateway_agent.set_send_msg(connection.send_msg) - - try: - connection.parse_message_from_kernel() - except Exception as e: - self.logger.error(f"Failed to connect agent: {self.host}:{self.port} {e}") + except socket.timeout: + self.logger.warning(f"Connection to {self.host}:{self.port} timed out") + return + except socket.error as e: + self.logger.error(f"Failed to connect to {self.host}:{self.port}") + self.logger.error(e) + return + + connection.message_received(gateway_agent.message_received) + gateway_agent.set_send_msg(connection.send_msg) + + try: + connection.parse_message_from_kernel() + except Exception as e: + self.logger.error(f"Failed to connect agent: {self.host}:{self.port} {e}") diff --git a/src/adf_core_python/core/gateway/gateway_module.py b/src/adf_core_python/core/gateway/gateway_module.py index 68bb446..a5fa18d 100644 --- a/src/adf_core_python/core/gateway/gateway_module.py +++ b/src/adf_core_python/core/gateway/gateway_module.py @@ -9,77 +9,75 @@ class GatewayModule: - def __init__(self, gateway_agent: GatewayAgent): - self._gateway_agent = gateway_agent - self._module_id: str = str(uuid.uuid4()) - self._is_initialized = False - self._is_executed = False - self._gateway_class_name: str = "" - self._result: Optional[Config] = None - self._gateway_agent.add_gateway_module(self) - - def get_module_id(self) -> str: - return self._module_id - - def get_gateway_class_name(self) -> str: - return self._gateway_class_name - - def set_gateway_class_name(self, gateway_class_name: str) -> None: - self._gateway_class_name = gateway_class_name - - def get_is_initialized(self) -> bool: - return self._is_initialized - - def set_is_initialized(self, is_initialized: bool) -> None: - self._is_initialized = is_initialized - - def initialize(self, module_name: str, default_class_name: str) -> str: - if not self._gateway_agent.is_initialized(): - self._gateway_agent.initialize() - if self._gateway_agent.send_msg is None: - raise RuntimeError("send_msg is None") - - am_module = AMModule() - self._gateway_agent.send_msg( - am_module.write( - self._module_id, - module_name, - default_class_name, - ) - ) - - while not self.get_is_initialized(): - pass - - return self.get_gateway_class_name() - - def get_execute_response(self) -> Config: - if self._result is None: - raise RuntimeError("No execution result available") - return self._result - - def set_execute_response(self, result: Config) -> None: - self._result = result - - def get_is_executed(self) -> bool: - return self._is_executed - - def set_is_executed(self, _is_executed: bool) -> None: - self._is_executed = _is_executed - - def execute( - self, method_name: str, args: Optional[dict[str, str]] = None - ) -> Config: - if args is None: - args = {} - if self._gateway_agent.send_msg is None: - raise RuntimeError("send_msg is None") - - am_exec = AMExec() - self._gateway_agent.send_msg(am_exec.write(self._module_id, method_name, args)) - - while not self.get_is_executed(): - pass - - self.set_is_executed(False) - return self.get_execute_response() + def __init__(self, gateway_agent: GatewayAgent): + self._gateway_agent = gateway_agent + self._module_id: str = str(uuid.uuid4()) + self._is_initialized = False + self._is_executed = False + self._gateway_class_name: str = "" + self._result: Optional[Config] = None + self._gateway_agent.add_gateway_module(self) + + def get_module_id(self) -> str: + return self._module_id + + def get_gateway_class_name(self) -> str: + return self._gateway_class_name + + def set_gateway_class_name(self, gateway_class_name: str) -> None: + self._gateway_class_name = gateway_class_name + + def get_is_initialized(self) -> bool: + return self._is_initialized + + def set_is_initialized(self, is_initialized: bool) -> None: + self._is_initialized = is_initialized + + def initialize(self, module_name: str, default_class_name: str) -> str: + if not self._gateway_agent.is_initialized(): + self._gateway_agent.initialize() + if self._gateway_agent.send_msg is None: + raise RuntimeError("send_msg is None") + + am_module = AMModule() + self._gateway_agent.send_msg( + am_module.write( + self._module_id, + module_name, + default_class_name, + ) + ) + + while not self.get_is_initialized(): + pass + + return self.get_gateway_class_name() + + def get_execute_response(self) -> Config: + if self._result is None: + raise RuntimeError("No execution result available") + return self._result + + def set_execute_response(self, result: Config) -> None: + self._result = result + + def get_is_executed(self) -> bool: + return self._is_executed + + def set_is_executed(self, _is_executed: bool) -> None: + self._is_executed = _is_executed + + def execute(self, method_name: str, args: Optional[dict[str, str]] = None) -> Config: + if args is None: + args = {} + if self._gateway_agent.send_msg is None: + raise RuntimeError("send_msg is None") + + am_exec = AMExec() + self._gateway_agent.send_msg(am_exec.write(self._module_id, method_name, args)) + + while not self.get_is_executed(): + pass + + self.set_is_executed(False) + return self.get_execute_response() diff --git a/src/adf_core_python/core/gateway/message/am_agent.py b/src/adf_core_python/core/gateway/message/am_agent.py index aac4850..416f702 100644 --- a/src/adf_core_python/core/gateway/message/am_agent.py +++ b/src/adf_core_python/core/gateway/message/am_agent.py @@ -7,48 +7,46 @@ from rcrscore.urn.control_message import ControlMessageURN from adf_core_python.core.gateway.message.urn.urn import ( - ComponentModuleMSG, - ModuleMSG, + ComponentModuleMSG, + ModuleMSG, ) class AMAgent(AKControlMessage): - @staticmethod - def write( - agent_id: EntityID, - entities: list[Entity], - config: dict[str, Any], - mode: int, - ) -> RCRSProto_pb2.MessageProto: - entity_proto_list = [] - for entity in entities: - entity_proto = RCRSProto_pb2.EntityProto() - entity_proto.urn = entity.get_urn() - entity_proto.entityID = entity.get_entity_id().get_value() - - property_proto_list = [] - for k, v in entity.get_properties().items(): - property_proto_list.append(v.to_property_proto()) - entity_proto.properties.extend(property_proto_list) - entity_proto_list.append(entity_proto) - - entity_list_proto = RCRSProto_pb2.EntityListProto() - entity_list_proto.entities.extend(entity_proto_list) - - config_proto = RCRSProto_pb2.ConfigProto() - for key, value in config.items(): - config_proto.data[str(key)] = str(value) - - msg = RCRSProto_pb2.MessageProto() - msg.urn = AMAgent.get_urn() - msg.components[ComponentModuleMSG.AgentID].entityID = agent_id.get_value() - msg.components[ComponentModuleMSG.Entities].entityList.CopyFrom( - entity_list_proto - ) - msg.components[ComponentModuleMSG.Config].config.CopyFrom(config_proto) - msg.components[ComponentModuleMSG.Mode].intValue = mode - return msg - - @staticmethod - def get_urn() -> ControlMessageURN: - return ModuleMSG.AM_AGENT # type: ignore + @staticmethod + def write( + agent_id: EntityID, + entities: list[Entity], + config: dict[str, Any], + mode: int, + ) -> RCRSProto_pb2.MessageProto: + entity_proto_list = [] + for entity in entities: + entity_proto = RCRSProto_pb2.EntityProto() + entity_proto.urn = entity.get_urn() + entity_proto.entityID = entity.get_entity_id().get_value() + + property_proto_list = [] + for k, v in entity.get_properties().items(): + property_proto_list.append(v.to_property_proto()) + entity_proto.properties.extend(property_proto_list) + entity_proto_list.append(entity_proto) + + entity_list_proto = RCRSProto_pb2.EntityListProto() + entity_list_proto.entities.extend(entity_proto_list) + + config_proto = RCRSProto_pb2.ConfigProto() + for key, value in config.items(): + config_proto.data[str(key)] = str(value) + + msg = RCRSProto_pb2.MessageProto() + msg.urn = AMAgent.get_urn() + msg.components[ComponentModuleMSG.AgentID].entityID = agent_id.get_value() + msg.components[ComponentModuleMSG.Entities].entityList.CopyFrom(entity_list_proto) + msg.components[ComponentModuleMSG.Config].config.CopyFrom(config_proto) + msg.components[ComponentModuleMSG.Mode].intValue = mode + return msg + + @staticmethod + def get_urn() -> ControlMessageURN: + return ModuleMSG.AM_AGENT # type: ignore diff --git a/src/adf_core_python/core/gateway/message/am_exec.py b/src/adf_core_python/core/gateway/message/am_exec.py index dd8508b..51f61d0 100644 --- a/src/adf_core_python/core/gateway/message/am_exec.py +++ b/src/adf_core_python/core/gateway/message/am_exec.py @@ -5,25 +5,25 @@ from rcrscore.urn.control_message import ControlMessageURN from adf_core_python.core.gateway.message.urn.urn import ( - ComponentModuleMSG, - ModuleMSG, + ComponentModuleMSG, + ModuleMSG, ) class AMExec(AKControlMessage): - @staticmethod - def write(module_id: str, method_name: str, arguments: dict[str, str]) -> Any: - msg = RCRSProto_pb2.MessageProto() - msg.urn = AMExec.get_urn() - msg.components[ComponentModuleMSG.ModuleID].stringValue = module_id - msg.components[ComponentModuleMSG.MethodName].stringValue = method_name - config_proto = RCRSProto_pb2.ConfigProto() - for key, value in arguments.items(): - config_proto.data[key] = value - msg.components[ComponentModuleMSG.Arguments].config.CopyFrom(config_proto) + @staticmethod + def write(module_id: str, method_name: str, arguments: dict[str, str]) -> Any: + msg = RCRSProto_pb2.MessageProto() + msg.urn = AMExec.get_urn() + msg.components[ComponentModuleMSG.ModuleID].stringValue = module_id + msg.components[ComponentModuleMSG.MethodName].stringValue = method_name + config_proto = RCRSProto_pb2.ConfigProto() + for key, value in arguments.items(): + config_proto.data[key] = value + msg.components[ComponentModuleMSG.Arguments].config.CopyFrom(config_proto) - return msg + return msg - @staticmethod - def get_urn() -> ControlMessageURN: - return ModuleMSG.AM_EXEC # type: ignore + @staticmethod + def get_urn() -> ControlMessageURN: + return ModuleMSG.AM_EXEC # type: ignore diff --git a/src/adf_core_python/core/gateway/message/am_module.py b/src/adf_core_python/core/gateway/message/am_module.py index 6b31662..9b2208f 100644 --- a/src/adf_core_python/core/gateway/message/am_module.py +++ b/src/adf_core_python/core/gateway/message/am_module.py @@ -5,28 +5,26 @@ from rcrscore.urn.control_message import ControlMessageURN from adf_core_python.core.gateway.message.urn.urn import ( - ComponentModuleMSG, - ModuleMSG, + ComponentModuleMSG, + ModuleMSG, ) class AMModule(AKControlMessage): - @staticmethod - def write( - module_id: str, - module_name: str, - default_class_name: str, - ) -> Any: - msg = RCRSProto_pb2.MessageProto() - msg.urn = AMModule.get_urn() - msg.components[ComponentModuleMSG.ModuleID].stringValue = module_id - msg.components[ComponentModuleMSG.ModuleName].stringValue = module_name - msg.components[ - ComponentModuleMSG.DefaultClassName - ].stringValue = default_class_name + @staticmethod + def write( + module_id: str, + module_name: str, + default_class_name: str, + ) -> Any: + msg = RCRSProto_pb2.MessageProto() + msg.urn = AMModule.get_urn() + msg.components[ComponentModuleMSG.ModuleID].stringValue = module_id + msg.components[ComponentModuleMSG.ModuleName].stringValue = module_name + msg.components[ComponentModuleMSG.DefaultClassName].stringValue = default_class_name - return msg + return msg - @staticmethod - def get_urn() -> ControlMessageURN: - return ModuleMSG.AM_MODULE # type: ignore + @staticmethod + def get_urn() -> ControlMessageURN: + return ModuleMSG.AM_MODULE # type: ignore diff --git a/src/adf_core_python/core/gateway/message/am_update.py b/src/adf_core_python/core/gateway/message/am_update.py index e6baa79..c5bf941 100644 --- a/src/adf_core_python/core/gateway/message/am_update.py +++ b/src/adf_core_python/core/gateway/message/am_update.py @@ -7,31 +7,29 @@ from rcrscore.worldmodel import ChangeSet from adf_core_python.core.gateway.message.urn.urn import ( - ComponentModuleMSG, - ModuleMSG, + ComponentModuleMSG, + ModuleMSG, ) class AMUpdate(AKControlMessage): - @staticmethod - def write(time: int, changed: ChangeSet, heard: list[Command]) -> Any: - msg = RCRSProto_pb2.MessageProto() - msg.urn = AMUpdate.get_urn() - msg.components[ComponentModuleMSG.Time].intValue = time - msg.components[ComponentModuleMSG.Changed].changeSet.CopyFrom( - changed.to_change_set_proto() - ) - message_list_proto = RCRSProto_pb2.MessageListProto() - message_proto_list = [] - if heard is not None: - for h in heard: - message_proto_list.append(h.to_message_proto()) - message_list_proto.commands.extend(message_proto_list) - msg.components[ComponentModuleMSG.Heard].commandList.CopyFrom( - message_list_proto - ) - return msg + @staticmethod + def write(time: int, changed: ChangeSet, heard: list[Command]) -> Any: + msg = RCRSProto_pb2.MessageProto() + msg.urn = AMUpdate.get_urn() + msg.components[ComponentModuleMSG.Time].intValue = time + msg.components[ComponentModuleMSG.Changed].changeSet.CopyFrom( + changed.to_change_set_proto() + ) + message_list_proto = RCRSProto_pb2.MessageListProto() + message_proto_list = [] + if heard is not None: + for h in heard: + message_proto_list.append(h.to_message_proto()) + message_list_proto.commands.extend(message_proto_list) + msg.components[ComponentModuleMSG.Heard].commandList.CopyFrom(message_list_proto) + return msg - @staticmethod - def get_urn() -> ControlMessageURN: - return ModuleMSG.AM_UPDATE # type: ignore + @staticmethod + def get_urn() -> ControlMessageURN: + return ModuleMSG.AM_UPDATE # type: ignore diff --git a/src/adf_core_python/core/gateway/message/ma_exec_response.py b/src/adf_core_python/core/gateway/message/ma_exec_response.py index 1e84021..98a50e2 100644 --- a/src/adf_core_python/core/gateway/message/ma_exec_response.py +++ b/src/adf_core_python/core/gateway/message/ma_exec_response.py @@ -4,24 +4,24 @@ from rcrscore.urn.control_message import ControlMessageURN from adf_core_python.core.gateway.message.urn.urn import ( - ComponentModuleMSG, - ModuleMSG, + ComponentModuleMSG, + ModuleMSG, ) class MAExecResponse(KAControlMessage): - def __init__(self, message_proto: RCRSProto_pb2.MessageProto) -> None: - self.result = Config() - self.read(message_proto) + def __init__(self, message_proto: RCRSProto_pb2.MessageProto) -> None: + self.result = Config() + self.read(message_proto) - def read(self, message_proto: RCRSProto_pb2.MessageProto) -> None: - self.module_id: str = message_proto.components[ - ComponentModuleMSG.ModuleID - ].stringValue - result = message_proto.components[ComponentModuleMSG.Result].config - for key, value in result.data.items(): - self.result.set_value(key, value) + def read(self, message_proto: RCRSProto_pb2.MessageProto) -> None: + self.module_id: str = message_proto.components[ + ComponentModuleMSG.ModuleID + ].stringValue + result = message_proto.components[ComponentModuleMSG.Result].config + for key, value in result.data.items(): + self.result.set_value(key, value) - @staticmethod - def get_urn() -> ControlMessageURN: - return ModuleMSG.MA_EXEC_RESPONSE # type: ignore + @staticmethod + def get_urn() -> ControlMessageURN: + return ModuleMSG.MA_EXEC_RESPONSE # type: ignore diff --git a/src/adf_core_python/core/gateway/message/ma_module_response.py b/src/adf_core_python/core/gateway/message/ma_module_response.py index 8e879f3..ce74646 100644 --- a/src/adf_core_python/core/gateway/message/ma_module_response.py +++ b/src/adf_core_python/core/gateway/message/ma_module_response.py @@ -6,25 +6,21 @@ from rcrscore.urn.control_message import ControlMessageURN from adf_core_python.core.gateway.message.urn.urn import ( - ComponentModuleMSG, - ModuleMSG, + ComponentModuleMSG, + ModuleMSG, ) class MAModuleResponse(KAControlMessage, ABC): - def __init__(self, message_proto: RCRSProto_pb2.MessageProto) -> None: - self.module_id: Optional[str] = None - self.class_name: Optional[str] = None - self.read(message_proto) + def __init__(self, message_proto: RCRSProto_pb2.MessageProto) -> None: + self.module_id: Optional[str] = None + self.class_name: Optional[str] = None + self.read(message_proto) - def read(self, message_proto: RCRSProto_pb2.MessageProto) -> None: - self.module_id = message_proto.components[ - ComponentModuleMSG.ModuleID - ].stringValue - self.class_name = message_proto.components[ - ComponentModuleMSG.ClassName - ].stringValue + def read(self, message_proto: RCRSProto_pb2.MessageProto) -> None: + self.module_id = message_proto.components[ComponentModuleMSG.ModuleID].stringValue + self.class_name = message_proto.components[ComponentModuleMSG.ClassName].stringValue - @staticmethod - def get_urn() -> ControlMessageURN: - return ModuleMSG.MA_MODULE_RESPONSE # type: ignore + @staticmethod + def get_urn() -> ControlMessageURN: + return ModuleMSG.MA_MODULE_RESPONSE # type: ignore diff --git a/src/adf_core_python/core/gateway/message/moduleMessageFactory.py b/src/adf_core_python/core/gateway/message/moduleMessageFactory.py index 3874b25..d5a93ed 100644 --- a/src/adf_core_python/core/gateway/message/moduleMessageFactory.py +++ b/src/adf_core_python/core/gateway/message/moduleMessageFactory.py @@ -4,21 +4,21 @@ from adf_core_python.core.gateway.message.ma_exec_response import MAExecResponse from adf_core_python.core.gateway.message.ma_module_response import ( - MAModuleResponse, + MAModuleResponse, ) from adf_core_python.core.gateway.message.urn.urn import ModuleMSG class ModuleMessageFactory: - def __init__(self) -> None: - pass + def __init__(self) -> None: + pass - def make_message( - self, msg: RCRSProto_pb2.MessageProto - ) -> Optional[MAModuleResponse | MAExecResponse]: - if msg.urn == ModuleMSG.MA_MODULE_RESPONSE: - return MAModuleResponse(msg) - elif msg.urn == ModuleMSG.MA_EXEC_RESPONSE: - return MAExecResponse(msg) + def make_message( + self, msg: RCRSProto_pb2.MessageProto + ) -> Optional[MAModuleResponse | MAExecResponse]: + if msg.urn == ModuleMSG.MA_MODULE_RESPONSE: + return MAModuleResponse(msg) + elif msg.urn == ModuleMSG.MA_EXEC_RESPONSE: + return MAExecResponse(msg) - return None + return None diff --git a/src/adf_core_python/core/gateway/message/urn/urn.py b/src/adf_core_python/core/gateway/message/urn/urn.py index d38e435..36a15bf 100644 --- a/src/adf_core_python/core/gateway/message/urn/urn.py +++ b/src/adf_core_python/core/gateway/message/urn/urn.py @@ -2,26 +2,26 @@ class ModuleMSG(IntEnum): - AM_AGENT = 0x0301 - AM_MODULE = 0x0302 - MA_MODULE_RESPONSE = 0x0303 - AM_UPDATE = 0x0304 - AM_EXEC = 0x0305 - MA_EXEC_RESPONSE = 0x0306 + AM_AGENT = 0x0301 + AM_MODULE = 0x0302 + MA_MODULE_RESPONSE = 0x0303 + AM_UPDATE = 0x0304 + AM_EXEC = 0x0305 + MA_EXEC_RESPONSE = 0x0306 class ComponentModuleMSG(IntEnum): - AgentID = 0x0401 - Entities = 0x0402 - Config = 0x0403 - Mode = 0x0404 - ModuleID = 0x0405 - ModuleName = 0x0406 - DefaultClassName = 0x0407 - ClassName = 0x0408 - Time = 0x0409 - Changed = 0x040A - Heard = 0x040B - MethodName = 0x040C - Arguments = 0x040D - Result = 0x040E + AgentID = 0x0401 + Entities = 0x0402 + Config = 0x0403 + Mode = 0x0404 + ModuleID = 0x0405 + ModuleName = 0x0406 + DefaultClassName = 0x0407 + ClassName = 0x0408 + Time = 0x0409 + Changed = 0x040A + Heard = 0x040B + MethodName = 0x040C + Arguments = 0x040D + Result = 0x040E diff --git a/src/adf_core_python/core/gateway/module_dict.py b/src/adf_core_python/core/gateway/module_dict.py index 7f668c6..e814b77 100644 --- a/src/adf_core_python/core/gateway/module_dict.py +++ b/src/adf_core_python/core/gateway/module_dict.py @@ -2,31 +2,31 @@ class ModuleDict: - def __init__(self, module_dict: Optional[dict[str, str]] = None): - self.module_dict: dict[str, str] = { - "adf_core_python.component.module.algorithm.Clustering": "adf_core_python.core.gateway.component.module.complex.gateway_clustering.GatewayClustering", - "adf_core_python.component.module.algorithm.DynamicClustering": "adf_core_python.core.gateway.component.module.complex.gateway_clustering.GatewayClustering", - "adf_core_python.component.module.algorithm.StaticClustering": "adf_core_python.core.gateway.component.module.complex.gateway_clustering.GatewayClustering", - "adf_core_python.component.module.algorithm.PathPlanning": "adf_core_python.core.gateway.component.module.complex.gateway_path_planning.GatewayPathPlanning", - "adf_core_python.component.module.complex.TargetDetector": "adf_core_python.core.gateway.component.module.complex.gateway_target_detector.GatewayTargetDetector", - "adf_core_python.component.module.complex.HumanDetector": "adf_core_python.core.gateway.component.module.complex.gateway_human_detector.GatewayHumanDetector", - "adf_core_python.component.module.complex.RoadDetector": "adf_core_python.core.gateway.component.module.complex.gateway_road_detector.GatewayRoadDetector", - "adf_core_python.component.module.complex.Search": "adf_core_python.core.gateway.component.module.complex.gateway_search.GatewaySearch", - "adf_core_python.component.module.complex.TargetAllocator": "adf_core_python.core.gateway.component.module.complex.gateway_target_allocator.GatewayTargetAllocator", - "adf_core_python.component.module.complex.AmbulanceTargetAllocator": "adf_core_python.core.gateway.component.module.complex.gateway_ambulance_target_allocator.GatewayAmbulanceTargetAllocator", - "adf_core_python.component.module.complex.FireTargetAllocator": "adf_core_python.core.gateway.component.module.complex.gateway_fire_target_allocator.GatewayFireTargetAllocator", - "adf_core_python.component.module.complex.PoliceTargetAllocator": "adf_core_python.core.gateway.component.module.complex.gateway_fire_target_allocator.GatewayPoliceTargetAllocator", - } - if module_dict is not None: - for key, value in module_dict.items(): - self.module_dict[key] = value + def __init__(self, module_dict: Optional[dict[str, str]] = None): + self.module_dict: dict[str, str] = { + "adf_core_python.component.module.algorithm.Clustering": "adf_core_python.core.gateway.component.module.complex.gateway_clustering.GatewayClustering", + "adf_core_python.component.module.algorithm.DynamicClustering": "adf_core_python.core.gateway.component.module.complex.gateway_clustering.GatewayClustering", + "adf_core_python.component.module.algorithm.StaticClustering": "adf_core_python.core.gateway.component.module.complex.gateway_clustering.GatewayClustering", + "adf_core_python.component.module.algorithm.PathPlanning": "adf_core_python.core.gateway.component.module.complex.gateway_path_planning.GatewayPathPlanning", + "adf_core_python.component.module.complex.TargetDetector": "adf_core_python.core.gateway.component.module.complex.gateway_target_detector.GatewayTargetDetector", + "adf_core_python.component.module.complex.HumanDetector": "adf_core_python.core.gateway.component.module.complex.gateway_human_detector.GatewayHumanDetector", + "adf_core_python.component.module.complex.RoadDetector": "adf_core_python.core.gateway.component.module.complex.gateway_road_detector.GatewayRoadDetector", + "adf_core_python.component.module.complex.Search": "adf_core_python.core.gateway.component.module.complex.gateway_search.GatewaySearch", + "adf_core_python.component.module.complex.TargetAllocator": "adf_core_python.core.gateway.component.module.complex.gateway_target_allocator.GatewayTargetAllocator", + "adf_core_python.component.module.complex.AmbulanceTargetAllocator": "adf_core_python.core.gateway.component.module.complex.gateway_ambulance_target_allocator.GatewayAmbulanceTargetAllocator", + "adf_core_python.component.module.complex.FireTargetAllocator": "adf_core_python.core.gateway.component.module.complex.gateway_fire_target_allocator.GatewayFireTargetAllocator", + "adf_core_python.component.module.complex.PoliceTargetAllocator": "adf_core_python.core.gateway.component.module.complex.gateway_fire_target_allocator.GatewayPoliceTargetAllocator", + } + if module_dict is not None: + for key, value in module_dict.items(): + self.module_dict[key] = value - def __getitem__(self, key: str) -> Optional[str]: - if not isinstance(key, str): - raise TypeError("TypeError: Key must be a string") - return self.module_dict.get(key) + def __getitem__(self, key: str) -> Optional[str]: + if not isinstance(key, str): + raise TypeError("TypeError: Key must be a string") + return self.module_dict.get(key) - def __setitem__(self, key: str, value: str) -> None: - if not isinstance(key, str): - raise TypeError("TypeError: Key must be a string") - self.module_dict[key] = value + def __setitem__(self, key: str, value: str) -> None: + if not isinstance(key, str): + raise TypeError("TypeError: Key must be a string") + self.module_dict[key] = value diff --git a/src/adf_core_python/core/launcher/agent_launcher.py b/src/adf_core_python/core/launcher/agent_launcher.py index 94fe7a8..a5c119f 100644 --- a/src/adf_core_python/core/launcher/agent_launcher.py +++ b/src/adf_core_python/core/launcher/agent_launcher.py @@ -10,123 +10,117 @@ from adf_core_python.core.launcher.connect.component_launcher import ComponentLauncher from adf_core_python.core.launcher.connect.connector import Connector from adf_core_python.core.launcher.connect.connector_ambulance_center import ( - ConnectorAmbulanceCenter, + ConnectorAmbulanceCenter, ) from adf_core_python.core.launcher.connect.connector_ambulance_team import ( - ConnectorAmbulanceTeam, + ConnectorAmbulanceTeam, ) from adf_core_python.core.launcher.connect.connector_fire_brigade import ( - ConnectorFireBrigade, + ConnectorFireBrigade, ) from adf_core_python.core.launcher.connect.connector_fire_station import ( - ConnectorFireStation, + ConnectorFireStation, ) from adf_core_python.core.launcher.connect.connector_police_force import ( - ConnectorPoliceForce, + ConnectorPoliceForce, ) from adf_core_python.core.launcher.connect.connector_police_office import ( - ConnectorPoliceOffice, + ConnectorPoliceOffice, ) from adf_core_python.core.logger.logger import get_logger class AgentLauncher: - def __init__(self, config: Config): - self.config = config - self.logger = get_logger(__name__) - self.connectors: list[Connector] = [] - self.agent_thread_list: list[threading.Thread] = [] - - def init_connector(self) -> None: - loader_name, loader_class_name = self.config.get_value( - ConfigKey.KEY_LOADER_CLASS, - "adf_core_python.implement.default_loader.DefaultLoader", - ).rsplit(".", 1) - loader_module = importlib.import_module(loader_name) - self.loader: AbstractLoader = getattr( - loader_module, - loader_class_name, - )( - self.config.get_value(ConfigKey.KEY_TEAM_NAME), - ) - - self.connectors.append(ConnectorAmbulanceTeam()) - self.connectors.append(ConnectorAmbulanceCenter()) - self.connectors.append(ConnectorFireBrigade()) - self.connectors.append(ConnectorFireStation()) - self.connectors.append(ConnectorPoliceForce()) - self.connectors.append(ConnectorPoliceOffice()) - - def launch(self) -> None: - kernel_host: str = self.config.get_value(ConfigKey.KEY_KERNEL_HOST, "localhost") - kernel_port: int = self.config.get_value(ConfigKey.KEY_KERNEL_PORT, 27931) - - component_launcher: ComponentLauncher = ComponentLauncher( - kernel_host, kernel_port, self.logger - ) - timeout: int = self.config.get_value( - ConfigKey.KEY_KERNEL_TIMEOUT, - 30, - ) - if component_launcher.check_kernel_connection(timeout=timeout): - self.logger.info( - f"Kernel is running (host: {kernel_host}, port: {kernel_port})" - ) - else: - self.logger.error( - f"Kernel is not running (host: {kernel_host}, port: {kernel_port})" - ) - return - - self.logger.info( - f"Start agent launcher (host: {kernel_host}, port: {kernel_port})" - ) - - gateway_launcher: Optional[GatewayLauncher] = None - gateway_flag: bool = self.config.get_value(ConfigKey.KEY_GATEWAY_FLAG, False) - if gateway_flag: - gateway_host: str = self.config.get_value( - ConfigKey.KEY_GATEWAY_HOST, "localhost" - ) - gateway_port: int = self.config.get_value(ConfigKey.KEY_GATEWAY_PORT, 27941) - self.logger.info( - f"Start gateway launcher (host: {gateway_host}, port: {gateway_port})" - ) - - gateway_launcher = GatewayLauncher(gateway_host, gateway_port, self.logger) - - connector_thread_list: list[threading.Thread] = [] - for connector in self.connectors: - threads = connector.connect( - component_launcher, gateway_launcher, self.config, self.loader - ) - self.agent_thread_list.extend(threads) - - def connect() -> None: - for thread, event in threads.items(): - thread.daemon = True - thread.start() - event.wait(5) - - connector_thread = threading.Thread(target=connect) - connector_thread_list.append(connector_thread) - connector_thread.start() - - for thread in connector_thread_list: - thread.join() - - self.logger.info("All agents have been launched") - - for thread in self.agent_thread_list: - thread.join() - - def check_kernel_connection(self, host: str, port: int, timeout: int = 5) -> bool: - try: - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.settimeout(timeout) - result = sock.connect_ex((host, port)) - sock.close() - return result == 0 - except Exception as e: - self.logger.error(f"カーネルへの接続確認中にエラーが発生しました: {e}") - return False + def __init__(self, config: Config): + self.config = config + self.logger = get_logger(__name__) + self.connectors: list[Connector] = [] + self.agent_thread_list: list[threading.Thread] = [] + + def init_connector(self) -> None: + loader_name, loader_class_name = self.config.get_value( + ConfigKey.KEY_LOADER_CLASS, + "adf_core_python.implement.default_loader.DefaultLoader", + ).rsplit(".", 1) + loader_module = importlib.import_module(loader_name) + self.loader: AbstractLoader = getattr( + loader_module, + loader_class_name, + )( + self.config.get_value(ConfigKey.KEY_TEAM_NAME), + ) + + self.connectors.append(ConnectorAmbulanceTeam()) + self.connectors.append(ConnectorAmbulanceCenter()) + self.connectors.append(ConnectorFireBrigade()) + self.connectors.append(ConnectorFireStation()) + self.connectors.append(ConnectorPoliceForce()) + self.connectors.append(ConnectorPoliceOffice()) + + def launch(self) -> None: + kernel_host: str = self.config.get_value(ConfigKey.KEY_KERNEL_HOST, "localhost") + kernel_port: int = self.config.get_value(ConfigKey.KEY_KERNEL_PORT, 27931) + + component_launcher: ComponentLauncher = ComponentLauncher( + kernel_host, kernel_port, self.logger + ) + timeout: int = self.config.get_value( + ConfigKey.KEY_KERNEL_TIMEOUT, + 30, + ) + if component_launcher.check_kernel_connection(timeout=timeout): + self.logger.info(f"Kernel is running (host: {kernel_host}, port: {kernel_port})") + else: + self.logger.error( + f"Kernel is not running (host: {kernel_host}, port: {kernel_port})" + ) + return + + self.logger.info(f"Start agent launcher (host: {kernel_host}, port: {kernel_port})") + + gateway_launcher: Optional[GatewayLauncher] = None + gateway_flag: bool = self.config.get_value(ConfigKey.KEY_GATEWAY_FLAG, False) + if gateway_flag: + gateway_host: str = self.config.get_value(ConfigKey.KEY_GATEWAY_HOST, "localhost") + gateway_port: int = self.config.get_value(ConfigKey.KEY_GATEWAY_PORT, 27941) + self.logger.info( + f"Start gateway launcher (host: {gateway_host}, port: {gateway_port})" + ) + + gateway_launcher = GatewayLauncher(gateway_host, gateway_port, self.logger) + + connector_thread_list: list[threading.Thread] = [] + for connector in self.connectors: + threads = connector.connect( + component_launcher, gateway_launcher, self.config, self.loader + ) + self.agent_thread_list.extend(threads) + + def connect() -> None: + for thread, event in threads.items(): + thread.daemon = True + thread.start() + event.wait(5) + + connector_thread = threading.Thread(target=connect) + connector_thread_list.append(connector_thread) + connector_thread.start() + + for thread in connector_thread_list: + thread.join() + + self.logger.info("All agents have been launched") + + for thread in self.agent_thread_list: + thread.join() + + def check_kernel_connection(self, host: str, port: int, timeout: int = 5) -> bool: + try: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.settimeout(timeout) + result = sock.connect_ex((host, port)) + sock.close() + return result == 0 + except Exception as e: + self.logger.error(f"カーネルへの接続確認中にエラーが発生しました: {e}") + return False diff --git a/src/adf_core_python/core/launcher/config_key.py b/src/adf_core_python/core/launcher/config_key.py index 2f7f9a0..90d4f3c 100644 --- a/src/adf_core_python/core/launcher/config_key.py +++ b/src/adf_core_python/core/launcher/config_key.py @@ -2,30 +2,30 @@ class ConfigKey: - # General - KEY_LOADER_CLASS: Final[str] = "adf_core_python.launcher.loader" - KEY_KERNEL_HOST: Final[str] = "kernel.host" - KEY_KERNEL_PORT: Final[str] = "kernel.port" - KEY_KERNEL_TIMEOUT: Final[str] = "kernel.timeout" - KEY_TEAM_NAME: Final[str] = "team.name" - KEY_DEBUG_FLAG: Final[str] = "adf.debug.flag" - KEY_DEVELOP_FLAG: Final[str] = "adf.develop.flag" - KEY_DEVELOP_DATA_FILE_NAME: Final[str] = "adf.develop.filename" - KEY_DEVELOP_DATA: Final[str] = "adf.develop.data" - KEY_MODULE_CONFIG_FILE_NAME: Final[str] = "adf.agent.moduleconfig.filename" - KEY_MODULE_DATA: Final[str] = "adf.agent.moduleconfig.data" - KEY_PRECOMPUTE: Final[str] = "adf.launcher.precompute" - # Platoon - KEY_AMBULANCE_TEAM_COUNT: Final[str] = "adf.team.platoon.ambulance.count" - KEY_FIRE_BRIGADE_COUNT: Final[str] = "adf.team.platoon.fire.count" - KEY_POLICE_FORCE_COUNT: Final[str] = "adf.team.platoon.police.count" - # Office - KEY_AMBULANCE_CENTRE_COUNT: Final[str] = "adf.team.office.ambulance.count" - 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" - # Gateway - KEY_GATEWAY_HOST: Final[str] = "gateway.host" - KEY_GATEWAY_PORT: Final[str] = "gateway.port" - KEY_GATEWAY_FLAG: Final[str] = "adf.gateway.flag" + # General + KEY_LOADER_CLASS: Final[str] = "adf_core_python.launcher.loader" + KEY_KERNEL_HOST: Final[str] = "kernel.host" + KEY_KERNEL_PORT: Final[str] = "kernel.port" + KEY_KERNEL_TIMEOUT: Final[str] = "kernel.timeout" + KEY_TEAM_NAME: Final[str] = "team.name" + KEY_DEBUG_FLAG: Final[str] = "adf.debug.flag" + KEY_DEVELOP_FLAG: Final[str] = "adf.develop.flag" + KEY_DEVELOP_DATA_FILE_NAME: Final[str] = "adf.develop.filename" + KEY_DEVELOP_DATA: Final[str] = "adf.develop.data" + KEY_MODULE_CONFIG_FILE_NAME: Final[str] = "adf.agent.moduleconfig.filename" + KEY_MODULE_DATA: Final[str] = "adf.agent.moduleconfig.data" + KEY_PRECOMPUTE: Final[str] = "adf.launcher.precompute" + # Platoon + KEY_AMBULANCE_TEAM_COUNT: Final[str] = "adf.team.platoon.ambulance.count" + KEY_FIRE_BRIGADE_COUNT: Final[str] = "adf.team.platoon.fire.count" + KEY_POLICE_FORCE_COUNT: Final[str] = "adf.team.platoon.police.count" + # Office + KEY_AMBULANCE_CENTRE_COUNT: Final[str] = "adf.team.office.ambulance.count" + 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" + # Gateway + KEY_GATEWAY_HOST: Final[str] = "gateway.host" + KEY_GATEWAY_PORT: Final[str] = "gateway.port" + KEY_GATEWAY_FLAG: Final[str] = "adf.gateway.flag" diff --git a/src/adf_core_python/core/launcher/connect/component_launcher.py b/src/adf_core_python/core/launcher/connect/component_launcher.py index 9a684fa..4890300 100644 --- a/src/adf_core_python/core/launcher/connect/component_launcher.py +++ b/src/adf_core_python/core/launcher/connect/component_launcher.py @@ -10,92 +10,88 @@ class ComponentLauncher: - def __init__(self, host: str, port: int, logger: BoundLogger) -> None: - self.request_id = 0 - self.port = port - self.host = host - self.logger = logger - - def make_connection(self) -> Connection: - return Connection(self.host, self.port) - - def connect(self, agent: Agent, _request_id: int) -> None: - connection = self.make_connection() - try: - connection.connect() - except socket.timeout: - self.logger.warning(f"Connection to {self.host}:{self.port} timed out") - return - except socket.error as e: - self.logger.exception( - f"Failed to connect to {self.host}:{self.port}", exception=str(e) - ) - return - - connection.message_received(agent.message_received) - agent.set_send_msg(connection.send_msg) - agent.start_up(_request_id) - - try: - connection.parse_message_from_kernel() - except AgentError as e: - self.logger.exception( - f"Agent error: {e}", - exception=str(e), - ) - except ServerError as e: - if isinstance(e.__cause__, EOFError): - self.logger.info( - f"Connection closed by server (request_id={_request_id})" - ) - else: - self.logger.exception("Server error", exception=str(e)) - - def generate_request_id(self) -> int: - self.request_id += 1 - return self.request_id - - def check_kernel_connection( - self, timeout: int = 30, retry_interval: float = 5.0 - ) -> bool: - """Attempts to connect to the kernel multiple times within the specified timeout period. - - Args: - timeout (int): Total timeout duration in seconds - retry_interval (float): Interval between retry attempts in seconds - - Returns: - bool: True if connection successful, False otherwise - """ - start_time = time.time() - attempt = 1 - - while True: - try: - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.settimeout(retry_interval) - result = sock.connect_ex((self.host, self.port)) - sock.close() - - if result == 0: - self.logger.info( - f"Successfully connected to kernel (attempt: {attempt})" - ) - return True - - elapsed_time = time.time() - start_time - if elapsed_time >= timeout: - self.logger.error( - f"Timeout: Could not connect to kernel within {timeout} seconds (attempts: {attempt})" - ) - return False - - self.logger.debug( - f"Connection attempt {attempt} failed - retrying in {retry_interval} seconds" - ) - time.sleep(retry_interval) - attempt += 1 - - except Exception as e: - self.logger.error(f"Error while checking kernel connection: {e}") - return False + def __init__(self, host: str, port: int, logger: BoundLogger) -> None: + self.request_id = 0 + self.port = port + self.host = host + self.logger = logger + + def make_connection(self) -> Connection: + return Connection(self.host, self.port) + + def connect(self, agent: Agent, _request_id: int) -> None: + connection = self.make_connection() + try: + connection.connect() + except socket.timeout: + self.logger.warning(f"Connection to {self.host}:{self.port} timed out") + return + except socket.error as e: + self.logger.exception( + f"Failed to connect to {self.host}:{self.port}", exception=str(e) + ) + return + + connection.message_received(agent.message_received) + agent.set_send_msg(connection.send_msg) + agent.start_up(_request_id) + + try: + connection.parse_message_from_kernel() + except AgentError as e: + self.logger.exception( + f"Agent error: {e}", + exception=str(e), + ) + except ServerError as e: + if isinstance(e.__cause__, EOFError): + self.logger.info(f"Connection closed by server (request_id={_request_id})") + else: + self.logger.exception("Server error", exception=str(e)) + + def generate_request_id(self) -> int: + self.request_id += 1 + return self.request_id + + def check_kernel_connection( + self, timeout: int = 30, retry_interval: float = 5.0 + ) -> bool: + """Attempts to connect to the kernel multiple times within the specified timeout period. + + Args: + timeout (int): Total timeout duration in seconds + retry_interval (float): Interval between retry attempts in seconds + + Returns: + bool: True if connection successful, False otherwise + """ + start_time = time.time() + attempt = 1 + + while True: + try: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.settimeout(retry_interval) + result = sock.connect_ex((self.host, self.port)) + sock.close() + + if result == 0: + self.logger.info(f"Successfully connected to kernel (attempt: {attempt})") + return True + + elapsed_time = time.time() - start_time + if elapsed_time >= timeout: + self.logger.error( + f"Timeout: Could not connect to kernel within {timeout} seconds (attempts: {attempt})" + ) + return False + + self.logger.debug( + f"Connection attempt {attempt} failed - retrying in {retry_interval} seconds" + ) + time.sleep(retry_interval) + attempt += 1 + + except Exception as e: + self.logger.error(f"Error while checking kernel connection: {e}") + return False diff --git a/src/adf_core_python/core/launcher/connect/connection.py b/src/adf_core_python/core/launcher/connect/connection.py index 2935f0d..660d987 100644 --- a/src/adf_core_python/core/launcher/connect/connection.py +++ b/src/adf_core_python/core/launcher/connect/connection.py @@ -1,59 +1,108 @@ import socket from typing import Any, Callable -import rcrs_core.connection.rcrs_encoding_utils as rcrs_encoding_utils +from rcrscore.proto import RCRSProto_pb2 from adf_core_python.core.launcher.connect.error.agent_error import AgentError from adf_core_python.core.launcher.connect.error.server_error import ServerError class Connection: - def __init__(self, host: str, port: int) -> None: - self.socket: socket.socket - self.agent = None - self.buffer_size: int = 4096 - self.data_buffer: bytes = b"" - self.host = host - self.port = port - - def connect(self) -> None: - """ - Connect to the kernel - - Raises - ------ - socket.timeout - If the connection times out - socket.error - If there is an error connecting to the socket - - """ - self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.socket.connect((self.host, self.port)) - - def parse_message_from_kernel(self) -> None: - """ - Parse messages from the kernel - - Raises - ------ - ServerError - If there is an error reading from the socket - AgentError - If there is an error in the agent calculation - """ - while True: - try: - msg = rcrs_encoding_utils.read_msg(self.socket) - except Exception as e: - raise ServerError(f"Error reading from socket: {e}") from e - try: - self.agent_message_received(msg) - except Exception as e: - raise AgentError(f"Error agent calculation: {e}") from e - - def message_received(self, agent_message_received: Callable) -> None: - self.agent_message_received = agent_message_received - - def send_msg(self, msg: Any) -> None: - rcrs_encoding_utils.write_msg(msg, self.socket) + def __init__(self, host: str, port: int) -> None: + self.socket: socket.socket + self.agent = None + self.buffer_size: int = 4096 + self.data_buffer: bytes = b"" + self.host = host + self.port = port + + def connect(self) -> None: + """ + Connect to the kernel + + Raises + ------ + socket.timeout + If the connection times out + socket.error + If there is an error connecting to the socket + + """ + self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.socket.connect((self.host, self.port)) + + def parse_message_from_kernel(self) -> None: + """ + Parse messages from the kernel + + Raises + ------ + ServerError + If there is an error reading from the socket + AgentError + If there is an error in the agent calculation + """ + while True: + try: + msg = Connection._read_msg(self.socket) + except Exception as e: + raise ServerError(f"Error reading from socket: {e}") from e + try: + self.agent_message_received(msg) + except Exception as e: + raise AgentError(f"Error agent calculation: {e}") from e + + def message_received(self, agent_message_received: Callable) -> None: + self.agent_message_received = agent_message_received + + def send_msg(self, msg: Any) -> None: + Connection._write_msg(msg, self.socket) + + @staticmethod + def _write_int32(value, sock): + b = [ + ((value >> 24) & 0xFF), + ((value >> 16) & 0xFF), + ((value >> 8) & 0xFF), + (value & 0xFF), + ] + + sock.sendall(bytes(b)) + + @staticmethod + def _readnbytes(sock, n): + buff = b"" + while n > 0: + b = sock.recv(n) + buff += b + if len(b) == 0: + raise EOFError # peer socket has received a SH_WR shutdown + n -= len(b) + return buff + + @staticmethod + def _read_int32(sock): + byte_array = Connection._readnbytes(sock, 4) + value = int( + ((byte_array[0]) << 24) + + ((byte_array[1]) << 16) + + ((byte_array[2]) << 8) + + (byte_array[3]) + ) + return value + + @staticmethod + def _write_msg(msg, sock): + out = msg.SerializeToString() + Connection._write_int32(len(out), sock) + + sock.sendall(out) + + @staticmethod + def _read_msg(sock): + # await reader.read(1) + size = Connection._read_int32(sock) + content = Connection._readnbytes(sock, size) + message = RCRSProto_pb2.MessageProto() + message.ParseFromString(bytes(content)) + return message diff --git a/src/adf_core_python/core/launcher/connect/connector.py b/src/adf_core_python/core/launcher/connect/connector.py index a36a04c..f58ce63 100644 --- a/src/adf_core_python/core/launcher/connect/connector.py +++ b/src/adf_core_python/core/launcher/connect/connector.py @@ -9,18 +9,18 @@ class Connector(ABC): - def __init__(self) -> None: - self.connected_agent_count = 0 + def __init__(self) -> None: + self.connected_agent_count = 0 - @abstractmethod - def connect( - self, - component_launcher: ComponentLauncher, - gateway_launcher: Optional[GatewayLauncher], - config: Config, - loader: AbstractLoader, - ) -> dict[threading.Thread, threading.Event]: - raise NotImplementedError + @abstractmethod + def connect( + self, + component_launcher: ComponentLauncher, + gateway_launcher: Optional[GatewayLauncher], + config: Config, + loader: AbstractLoader, + ) -> dict[threading.Thread, threading.Event]: + raise NotImplementedError - def get_connected_agent_count(self) -> int: - return self.connected_agent_count + def get_connected_agent_count(self) -> int: + return self.connected_agent_count diff --git a/src/adf_core_python/core/launcher/connect/connector_ambulance_center.py b/src/adf_core_python/core/launcher/connect/connector_ambulance_center.py index ac99bf7..86e8fe8 100644 --- a/src/adf_core_python/core/launcher/connect/connector_ambulance_center.py +++ b/src/adf_core_python/core/launcher/connect/connector_ambulance_center.py @@ -6,7 +6,7 @@ from adf_core_python.core.agent.office.office_ambulance import OfficeAmbulance from adf_core_python.core.component.abstract_loader import AbstractLoader from adf_core_python.core.component.tactics.tactics_ambulance_center import ( - TacticsAmbulanceCenter, + TacticsAmbulanceCenter, ) from adf_core_python.core.config.config import Config from adf_core_python.core.gateway.gateway_agent import GatewayAgent @@ -18,79 +18,79 @@ class ConnectorAmbulanceCenter(Connector): - def __init__(self) -> None: - super().__init__() - self.logger = get_logger(__name__) + def __init__(self) -> None: + super().__init__() + self.logger = get_logger(__name__) - def connect( - self, - component_launcher: ComponentLauncher, - gateway_launcher: Optional[GatewayLauncher], - config: Config, - loader: AbstractLoader, - ) -> dict[threading.Thread, threading.Event]: - count: int = config.get_value(ConfigKey.KEY_AMBULANCE_CENTRE_COUNT, 0) - if count == 0: - return {} + def connect( + self, + component_launcher: ComponentLauncher, + gateway_launcher: Optional[GatewayLauncher], + config: Config, + loader: AbstractLoader, + ) -> dict[threading.Thread, threading.Event]: + count: int = config.get_value(ConfigKey.KEY_AMBULANCE_CENTRE_COUNT, 0) + if count == 0: + return {} - threads: dict[threading.Thread, threading.Event] = {} + threads: dict[threading.Thread, threading.Event] = {} - for _ in range(count): - if loader.get_tactics_ambulance_center() is None: - self.logger.error("Cannot load ambulance centre tactics") + for _ in range(count): + if loader.get_tactics_ambulance_center() is None: + self.logger.error("Cannot load ambulance centre tactics") - tactics_ambulance_center: TacticsAmbulanceCenter = ( - loader.get_tactics_ambulance_center() - ) + tactics_ambulance_center: TacticsAmbulanceCenter = ( + loader.get_tactics_ambulance_center() + ) - module_config: ModuleConfig = ModuleConfig( - config.get_value( - ConfigKey.KEY_MODULE_CONFIG_FILE_NAME, - ModuleConfig.DEFAULT_CONFIG_FILE_NAME, - ) - ) + module_config: ModuleConfig = ModuleConfig( + config.get_value( + ConfigKey.KEY_MODULE_CONFIG_FILE_NAME, + ModuleConfig.DEFAULT_CONFIG_FILE_NAME, + ) + ) - develop_data: DevelopData = DevelopData( - config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), - config.get_value( - ConfigKey.KEY_DEVELOP_DATA_FILE_NAME, DevelopData.DEFAULT_FILE_NAME - ), - ) + develop_data: DevelopData = DevelopData( + config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), + config.get_value( + ConfigKey.KEY_DEVELOP_DATA_FILE_NAME, DevelopData.DEFAULT_FILE_NAME + ), + ) - precompute_data_dir: str = f"{config.get_value(ConfigKey.KEY_PRECOMPUTE_DATA_DIR, 'precompute')}/ambulance_center" + 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() + finish_post_connect_event = threading.Event() + request_id: int = component_launcher.generate_request_id() - gateway_agent: Optional[GatewayAgent] = None - if isinstance(gateway_launcher, GatewayLauncher): - gateway_agent = GatewayAgent(gateway_launcher) - if isinstance(gateway_agent, GatewayAgent): - gateway_thread = threading.Thread( - target=gateway_launcher.connect, - args=(gateway_agent,), - ) - gateway_thread.daemon = True - gateway_thread.start() + gateway_agent: Optional[GatewayAgent] = None + if isinstance(gateway_launcher, GatewayLauncher): + gateway_agent = GatewayAgent(gateway_launcher) + if isinstance(gateway_agent, GatewayAgent): + gateway_thread = threading.Thread( + target=gateway_launcher.connect, + args=(gateway_agent,), + ) + gateway_thread.daemon = True + gateway_thread.start() - component_thread = threading.Thread( - target=component_launcher.connect, - args=( - OfficeAmbulance( - tactics_ambulance_center, - "ambulance_center", - config.get_value(ConfigKey.KEY_PRECOMPUTE, False), - config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), - precompute_data_dir, - module_config, - develop_data, - finish_post_connect_event, - gateway_agent, - ), - request_id, - ), - name=f"AmbulanceCenterAgent-{request_id}", - ) - threads[component_thread] = finish_post_connect_event + component_thread = threading.Thread( + target=component_launcher.connect, + args=( + OfficeAmbulance( + tactics_ambulance_center, + "ambulance_center", + config.get_value(ConfigKey.KEY_PRECOMPUTE, False), + config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), + precompute_data_dir, + module_config, + develop_data, + finish_post_connect_event, + gateway_agent, + ), + request_id, + ), + name=f"AmbulanceCenterAgent-{request_id}", + ) + threads[component_thread] = finish_post_connect_event - return threads + return threads diff --git a/src/adf_core_python/core/launcher/connect/connector_ambulance_team.py b/src/adf_core_python/core/launcher/connect/connector_ambulance_team.py index b354c7c..3645637 100644 --- a/src/adf_core_python/core/launcher/connect/connector_ambulance_team.py +++ b/src/adf_core_python/core/launcher/connect/connector_ambulance_team.py @@ -6,7 +6,7 @@ from adf_core_python.core.agent.platoon.platoon_ambulance import PlatoonAmbulance from adf_core_python.core.component.abstract_loader import AbstractLoader from adf_core_python.core.component.tactics.tactics_ambulance_team import ( - TacticsAmbulanceTeam, + TacticsAmbulanceTeam, ) from adf_core_python.core.config.config import Config from adf_core_python.core.gateway.gateway_agent import GatewayAgent @@ -18,79 +18,77 @@ class ConnectorAmbulanceTeam(Connector): - def __init__(self) -> None: - super().__init__() - self.logger = get_logger(__name__) + def __init__(self) -> None: + super().__init__() + self.logger = get_logger(__name__) - def connect( - self, - component_launcher: ComponentLauncher, - gateway_launcher: Optional[GatewayLauncher], - config: Config, - loader: AbstractLoader, - ) -> dict[threading.Thread, threading.Event]: - count: int = config.get_value(ConfigKey.KEY_AMBULANCE_TEAM_COUNT, 0) - if count == 0: - return {} + def connect( + self, + component_launcher: ComponentLauncher, + gateway_launcher: Optional[GatewayLauncher], + config: Config, + loader: AbstractLoader, + ) -> dict[threading.Thread, threading.Event]: + count: int = config.get_value(ConfigKey.KEY_AMBULANCE_TEAM_COUNT, 0) + if count == 0: + return {} - threads: dict[threading.Thread, threading.Event] = {} + threads: dict[threading.Thread, threading.Event] = {} - for _ in range(count): - if loader.get_tactics_ambulance_team() is None: - self.logger.error("Cannot load ambulance team tactics") + for _ in range(count): + if loader.get_tactics_ambulance_team() is None: + self.logger.error("Cannot load ambulance team tactics") - tactics_ambulance_team: TacticsAmbulanceTeam = ( - loader.get_tactics_ambulance_team() - ) + tactics_ambulance_team: TacticsAmbulanceTeam = loader.get_tactics_ambulance_team() - module_config: ModuleConfig = ModuleConfig( - config.get_value( - ConfigKey.KEY_MODULE_CONFIG_FILE_NAME, - ModuleConfig.DEFAULT_CONFIG_FILE_NAME, - ) - ) + module_config: ModuleConfig = ModuleConfig( + config.get_value( + ConfigKey.KEY_MODULE_CONFIG_FILE_NAME, + ModuleConfig.DEFAULT_CONFIG_FILE_NAME, + ) + ) - develop_data: DevelopData = DevelopData( - config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), - config.get_value( - ConfigKey.KEY_DEVELOP_DATA_FILE_NAME, DevelopData.DEFAULT_FILE_NAME - ), - ) + develop_data: DevelopData = DevelopData( + config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), + config.get_value( + ConfigKey.KEY_DEVELOP_DATA_FILE_NAME, DevelopData.DEFAULT_FILE_NAME + ), + ) - precompute_data_dir: str = f"{config.get_value(ConfigKey.KEY_PRECOMPUTE_DATA_DIR, 'precompute')}/ambulance_team" + 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() + finish_post_connect_event = threading.Event() + request_id: int = component_launcher.generate_request_id() - gateway_agent: Optional[GatewayAgent] = None - if isinstance(gateway_launcher, GatewayLauncher): - gateway_agent = GatewayAgent(gateway_launcher) - if isinstance(gateway_agent, GatewayAgent): - gateway_thread = threading.Thread( - target=gateway_launcher.connect, - args=(gateway_agent,), - ) - gateway_thread.daemon = True - gateway_thread.start() + gateway_agent: Optional[GatewayAgent] = None + if isinstance(gateway_launcher, GatewayLauncher): + gateway_agent = GatewayAgent(gateway_launcher) + if isinstance(gateway_agent, GatewayAgent): + gateway_thread = threading.Thread( + target=gateway_launcher.connect, + args=(gateway_agent,), + ) + gateway_thread.daemon = True + gateway_thread.start() - component_thread = threading.Thread( - target=component_launcher.connect, - args=( - PlatoonAmbulance( - tactics_ambulance_team, - "ambulance_team", - config.get_value(ConfigKey.KEY_PRECOMPUTE, False), - config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), - precompute_data_dir, - module_config, - develop_data, - finish_post_connect_event, - gateway_agent, - ), - request_id, - ), - name=f"AmbulanceTeam-{request_id}", - ) - threads[component_thread] = finish_post_connect_event + component_thread = threading.Thread( + target=component_launcher.connect, + args=( + PlatoonAmbulance( + tactics_ambulance_team, + "ambulance_team", + config.get_value(ConfigKey.KEY_PRECOMPUTE, False), + config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), + precompute_data_dir, + module_config, + develop_data, + finish_post_connect_event, + gateway_agent, + ), + request_id, + ), + name=f"AmbulanceTeam-{request_id}", + ) + threads[component_thread] = finish_post_connect_event - return threads + return threads diff --git a/src/adf_core_python/core/launcher/connect/connector_fire_brigade.py b/src/adf_core_python/core/launcher/connect/connector_fire_brigade.py index 6e5fda3..8889365 100644 --- a/src/adf_core_python/core/launcher/connect/connector_fire_brigade.py +++ b/src/adf_core_python/core/launcher/connect/connector_fire_brigade.py @@ -6,7 +6,7 @@ from adf_core_python.core.agent.platoon.platoon_fire import PlatoonFire from adf_core_python.core.component.abstract_loader import AbstractLoader from adf_core_python.core.component.tactics.tactics_fire_brigade import ( - TacticsFireBrigade, + TacticsFireBrigade, ) from adf_core_python.core.config.config import Config from adf_core_python.core.gateway.gateway_agent import GatewayAgent @@ -18,77 +18,77 @@ class ConnectorFireBrigade(Connector): - def __init__(self) -> None: - super().__init__() - self.logger = get_logger(__name__) + def __init__(self) -> None: + super().__init__() + self.logger = get_logger(__name__) - def connect( - self, - component_launcher: ComponentLauncher, - gateway_launcher: Optional[GatewayLauncher], - config: Config, - loader: AbstractLoader, - ) -> dict[threading.Thread, threading.Event]: - count: int = config.get_value(ConfigKey.KEY_FIRE_BRIGADE_COUNT, 0) - if count == 0: - return {} + def connect( + self, + component_launcher: ComponentLauncher, + gateway_launcher: Optional[GatewayLauncher], + config: Config, + loader: AbstractLoader, + ) -> dict[threading.Thread, threading.Event]: + count: int = config.get_value(ConfigKey.KEY_FIRE_BRIGADE_COUNT, 0) + if count == 0: + return {} - threads: dict[threading.Thread, threading.Event] = {} + threads: dict[threading.Thread, threading.Event] = {} - for _ in range(count): - if loader.get_tactics_fire_brigade() is None: - self.logger.error("Cannot load fire brigade tactics") + for _ in range(count): + if loader.get_tactics_fire_brigade() is None: + self.logger.error("Cannot load fire brigade tactics") - tactics_fire_brigade: TacticsFireBrigade = loader.get_tactics_fire_brigade() + tactics_fire_brigade: TacticsFireBrigade = loader.get_tactics_fire_brigade() - module_config: ModuleConfig = ModuleConfig( - config.get_value( - ConfigKey.KEY_MODULE_CONFIG_FILE_NAME, - ModuleConfig.DEFAULT_CONFIG_FILE_NAME, - ) - ) + module_config: ModuleConfig = ModuleConfig( + config.get_value( + ConfigKey.KEY_MODULE_CONFIG_FILE_NAME, + ModuleConfig.DEFAULT_CONFIG_FILE_NAME, + ) + ) - develop_data: DevelopData = DevelopData( - config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), - config.get_value( - ConfigKey.KEY_DEVELOP_DATA_FILE_NAME, DevelopData.DEFAULT_FILE_NAME - ), - ) + develop_data: DevelopData = DevelopData( + config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), + config.get_value( + ConfigKey.KEY_DEVELOP_DATA_FILE_NAME, DevelopData.DEFAULT_FILE_NAME + ), + ) - precompute_data_dir: str = f"{config.get_value(ConfigKey.KEY_PRECOMPUTE_DATA_DIR, 'precompute')}/fire_brigade" + precompute_data_dir: str = f"{config.get_value(ConfigKey.KEY_PRECOMPUTE_DATA_DIR, 'precompute')}/fire_brigade" - finish_post_connect_event = threading.Event() - request_id: int = component_launcher.generate_request_id() + finish_post_connect_event = threading.Event() + request_id: int = component_launcher.generate_request_id() - gateway_agent: Optional[GatewayAgent] = None - if isinstance(gateway_launcher, GatewayLauncher): - gateway_agent = GatewayAgent(gateway_launcher) - if isinstance(gateway_agent, GatewayAgent): - gateway_thread = threading.Thread( - target=gateway_launcher.connect, - args=(gateway_agent,), - ) - gateway_thread.daemon = True - gateway_thread.start() + gateway_agent: Optional[GatewayAgent] = None + if isinstance(gateway_launcher, GatewayLauncher): + gateway_agent = GatewayAgent(gateway_launcher) + if isinstance(gateway_agent, GatewayAgent): + gateway_thread = threading.Thread( + target=gateway_launcher.connect, + args=(gateway_agent,), + ) + gateway_thread.daemon = True + gateway_thread.start() - component_thread = threading.Thread( - target=component_launcher.connect, - args=( - PlatoonFire( - tactics_fire_brigade, - "fire_brigade", - config.get_value(ConfigKey.KEY_PRECOMPUTE, False), - config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), - precompute_data_dir, - module_config, - develop_data, - finish_post_connect_event, - gateway_agent, - ), - request_id, - ), - name=f"FireBrigadeAgent-{request_id}", - ) - threads[component_thread] = finish_post_connect_event + component_thread = threading.Thread( + target=component_launcher.connect, + args=( + PlatoonFire( + tactics_fire_brigade, + "fire_brigade", + config.get_value(ConfigKey.KEY_PRECOMPUTE, False), + config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), + precompute_data_dir, + module_config, + develop_data, + finish_post_connect_event, + gateway_agent, + ), + request_id, + ), + name=f"FireBrigadeAgent-{request_id}", + ) + threads[component_thread] = finish_post_connect_event - return threads + return threads diff --git a/src/adf_core_python/core/launcher/connect/connector_fire_station.py b/src/adf_core_python/core/launcher/connect/connector_fire_station.py index 2263167..d1bdf7a 100644 --- a/src/adf_core_python/core/launcher/connect/connector_fire_station.py +++ b/src/adf_core_python/core/launcher/connect/connector_fire_station.py @@ -6,7 +6,7 @@ from adf_core_python.core.agent.office.office_fire import OfficeFire from adf_core_python.core.component.abstract_loader import AbstractLoader from adf_core_python.core.component.tactics.tactics_fire_station import ( - TacticsFireStation, + TacticsFireStation, ) from adf_core_python.core.config.config import Config from adf_core_python.core.gateway.gateway_agent import GatewayAgent @@ -18,77 +18,77 @@ class ConnectorFireStation(Connector): - def __init__(self) -> None: - super().__init__() - self.logger = get_logger(__name__) + def __init__(self) -> None: + super().__init__() + self.logger = get_logger(__name__) - def connect( - self, - component_launcher: ComponentLauncher, - gateway_launcher: Optional[GatewayLauncher], - config: Config, - loader: AbstractLoader, - ) -> dict[threading.Thread, threading.Event]: - count: int = config.get_value(ConfigKey.KEY_FIRE_STATION_COUNT, 0) - if count == 0: - return {} + def connect( + self, + component_launcher: ComponentLauncher, + gateway_launcher: Optional[GatewayLauncher], + config: Config, + loader: AbstractLoader, + ) -> dict[threading.Thread, threading.Event]: + count: int = config.get_value(ConfigKey.KEY_FIRE_STATION_COUNT, 0) + if count == 0: + return {} - threads: dict[threading.Thread, threading.Event] = {} + threads: dict[threading.Thread, threading.Event] = {} - for _ in range(count): - if loader.get_tactics_fire_station() is None: - self.logger.error("Cannot load fire station tactics") + for _ in range(count): + if loader.get_tactics_fire_station() is None: + self.logger.error("Cannot load fire station tactics") - tactics_fire_station: TacticsFireStation = loader.get_tactics_fire_station() + tactics_fire_station: TacticsFireStation = loader.get_tactics_fire_station() - module_config: ModuleConfig = ModuleConfig( - config.get_value( - ConfigKey.KEY_MODULE_CONFIG_FILE_NAME, - ModuleConfig.DEFAULT_CONFIG_FILE_NAME, - ) - ) + module_config: ModuleConfig = ModuleConfig( + config.get_value( + ConfigKey.KEY_MODULE_CONFIG_FILE_NAME, + ModuleConfig.DEFAULT_CONFIG_FILE_NAME, + ) + ) - develop_data: DevelopData = DevelopData( - config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), - config.get_value( - ConfigKey.KEY_DEVELOP_DATA_FILE_NAME, DevelopData.DEFAULT_FILE_NAME - ), - ) + develop_data: DevelopData = DevelopData( + config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), + config.get_value( + ConfigKey.KEY_DEVELOP_DATA_FILE_NAME, DevelopData.DEFAULT_FILE_NAME + ), + ) - precompute_data_dir: str = f"{config.get_value(ConfigKey.KEY_PRECOMPUTE_DATA_DIR, 'precompute')}/fire_station" + precompute_data_dir: str = f"{config.get_value(ConfigKey.KEY_PRECOMPUTE_DATA_DIR, 'precompute')}/fire_station" - finish_post_connect_event = threading.Event() - request_id: int = component_launcher.generate_request_id() + finish_post_connect_event = threading.Event() + request_id: int = component_launcher.generate_request_id() - gateway_agent: Optional[GatewayAgent] = None - if isinstance(gateway_launcher, GatewayLauncher): - gateway_agent = GatewayAgent(gateway_launcher) - if isinstance(gateway_agent, GatewayAgent): - gateway_thread = threading.Thread( - target=gateway_launcher.connect, - args=(gateway_agent,), - ) - gateway_thread.daemon = True - gateway_thread.start() + gateway_agent: Optional[GatewayAgent] = None + if isinstance(gateway_launcher, GatewayLauncher): + gateway_agent = GatewayAgent(gateway_launcher) + if isinstance(gateway_agent, GatewayAgent): + gateway_thread = threading.Thread( + target=gateway_launcher.connect, + args=(gateway_agent,), + ) + gateway_thread.daemon = True + gateway_thread.start() - component_thread = threading.Thread( - target=component_launcher.connect, - args=( - OfficeFire( - tactics_fire_station, - "fire_station", - config.get_value(ConfigKey.KEY_PRECOMPUTE, False), - config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), - precompute_data_dir, - module_config, - develop_data, - finish_post_connect_event, - gateway_agent, - ), - request_id, - ), - name=f"FireStationAgent-{request_id}", - ) - threads[component_thread] = finish_post_connect_event + component_thread = threading.Thread( + target=component_launcher.connect, + args=( + OfficeFire( + tactics_fire_station, + "fire_station", + config.get_value(ConfigKey.KEY_PRECOMPUTE, False), + config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), + precompute_data_dir, + module_config, + develop_data, + finish_post_connect_event, + gateway_agent, + ), + request_id, + ), + name=f"FireStationAgent-{request_id}", + ) + threads[component_thread] = finish_post_connect_event - return threads + return threads diff --git a/src/adf_core_python/core/launcher/connect/connector_police_force.py b/src/adf_core_python/core/launcher/connect/connector_police_force.py index e2d379b..45acf86 100644 --- a/src/adf_core_python/core/launcher/connect/connector_police_force.py +++ b/src/adf_core_python/core/launcher/connect/connector_police_force.py @@ -6,7 +6,7 @@ from adf_core_python.core.agent.platoon.platoon_police import PlatoonPolice from adf_core_python.core.component.abstract_loader import AbstractLoader from adf_core_python.core.component.tactics.tactics_police_force import ( - TacticsPoliceForce, + TacticsPoliceForce, ) from adf_core_python.core.config.config import Config from adf_core_python.core.gateway.gateway_agent import GatewayAgent @@ -18,77 +18,77 @@ class ConnectorPoliceForce(Connector): - def __init__(self) -> None: - super().__init__() - self.logger = get_logger(__name__) + def __init__(self) -> None: + super().__init__() + self.logger = get_logger(__name__) - def connect( - self, - component_launcher: ComponentLauncher, - gateway_launcher: Optional[GatewayLauncher], - config: Config, - loader: AbstractLoader, - ) -> dict[threading.Thread, threading.Event]: - count: int = config.get_value(ConfigKey.KEY_POLICE_FORCE_COUNT, 0) - if count == 0: - return {} + def connect( + self, + component_launcher: ComponentLauncher, + gateway_launcher: Optional[GatewayLauncher], + config: Config, + loader: AbstractLoader, + ) -> dict[threading.Thread, threading.Event]: + count: int = config.get_value(ConfigKey.KEY_POLICE_FORCE_COUNT, 0) + if count == 0: + return {} - threads: dict[threading.Thread, threading.Event] = {} + threads: dict[threading.Thread, threading.Event] = {} - for _ in range(count): - if loader.get_tactics_police_force() is None: - self.logger.error("Cannot load police force tactics") + for _ in range(count): + if loader.get_tactics_police_force() is None: + self.logger.error("Cannot load police force tactics") - tactics_police_force: TacticsPoliceForce = loader.get_tactics_police_force() + tactics_police_force: TacticsPoliceForce = loader.get_tactics_police_force() - module_config: ModuleConfig = ModuleConfig( - config.get_value( - ConfigKey.KEY_MODULE_CONFIG_FILE_NAME, - ModuleConfig.DEFAULT_CONFIG_FILE_NAME, - ) - ) + module_config: ModuleConfig = ModuleConfig( + config.get_value( + ConfigKey.KEY_MODULE_CONFIG_FILE_NAME, + ModuleConfig.DEFAULT_CONFIG_FILE_NAME, + ) + ) - develop_data: DevelopData = DevelopData( - config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), - config.get_value( - ConfigKey.KEY_DEVELOP_DATA_FILE_NAME, DevelopData.DEFAULT_FILE_NAME - ), - ) + develop_data: DevelopData = DevelopData( + config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), + config.get_value( + ConfigKey.KEY_DEVELOP_DATA_FILE_NAME, DevelopData.DEFAULT_FILE_NAME + ), + ) - precompute_data_dir: str = f"{config.get_value(ConfigKey.KEY_PRECOMPUTE_DATA_DIR, 'precompute')}/police_force" + precompute_data_dir: str = f"{config.get_value(ConfigKey.KEY_PRECOMPUTE_DATA_DIR, 'precompute')}/police_force" - finish_post_connect_event = threading.Event() - request_id: int = component_launcher.generate_request_id() + finish_post_connect_event = threading.Event() + request_id: int = component_launcher.generate_request_id() - gateway_agent: Optional[GatewayAgent] = None - if isinstance(gateway_launcher, GatewayLauncher): - gateway_agent = GatewayAgent(gateway_launcher) - if isinstance(gateway_agent, GatewayAgent): - gateway_thread = threading.Thread( - target=gateway_launcher.connect, - args=(gateway_agent,), - ) - gateway_thread.daemon = True - gateway_thread.start() + gateway_agent: Optional[GatewayAgent] = None + if isinstance(gateway_launcher, GatewayLauncher): + gateway_agent = GatewayAgent(gateway_launcher) + if isinstance(gateway_agent, GatewayAgent): + gateway_thread = threading.Thread( + target=gateway_launcher.connect, + args=(gateway_agent,), + ) + gateway_thread.daemon = True + gateway_thread.start() - component_thread = threading.Thread( - target=component_launcher.connect, - args=( - PlatoonPolice( - tactics_police_force, - "police_force", - config.get_value(ConfigKey.KEY_PRECOMPUTE, False), - config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), - precompute_data_dir, - module_config, - develop_data, - finish_post_connect_event, - gateway_agent, - ), - request_id, - ), - name=f"PoliceForceAgent-{request_id}", - ) - threads[component_thread] = finish_post_connect_event + component_thread = threading.Thread( + target=component_launcher.connect, + args=( + PlatoonPolice( + tactics_police_force, + "police_force", + config.get_value(ConfigKey.KEY_PRECOMPUTE, False), + config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), + precompute_data_dir, + module_config, + develop_data, + finish_post_connect_event, + gateway_agent, + ), + request_id, + ), + name=f"PoliceForceAgent-{request_id}", + ) + threads[component_thread] = finish_post_connect_event - return threads + return threads diff --git a/src/adf_core_python/core/launcher/connect/connector_police_office.py b/src/adf_core_python/core/launcher/connect/connector_police_office.py index 1d26a92..97d75f9 100644 --- a/src/adf_core_python/core/launcher/connect/connector_police_office.py +++ b/src/adf_core_python/core/launcher/connect/connector_police_office.py @@ -6,7 +6,7 @@ from adf_core_python.core.agent.office.office_police import OfficePolice from adf_core_python.core.component.abstract_loader import AbstractLoader from adf_core_python.core.component.tactics.tactics_police_office import ( - TacticsPoliceOffice, + TacticsPoliceOffice, ) from adf_core_python.core.config.config import Config from adf_core_python.core.gateway.gateway_agent import GatewayAgent @@ -18,79 +18,77 @@ class ConnectorPoliceOffice(Connector): - def __init__(self) -> None: - super().__init__() - self.logger = get_logger(__name__) + def __init__(self) -> None: + super().__init__() + self.logger = get_logger(__name__) - def connect( - self, - component_launcher: ComponentLauncher, - gateway_launcher: Optional[GatewayLauncher], - config: Config, - loader: AbstractLoader, - ) -> dict[threading.Thread, threading.Event]: - count: int = config.get_value(ConfigKey.KEY_POLICE_OFFICE_COUNT, 0) - if count == 0: - return {} + def connect( + self, + component_launcher: ComponentLauncher, + gateway_launcher: Optional[GatewayLauncher], + config: Config, + loader: AbstractLoader, + ) -> dict[threading.Thread, threading.Event]: + count: int = config.get_value(ConfigKey.KEY_POLICE_OFFICE_COUNT, 0) + if count == 0: + return {} - threads: dict[threading.Thread, threading.Event] = {} + threads: dict[threading.Thread, threading.Event] = {} - for _ in range(count): - if loader.get_tactics_police_office() is None: - self.logger.error("Cannot load police office tactics") + for _ in range(count): + if loader.get_tactics_police_office() is None: + self.logger.error("Cannot load police office tactics") - tactics_police_office: TacticsPoliceOffice = ( - loader.get_tactics_police_office() - ) + tactics_police_office: TacticsPoliceOffice = loader.get_tactics_police_office() - module_config: ModuleConfig = ModuleConfig( - config.get_value( - ConfigKey.KEY_MODULE_CONFIG_FILE_NAME, - ModuleConfig.DEFAULT_CONFIG_FILE_NAME, - ) - ) + module_config: ModuleConfig = ModuleConfig( + config.get_value( + ConfigKey.KEY_MODULE_CONFIG_FILE_NAME, + ModuleConfig.DEFAULT_CONFIG_FILE_NAME, + ) + ) - develop_data: DevelopData = DevelopData( - config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), - config.get_value( - ConfigKey.KEY_DEVELOP_DATA_FILE_NAME, DevelopData.DEFAULT_FILE_NAME - ), - ) + develop_data: DevelopData = DevelopData( + config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), + config.get_value( + ConfigKey.KEY_DEVELOP_DATA_FILE_NAME, DevelopData.DEFAULT_FILE_NAME + ), + ) - precompute_data_dir: str = f"{config.get_value(ConfigKey.KEY_PRECOMPUTE_DATA_DIR, 'precompute')}/police_office" + precompute_data_dir: str = f"{config.get_value(ConfigKey.KEY_PRECOMPUTE_DATA_DIR, 'precompute')}/police_office" - finish_post_connect_event = threading.Event() - request_id: int = component_launcher.generate_request_id() + finish_post_connect_event = threading.Event() + request_id: int = component_launcher.generate_request_id() - gateway_agent: Optional[GatewayAgent] = None - if isinstance(gateway_launcher, GatewayLauncher): - gateway_agent = GatewayAgent(gateway_launcher) - if isinstance(gateway_agent, GatewayAgent): - gateway_thread = threading.Thread( - target=gateway_launcher.connect, - args=(gateway_agent,), - ) - gateway_thread.daemon = True - gateway_thread.start() + gateway_agent: Optional[GatewayAgent] = None + if isinstance(gateway_launcher, GatewayLauncher): + gateway_agent = GatewayAgent(gateway_launcher) + if isinstance(gateway_agent, GatewayAgent): + gateway_thread = threading.Thread( + target=gateway_launcher.connect, + args=(gateway_agent,), + ) + gateway_thread.daemon = True + gateway_thread.start() - component_thread = threading.Thread( - target=component_launcher.connect, - args=( - OfficePolice( - tactics_police_office, - "police_office", - config.get_value(ConfigKey.KEY_PRECOMPUTE, False), - config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), - precompute_data_dir, - module_config, - develop_data, - finish_post_connect_event, - gateway_agent, - ), - request_id, - ), - name=f"PoliceOfficeAgent-{request_id}", - ) - threads[component_thread] = finish_post_connect_event + component_thread = threading.Thread( + target=component_launcher.connect, + args=( + OfficePolice( + tactics_police_office, + "police_office", + config.get_value(ConfigKey.KEY_PRECOMPUTE, False), + config.get_value(ConfigKey.KEY_DEBUG_FLAG, False), + precompute_data_dir, + module_config, + develop_data, + finish_post_connect_event, + gateway_agent, + ), + request_id, + ), + name=f"PoliceOfficeAgent-{request_id}", + ) + threads[component_thread] = finish_post_connect_event - return threads + return threads diff --git a/src/adf_core_python/core/launcher/connect/error/agent_error.py b/src/adf_core_python/core/launcher/connect/error/agent_error.py index 8725dba..7eee9fe 100644 --- a/src/adf_core_python/core/launcher/connect/error/agent_error.py +++ b/src/adf_core_python/core/launcher/connect/error/agent_error.py @@ -1,2 +1,2 @@ class AgentError(Exception): - pass + pass diff --git a/src/adf_core_python/core/launcher/connect/error/server_error.py b/src/adf_core_python/core/launcher/connect/error/server_error.py index 8c3951c..a1d0ea2 100644 --- a/src/adf_core_python/core/launcher/connect/error/server_error.py +++ b/src/adf_core_python/core/launcher/connect/error/server_error.py @@ -1,2 +1,2 @@ class ServerError(Exception): - pass + pass diff --git a/src/adf_core_python/core/logger/logger.py b/src/adf_core_python/core/logger/logger.py index 8b8f2f6..1f9a61d 100644 --- a/src/adf_core_python/core/logger/logger.py +++ b/src/adf_core_python/core/logger/logger.py @@ -11,86 +11,86 @@ def get_logger(name: str) -> structlog.BoundLogger: - """ - Get a logger with the given name. - For kernel logging, use this function to get a logger. + """ + Get a logger with the given name. + For kernel logging, use this function to get a logger. - Parameters - ---------- - name : str - The name of the logger. + Parameters + ---------- + name : str + The name of the logger. - Returns - ------- - structlog.BoundLogger - The logger with the given name. - """ - return structlog.get_logger(name) + Returns + ------- + structlog.BoundLogger + The logger with the given name. + """ + return structlog.get_logger(name) def get_agent_logger(name: str, agent_info: AgentInfo) -> structlog.BoundLogger: - """ - Get a logger with the given name and agent information. - For agent logging, use this function to get a logger. - - Parameters - ---------- - name : str - The name of the logger. - agent_info : AgentInfo - The agent information. - - Returns - ------- - structlog.BoundLogger - The logger with the given name and agent information. - """ - agent = agent_info.get_myself() - if agent is None: - raise ValueError("Agent information is not available") - - return structlog.get_logger(name).bind( - agent_id=str(agent_info.get_entity_id()), - agent_type=str(agent.get_urn().name), - ) + """ + Get a logger with the given name and agent information. + For agent logging, use this function to get a logger. + + Parameters + ---------- + name : str + The name of the logger. + agent_info : AgentInfo + The agent information. + + Returns + ------- + structlog.BoundLogger + The logger with the given name and agent information. + """ + agent = agent_info.get_myself() + if agent is None: + raise ValueError("Agent information is not available") + + return structlog.get_logger(name).bind( + agent_id=str(agent_info.get_entity_id()), + agent_type=str(agent.get_urn().name), + ) def configure_logger() -> None: - # 既存のログファイルが存在する場合、日付付きでバックアップする - log_file = "agent.log" - if os.path.exists(log_file): - timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") - backup_file = f"agent_{timestamp}.log" - os.rename(log_file, backup_file) - - structlog.configure( - processors=[ - structlog.stdlib.add_log_level, - structlog.stdlib.add_logger_name, - structlog.stdlib.PositionalArgumentsFormatter(), - structlog.processors.TimeStamper(fmt="%Y-%m-%d %H:%M.%S", utc=False), - structlog.processors.StackInfoRenderer(), - structlog.processors.UnicodeDecoder(), - structlog.stdlib.ProcessorFormatter.wrap_for_formatter, - ], - logger_factory=structlog.stdlib.LoggerFactory(), - wrapper_class=structlog.stdlib.BoundLogger, - cache_logger_on_first_use=True, - ) - - handler_stdout = logging.StreamHandler(sys.stdout) - handler_stdout.setFormatter( - structlog.stdlib.ProcessorFormatter(processor=ConsoleRenderer()) - ) - handler_stdout.setLevel(logging.INFO) - - handler_file = logging.FileHandler(log_file) - handler_file.setFormatter( - structlog.stdlib.ProcessorFormatter(processor=JSONRenderer()) - ) - handler_file.setLevel(logging.DEBUG) - - root_logger = logging.getLogger() - root_logger.addHandler(handler_stdout) - root_logger.addHandler(handler_file) - root_logger.setLevel(logging.DEBUG) + # 既存のログファイルが存在する場合、日付付きでバックアップする + log_file = "agent.log" + if os.path.exists(log_file): + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + backup_file = f"agent_{timestamp}.log" + os.rename(log_file, backup_file) + + structlog.configure( + processors=[ + structlog.stdlib.add_log_level, + structlog.stdlib.add_logger_name, + structlog.stdlib.PositionalArgumentsFormatter(), + structlog.processors.TimeStamper(fmt="%Y-%m-%d %H:%M.%S", utc=False), + structlog.processors.StackInfoRenderer(), + structlog.processors.UnicodeDecoder(), + structlog.stdlib.ProcessorFormatter.wrap_for_formatter, + ], + logger_factory=structlog.stdlib.LoggerFactory(), + wrapper_class=structlog.stdlib.BoundLogger, + cache_logger_on_first_use=True, + ) + + handler_stdout = logging.StreamHandler(sys.stdout) + handler_stdout.setFormatter( + structlog.stdlib.ProcessorFormatter(processor=ConsoleRenderer()) + ) + handler_stdout.setLevel(logging.INFO) + + handler_file = logging.FileHandler(log_file) + handler_file.setFormatter( + structlog.stdlib.ProcessorFormatter(processor=JSONRenderer()) + ) + handler_file.setLevel(logging.DEBUG) + + root_logger = logging.getLogger() + root_logger.addHandler(handler_stdout) + root_logger.addHandler(handler_file) + root_logger.setLevel(logging.DEBUG) diff --git a/src/adf_core_python/implement/action/default_extend_action_clear.py b/src/adf_core_python/implement/action/default_extend_action_clear.py index 7e09b41..ad837e9 100644 --- a/src/adf_core_python/implement/action/default_extend_action_clear.py +++ b/src/adf_core_python/implement/action/default_extend_action_clear.py @@ -3,16 +3,16 @@ from typing import Optional, cast from rcrscore.entities import ( - AmbulanceTeam, - Area, - Blockade, - Building, - EntityID, - FireBrigade, - Human, - PoliceForce, - Refuge, - Road, + AmbulanceTeam, + Area, + Blockade, + Building, + EntityID, + FireBrigade, + Human, + PoliceForce, + Refuge, + Road, ) from shapely import LineString, Point, Polygon @@ -33,771 +33,720 @@ class DefaultExtendActionClear(ExtendAction): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - self._clear_distance = float( - self.scenario_info.get_value("clear.repair.distance", 0.0) - ) - self._forced_move = float( - develop_data.get_value( - "adf_core_python.implement.action.DefaultExtendActionClear.forced_move", - 3, - ) - ) - self._threshold_rest = float( - develop_data.get_value( - "adf_core_python.implement.action.DefaultExtendActionClear.rest", 100 - ) - ) - - self._target_entity_id: Optional[EntityID] = None - self._move_point_cache: dict[EntityID, Optional[set[tuple[float, float]]]] = {} - self._old_clear_x = 0 - self._old_clear_y = 0 - self.count = 0 - - 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) - if self.get_count_precompute() >= 2: - return self - self._path_planning.precompute(precompute_data) - self._kernel_time = self.scenario_info.get_value("kernel.timesteps", -1) - return self - - def resume(self, precompute_data: PrecomputeData) -> ExtendAction: - super().resume(precompute_data) - if self.get_count_resume() >= 2: - return self - self._path_planning.resume(precompute_data) - self._kernel_time = self.scenario_info.get_value("kernel.timesteps", -1) + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + self._clear_distance = float( + self.scenario_info.get_value("clear.repair.distance", 0.0) + ) + self._forced_move = float( + develop_data.get_value( + "adf_core_python.implement.action.DefaultExtendActionClear.forced_move", + 3, + ) + ) + self._threshold_rest = float( + develop_data.get_value( + "adf_core_python.implement.action.DefaultExtendActionClear.rest", 100 + ) + ) + + self._target_entity_id: Optional[EntityID] = None + self._move_point_cache: dict[EntityID, Optional[set[tuple[float, float]]]] = {} + self._old_clear_x = 0 + self._old_clear_y = 0 + self.count = 0 + + 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) + if self.get_count_precompute() >= 2: + return self + self._path_planning.precompute(precompute_data) + self._kernel_time = self.scenario_info.get_value("kernel.timesteps", -1) + return self + + def resume(self, precompute_data: PrecomputeData) -> ExtendAction: + super().resume(precompute_data) + if self.get_count_resume() >= 2: + return self + self._path_planning.resume(precompute_data) + self._kernel_time = self.scenario_info.get_value("kernel.timesteps", -1) + return self + + def prepare(self) -> ExtendAction: + super().prepare() + if self.get_count_prepare() >= 2: + return self + self._path_planning.prepare() + self._kernel_time = self.scenario_info.get_value("kernel.timesteps", -1) + return self + + def update_info(self, message_manager: MessageManager) -> ExtendAction: + super().update_info(message_manager) + if self.get_count_update_info() >= 2: + return self + self._path_planning.update_info(message_manager) + return self + + def set_target_entity_id(self, target_entity_id: EntityID) -> ExtendAction: + self._target_entity_id = None + target_entity = self.world_info.get_entity(target_entity_id) + if target_entity is not None: + if isinstance(target_entity, Road): + self._target_entity_id = target_entity_id + elif isinstance(target_entity, Blockade): + self._target_entity_id = target_entity.get_position() + elif isinstance(target_entity, Building): + self._target_entity_id = target_entity_id + return self + + def calculate(self) -> ExtendAction: + self.result = None + police_force = cast(PoliceForce, self.agent_info.get_myself()) + + if self._need_rest(police_force): + target_entity_ids: list[EntityID] = [] + if self._target_entity_id is not None: + target_entity_ids.append(self._target_entity_id) + + self.result = self._calc_rest( + police_force, self._path_planning, target_entity_ids + ) + if self.result is not None: return self - def prepare(self) -> ExtendAction: - super().prepare() - if self.get_count_prepare() >= 2: - return self - self._path_planning.prepare() - self._kernel_time = self.scenario_info.get_value("kernel.timesteps", -1) + if self._target_entity_id is None: + return self + + agent_position_entity_id = police_force.get_position() + if agent_position_entity_id is None: + return self + target_entity = self.world_info.get_entity(self._target_entity_id) + position_entity = self.world_info.get_entity(agent_position_entity_id) + if target_entity is None or isinstance(target_entity, Area) is False: + return self + if isinstance(position_entity, Road): + self.result = self._get_rescue_action(police_force, position_entity) + if self.result is not None: return self - def update_info(self, message_manager: MessageManager) -> ExtendAction: - super().update_info(message_manager) - if self.get_count_update_info() >= 2: - return self - self._path_planning.update_info(message_manager) + if agent_position_entity_id == self._target_entity_id: + self.result = self._get_area_clear_action( + police_force, cast(Road, position_entity) + ) + if self.result is not None: return self + elif cast(Area, target_entity).get_edge_to(agent_position_entity_id) is not None: + self.result = self._get_neighbour_position_action( + police_force, cast(Area, target_entity) + ) + else: + path = self._path_planning.get_path( + agent_position_entity_id, self._target_entity_id + ) + if path is not None and len(path) > 0: + index = self._index_of(path, agent_position_entity_id) + if index == -1: + area = cast(Area, position_entity) + for i in range(0, len(path), 1): + if area.get_edge_to(path[i]) is not None: + index = i + break + + elif index >= 0: + index += 1 + + if index >= 0 and index < len(path): + entity = self.world_info.get_entity(path[index]) + self.result = self._get_neighbour_position_action( + police_force, cast(Area, entity) + ) + if self.result is not None and isinstance(self.result, ActionMove): + action_move = self.result + if action_move.is_destination_defined(): + self.result = None + + if self.result is None: + self.result = ActionMove(path) + + return self + + def _need_rest(self, police_force: PoliceForce) -> bool: + hp = police_force.get_hp() + damage = police_force.get_damage() + + if hp is None or damage is None or hp == 0 or damage == 0: + return False + + active_time = (hp / damage) + (1 if (hp % damage) != 0 else 0) + if self._kernel_time == -1: + self._kernel_time = self.scenario_info.get_value("kernel.timesteps", -1) + + return damage is not None and ( + damage >= self._threshold_rest + or (active_time + self.agent_info.get_time() < self._kernel_time) + ) + + def _calc_rest( + self, + police_force: PoliceForce, + path_planning: PathPlanning, + target_entity_ids: list[EntityID], + ) -> Optional[Action]: + position_entity_id = police_force.get_position() + if position_entity_id is None: + return None + refuges = self.world_info.get_entity_ids_of_types([Refuge]) + current_size = len(refuges) + if position_entity_id in refuges: + return ActionRest() + + first_result: list[EntityID] = [] + while len(refuges) > 0: + path = path_planning.get_path(position_entity_id, refuges[0]) + if path is not None and len(path) > 0: + if first_result == []: + first_result = path.copy() + if target_entity_ids == []: + break + + refuge_entity_id = path[-1] + from_refuge_to_target_path = path_planning.get_path( + refuge_entity_id, target_entity_ids[0] + ) + if from_refuge_to_target_path != []: + return ActionMove(path) - def set_target_entity_id(self, target_entity_id: EntityID) -> ExtendAction: - self._target_entity_id = None - target_entity = self.world_info.get_entity(target_entity_id) - if target_entity is not None: - if isinstance(target_entity, Road): - self._target_entity_id = target_entity_id - elif isinstance(target_entity, Blockade): - self._target_entity_id = target_entity.get_position() - elif isinstance(target_entity, Building): - self._target_entity_id = target_entity_id - return self - - def calculate(self) -> ExtendAction: - self.result = None - police_force = cast(PoliceForce, self.agent_info.get_myself()) - - if self._need_rest(police_force): - target_entity_ids: list[EntityID] = [] - if self._target_entity_id is not None: - target_entity_ids.append(self._target_entity_id) - - self.result = self._calc_rest( - police_force, self._path_planning, target_entity_ids - ) - if self.result is not None: - return self - - if self._target_entity_id is None: - return self - - agent_position_entity_id = police_force.get_position() - if agent_position_entity_id is None: - return self - target_entity = self.world_info.get_entity(self._target_entity_id) - position_entity = self.world_info.get_entity(agent_position_entity_id) - if target_entity is None or isinstance(target_entity, Area) is False: - return self - if isinstance(position_entity, Road): - self.result = self._get_rescue_action(police_force, position_entity) - if self.result is not None: - return self - - if agent_position_entity_id == self._target_entity_id: - self.result = self._get_area_clear_action( - police_force, cast(Road, position_entity) - ) - if self.result is not None: - return self - elif ( - cast(Area, target_entity).get_edge_to(agent_position_entity_id) is not None + refuges.remove(refuge_entity_id) + if current_size == len(refuges): + break + current_size = len(refuges) + else: + break + + return ActionMove(first_result) if first_result != [] else None + + def _get_rescue_action( + self, police_entity: PoliceForce, road: Road + ) -> Optional[Action]: + road_blockades = road.get_blockades() + blockades = set( + [] + if road_blockades is None + else [ + cast(Blockade, self.world_info.get_entity(blockade_entity_id)) + for blockade_entity_id in road_blockades + ] + ) + agent_entities = set( + self.world_info.get_entities_of_types([AmbulanceTeam, FireBrigade]) + ) + + police_x = police_entity.get_x() + police_y = police_entity.get_y() + min_distance = sys.float_info.max + move_action: Optional[ActionMove] = None + + for agent_entity in agent_entities: + human = cast(Human, agent_entity) + human_position = human.get_position() + if ( + human_position is None + or human_position.get_value() != road.get_entity_id().get_value() + ): + continue + + human_x = human.get_x() + human_y = human.get_y() + if human_x is None or human_y is None or police_x is None or police_y is None: + continue + + action_clear: Optional[ActionClear | ActionClearArea] = None + clear_blockade: Optional[Blockade] = None + for blockade in blockades: + blockade_apexes = blockade.get_apexes() + if blockade_apexes is None or not self._is_inside( + human_x, human_y, blockade_apexes ): - self.result = self._get_neighbour_position_action( - police_force, cast(Area, target_entity) - ) - else: - path = self._path_planning.get_path( - agent_position_entity_id, self._target_entity_id - ) - if path is not None and len(path) > 0: - index = self._index_of(path, agent_position_entity_id) - if index == -1: - area = cast(Area, position_entity) - for i in range(0, len(path), 1): - if area.get_edge_to(path[i]) is not None: - index = i - break - - elif index >= 0: - index += 1 - - if index >= 0 and index < len(path): - entity = self.world_info.get_entity(path[index]) - self.result = self._get_neighbour_position_action( - police_force, cast(Area, entity) - ) - if self.result is not None and isinstance(self.result, ActionMove): - action_move = self.result - if action_move.is_destination_defined(): - self.result = None - - if self.result is None: - self.result = ActionMove(path) - - return self + continue + + distance = self._get_distance(police_x, police_y, human_x, human_y) + if self._is_intersecting_area(police_x, police_y, human_x, human_y, road): + action = self._get_intersect_edge_action( + police_x, police_y, human_x, human_y, road + ) + if action is None: + continue + if isinstance(action, ActionClear): + if action_clear is None: + action_clear = action + clear_blockade = blockade + continue + + if clear_blockade is not None: + if self._is_intersecting_blockades(blockade, clear_blockade): + return ActionClear(clear_blockade) - def _need_rest(self, police_force: PoliceForce) -> bool: - hp = police_force.get_hp() - damage = police_force.get_damage() + another_distance = self.world_info.get_distance( + police_entity.get_entity_id(), + clear_blockade.get_entity_id(), + ) + blockade_distance = self.world_info.get_distance( + police_entity.get_entity_id(), blockade.get_entity_id() + ) + if blockade_distance < another_distance: + return action + + return action_clear + elif isinstance(action, ActionMove) and distance < min_distance: + min_distance = distance + move_action = action + + elif self._is_intersecting_blockade( + police_x, police_y, human_x, human_y, blockade + ): + vector = self._scale_clear( + self._get_vector(police_x, police_y, human_x, human_y) + ) + clear_x = int(police_x + vector[0]) + clear_y = int(police_y + vector[1]) - if hp is None or damage is None or hp == 0 or damage == 0: - return False + vector = self._scale_back_clear(vector) + start_x = int(police_x + vector[0]) + start_y = int(police_y + vector[1]) - active_time = (hp / damage) + (1 if (hp % damage) != 0 else 0) - if self._kernel_time == -1: - self._kernel_time = self.scenario_info.get_value("kernel.timesteps", -1) + if self._is_intersecting_blockade( + start_x, start_y, clear_x, clear_y, blockade + ): + if action_clear is None: + action_clear = ActionClearArea(clear_x, clear_y) + clear_blockade = blockade + else: + if clear_blockade is not None: + if self._is_intersecting_blockades(blockade, clear_blockade): + return ActionClear(clear_blockade) + + distance1 = self.world_info.get_distance( + police_entity.get_entity_id(), + clear_blockade.get_entity_id(), + ) + distance2 = self.world_info.get_distance( + police_entity.get_entity_id(), + blockade.get_entity_id(), + ) + if distance1 > distance2: + return ActionClearArea(clear_x, clear_y) - return damage is not None and ( - damage >= self._threshold_rest - or (active_time + self.agent_info.get_time() < self._kernel_time) - ) + return action_clear - def _calc_rest( - self, - police_force: PoliceForce, - path_planning: PathPlanning, - target_entity_ids: list[EntityID], - ) -> Optional[Action]: - position_entity_id = police_force.get_position() - if position_entity_id is None: - return None - refuges = self.world_info.get_entity_ids_of_types([Refuge]) - current_size = len(refuges) - if position_entity_id in refuges: - return ActionRest() - - first_result: list[EntityID] = [] - while len(refuges) > 0: - path = path_planning.get_path(position_entity_id, refuges[0]) - if path is not None and len(path) > 0: - if first_result == []: - first_result = path.copy() - if target_entity_ids == []: - break - - refuge_entity_id = path[-1] - from_refuge_to_target_path = path_planning.get_path( - refuge_entity_id, target_entity_ids[0] - ) - if from_refuge_to_target_path != []: - return ActionMove(path) - - refuges.remove(refuge_entity_id) - if current_size == len(refuges): - break - current_size = len(refuges) + elif distance < min_distance: + min_distance = distance + move_action = ActionMove([road.get_entity_id()], human_x, human_y) + + if action_clear is not None: + return action_clear + + return move_action + + def _is_inside(self, x: float, y: float, apexes: list[int]) -> bool: + point = Point(x, y) + polygon = Polygon([(apexes[i], apexes[i + 1]) for i in range(0, len(apexes), 2)]) + return polygon.contains(point) + + def _get_distance(self, x1: float, y1: float, x2: float, y2: float) -> float: + return ((x1 - x2) ** 2 + (y1 - y2) ** 2) ** 0.5 + + def _is_intersecting_area( + self, agent_x: float, agent_y: float, point_x: float, point_y: float, area: Area + ) -> bool: + edges = area.get_edges() + if edges is None: + return False + for edge in edges: + start_x = edge.get_start_x() + start_y = edge.get_start_y() + end_x = edge.get_end_x() + end_y = edge.get_end_y() + + line1 = LineString([(agent_x, agent_y), (point_x, point_y)]) + line2 = LineString([(start_x, start_y), (end_x, end_y)]) + if line1.intersects(line2): + mid_x = (start_x + end_x) / 2.0 + mid_y = (start_y + end_y) / 2.0 + if not self._equals_point( + agent_x, agent_y, mid_x, mid_y, 1000 + ) and not self._equals_point(point_x, point_y, mid_x, mid_y, 1000): + return True + + return False + + def _equals_point( + self, x1: float, y1: float, x2: float, y2: float, range: float + ) -> bool: + return (x2 - range < x1 and x1 < x2 + range) and ( + y2 - range < y1 and y1 < y2 + range + ) + + def _get_intersect_edge_action( + self, agent_x: float, agent_y: float, point_x: float, point_y: float, road: Road + ) -> Action: + move_points = self._get_move_points(road) + best_point: Optional[tuple[float, float]] = None + best_distance = sys.float_info.max + for point in move_points: + if not self._is_intersecting_area(agent_x, agent_y, point[0], point[1], road): + if not self._is_intersecting_area(point_x, point_y, point[0], point[1], road): + distance = self._get_distance(point_x, point_y, point[0], point[1]) + if distance < best_distance: + best_point = point + best_distance = distance + + if best_point is not None: + bp_x, bp_y = best_point + if road.get_blockades() is None: + return ActionMove([road.get_entity_id()], int(bp_x), int(bp_y)) + + action_clear: Optional[ActionClearArea] = None + clear_blockade: Optional[Blockade] = None + action_move: Optional[ActionMove] = None + + vector = self._scale_clear(self._get_vector(agent_x, agent_y, bp_x, bp_y)) + clear_x = int(agent_x + vector[0]) + clear_y = int(agent_x + vector[1]) + + vector = self._scale_back_clear(vector) + start_x = int(agent_x + vector[0]) + start_y = int(agent_y + vector[1]) + + for blockade in self.world_info.get_blockades(road): + if self._is_intersecting_blockade(start_x, start_y, bp_x, bp_y, blockade): + if self._is_intersecting_blockade( + start_x, start_y, clear_x, clear_y, blockade + ): + if action_clear is None: + action_clear = ActionClearArea(clear_x, clear_y) + clear_blockade = blockade else: - break - - return ActionMove(first_result) if first_result != [] else None - - def _get_rescue_action( - self, police_entity: PoliceForce, road: Road - ) -> Optional[Action]: - road_blockades = road.get_blockades() - blockades = set( - [] - if road_blockades is None - else [ - cast(Blockade, self.world_info.get_entity(blockade_entity_id)) - for blockade_entity_id in road_blockades - ] - ) - agent_entities = set( - self.world_info.get_entities_of_types([AmbulanceTeam, FireBrigade]) + if clear_blockade is not None and self._is_intersecting_blockades( + blockade, clear_blockade + ): + return ActionClear(clear_blockade) + return action_clear + elif action_move is None: + action_move = ActionMove([road.get_entity_id()], int(bp_x), int(bp_y)) + + if action_clear is not None: + return action_clear + if action_move is not None: + return action_move + + action = self._get_area_clear_action( + cast(PoliceForce, self.agent_info.get_myself()), road + ) + if action is None: + action = ActionMove([road.get_entity_id()], int(point_x), int(point_y)) + return action + + def _get_move_points(self, road: Road) -> set[tuple[float, float]]: + points: Optional[set[tuple[float, float]]] = self._move_point_cache.get( + road.get_entity_id() + ) + if points is None: + points = set() + apex = road.get_apexes() + for i in range(0, len(apex), 2): + for j in range(i + 2, len(apex), 2): + mid_x = (apex[i] + apex[j]) / 2.0 + mid_y = (apex[i + 1] + apex[j + 1]) / 2.0 + if self._is_inside(mid_x, mid_y, apex): + points.add((mid_x, mid_y)) + + edges = road.get_edges() + if edges is not None: + for edge in edges: + mid_x = (edge.get_start_x() + edge.get_end_x()) / 2.0 + mid_y = (edge.get_start_y() + edge.get_end_y()) / 2.0 + if (mid_x, mid_y) in points: + points.remove((mid_x, mid_y)) + + self._move_point_cache[road.get_entity_id()] = points + + return points + + def _get_vector( + self, from_x: float, from_y: float, to_x: float, to_y: float + ) -> tuple[float, float]: + return (to_x - from_x, to_y - from_y) + + def _scale_clear(self, vector: tuple[float, float]) -> tuple[float, float]: + length = 1.0 / math.hypot(vector[0], vector[1]) + return ( + vector[0] * length * self._clear_distance, + vector[1] * length * self._clear_distance, + ) + + def _scale_back_clear(self, vector: tuple[float, float]) -> tuple[float, float]: + length = 1.0 / math.hypot(vector[0], vector[1]) + return (vector[0] * length * -510, vector[1] * length * -510) + + def _is_intersecting_blockade( + self, + agent_x: float, + agent_y: float, + point_x: float, + point_y: float, + blockade: Blockade, + ) -> bool: + apexes = blockade.get_apexes() + if apexes is None or len(apexes) < 4: + return False + for i in range(0, len(apexes) - 3, 2): + line1 = LineString([(apexes[i], apexes[i + 1]), (apexes[i + 2], apexes[i + 3])]) + line2 = LineString([(agent_x, agent_y), (point_x, point_y)]) + if line1.intersects(line2): + return True + return False + + def _is_intersecting_blockades( + self, blockade1: Blockade, blockade2: Blockade + ) -> bool: + apexes1 = blockade1.get_apexes() + apexes2 = blockade2.get_apexes() + if apexes1 is None or apexes2 is None or len(apexes1) < 4 or len(apexes2) < 4: + return False + for i in range(0, len(apexes1) - 2, 2): + for j in range(0, len(apexes2) - 2, 2): + line1 = LineString( + [(apexes1[i], apexes1[i + 1]), (apexes1[i + 2], apexes1[i + 3])] ) - - police_x = police_entity.get_x() - police_y = police_entity.get_y() - min_distance = sys.float_info.max - move_action: Optional[ActionMove] = None - - for agent_entity in agent_entities: - human = cast(Human, agent_entity) - human_position = human.get_position() - if ( - human_position is None - or human_position.get_value() != road.get_entity_id().get_value() - ): - continue - - human_x = human.get_x() - human_y = human.get_y() - if ( - human_x is None - or human_y is None - or police_x is None - or police_y is None - ): - continue - - action_clear: Optional[ActionClear | ActionClearArea] = None - clear_blockade: Optional[Blockade] = None - for blockade in blockades: - blockade_apexes = blockade.get_apexes() - if blockade_apexes is None or not self._is_inside( - human_x, human_y, blockade_apexes - ): - continue - - distance = self._get_distance(police_x, police_y, human_x, human_y) - if self._is_intersecting_area( - police_x, police_y, human_x, human_y, road - ): - action = self._get_intersect_edge_action( - police_x, police_y, human_x, human_y, road - ) - if action is None: - continue - if isinstance(action, ActionClear): - if action_clear is None: - action_clear = action - clear_blockade = blockade - continue - - if clear_blockade is not None: - if self._is_intersecting_blockades( - blockade, clear_blockade - ): - return ActionClear(clear_blockade) - - another_distance = self.world_info.get_distance( - police_entity.get_entity_id(), - clear_blockade.get_entity_id(), - ) - blockade_distance = self.world_info.get_distance( - police_entity.get_entity_id(), blockade.get_entity_id() - ) - if blockade_distance < another_distance: - return action - - return action_clear - elif isinstance(action, ActionMove) and distance < min_distance: - min_distance = distance - move_action = action - - elif self._is_intersecting_blockade( - police_x, police_y, human_x, human_y, blockade - ): - vector = self._scale_clear( - self._get_vector(police_x, police_y, human_x, human_y) - ) - clear_x = int(police_x + vector[0]) - clear_y = int(police_y + vector[1]) - - vector = self._scale_back_clear(vector) - start_x = int(police_x + vector[0]) - start_y = int(police_y + vector[1]) - - if self._is_intersecting_blockade( - start_x, start_y, clear_x, clear_y, blockade - ): - if action_clear is None: - action_clear = ActionClearArea(clear_x, clear_y) - clear_blockade = blockade - else: - if clear_blockade is not None: - if self._is_intersecting_blockades( - blockade, clear_blockade - ): - return ActionClear(clear_blockade) - - distance1 = self.world_info.get_distance( - police_entity.get_entity_id(), - clear_blockade.get_entity_id(), - ) - distance2 = self.world_info.get_distance( - police_entity.get_entity_id(), - blockade.get_entity_id(), - ) - if distance1 > distance2: - return ActionClearArea(clear_x, clear_y) - - return action_clear - - elif distance < min_distance: - min_distance = distance - move_action = ActionMove( - [road.get_entity_id()], human_x, human_y - ) - - if action_clear is not None: - return action_clear - - return move_action - - def _is_inside(self, x: float, y: float, apexes: list[int]) -> bool: - point = Point(x, y) - polygon = Polygon( - [(apexes[i], apexes[i + 1]) for i in range(0, len(apexes), 2)] + line2 = LineString( + [(apexes2[j], apexes2[j + 1]), (apexes2[j + 2], apexes2[j + 3])] ) - return polygon.contains(point) + if line1.intersects(line2): + return True + + for i in range(0, len(apexes1) - 2, 2): + line1 = LineString( + [(apexes1[i], apexes1[i + 1]), (apexes1[i + 2], apexes1[i + 3])] + ) + line2 = LineString([(apexes2[-2], apexes2[-1]), (apexes2[0], apexes2[1])]) + if line1.intersects(line2): + return True + + for i in range(0, len(apexes2) - 2, 2): + line1 = LineString([(apexes1[-2], apexes1[-1]), (apexes1[0], apexes1[1])]) + line2 = LineString( + [(apexes2[i], apexes2[i + 1]), (apexes2[i + 2], apexes2[i + 3])] + ) + if line1.intersects(line2): + return True + + return False + + def _get_area_clear_action( + self, police_entity: PoliceForce, road: Road + ) -> Optional[Action]: + if road.get_blockades() == []: + return None + + blockades = set(self.world_info.get_blockades(road)) + min_distance = sys.float_info.max + clear_blockade: Optional[Blockade] = None + for blockade in blockades: + for another in blockades: + if blockade == another: + continue + + if self._is_intersecting_blockades(blockade, another): + distance1 = self.world_info.get_distance( + police_entity.get_entity_id(), blockade.get_entity_id() + ) + distance2 = self.world_info.get_distance( + police_entity.get_entity_id(), another.get_entity_id() + ) + if distance1 <= distance2 and distance1 < min_distance: + min_distance = distance1 + clear_blockade = blockade + elif distance2 < min_distance: + min_distance = distance2 + clear_blockade = another + + if clear_blockade is not None: + if min_distance < self._clear_distance: + return ActionClear(clear_blockade) + else: + position = police_entity.get_position() + if position is not None: + return ActionMove( + [position], + clear_blockade.get_x(), + clear_blockade.get_y(), + ) + + agent_x = police_entity.get_x() + agent_y = police_entity.get_y() + if agent_x is None or agent_y is None: + return None + clear_blockade = None + min_point_distance = sys.float_info.max + clear_x = 0 + clear_y = 0 + for blockade in blockades: + apexes = blockade.get_apexes() + if apexes is None or len(apexes) < 4: + continue + for i in range(0, len(apexes) - 2, 2): + distance = self._get_distance(agent_x, agent_y, apexes[i], apexes[i + 1]) + if distance < min_point_distance: + clear_blockade = blockade + min_point_distance = distance + clear_x = apexes[i] + clear_y = apexes[i + 1] + + if clear_blockade is not None: + if min_point_distance < self._clear_distance: + vector = self._scale_clear(self._get_vector(agent_x, agent_y, clear_x, clear_y)) + clear_x = int(agent_x + vector[0]) + clear_y = int(agent_y + vector[1]) + return ActionClearArea(clear_x, clear_y) + position = police_entity.get_position() + if position is not None: + return ActionMove([position], clear_x, clear_y) + + return None + + def _index_of(self, list: list[EntityID], x: EntityID) -> int: + return list.index(x) if x in list else -1 + + def _get_neighbour_position_action( + self, police_entity: PoliceForce, target: Area + ) -> Optional[Action]: + agent_x = police_entity.get_x() + agent_y = police_entity.get_y() + if agent_x is None or agent_y is None: + return None + position_id = police_entity.get_position() + if position_id is None: + return None + position = self.world_info.get_entity(position_id) + if position is None: + return None + + edge = target.get_edge_to(position.get_entity_id()) + if edge is None: + return None + + if isinstance(position, Road): + road = position + if road.get_blockades() != []: + mid_x = (edge.get_start_x() + edge.get_end_x()) / 2.0 + mid_y = (edge.get_start_y() + edge.get_end_y()) / 2.0 + if self._is_intersecting_area(agent_x, agent_y, mid_x, mid_y, road): + return self._get_intersect_edge_action(agent_x, agent_y, mid_x, mid_y, road) + + action_clear: Optional[ActionClear | ActionClearArea] = None + clear_blockade: Optional[Blockade] = None + action_move: Optional[ActionMove] = None - def _get_distance(self, x1: float, y1: float, x2: float, y2: float) -> float: - return ((x1 - x2) ** 2 + (y1 - y2) ** 2) ** 0.5 + vector = self._scale_clear(self._get_vector(agent_x, agent_y, mid_x, mid_y)) + clear_x = int(agent_x + vector[0]) + clear_y = int(agent_y + vector[1]) - def _is_intersecting_area( - self, agent_x: float, agent_y: float, point_x: float, point_y: float, area: Area - ) -> bool: - edges = area.get_edges() - if edges is None: - return False - for edge in edges: - start_x = edge.get_start_x() - start_y = edge.get_start_y() - end_x = edge.get_end_x() - end_y = edge.get_end_y() - - line1 = LineString([(agent_x, agent_y), (point_x, point_y)]) - line2 = LineString([(start_x, start_y), (end_x, end_y)]) - if line1.intersects(line2): - mid_x = (start_x + end_x) / 2.0 - mid_y = (start_y + end_y) / 2.0 - if not self._equals_point( - agent_x, agent_y, mid_x, mid_y, 1000 - ) and not self._equals_point(point_x, point_y, mid_x, mid_y, 1000): - return True - - return False - - def _equals_point( - self, x1: float, y1: float, x2: float, y2: float, range: float - ) -> bool: - return (x2 - range < x1 and x1 < x2 + range) and ( - y2 - range < y1 and y1 < y2 + range - ) + vector = self._scale_back_clear(vector) + start_x = int(agent_x + vector[0]) + start_y = int(agent_y + vector[1]) - def _get_intersect_edge_action( - self, agent_x: float, agent_y: float, point_x: float, point_y: float, road: Road - ) -> Action: - move_points = self._get_move_points(road) - best_point: Optional[tuple[float, float]] = None - best_distance = sys.float_info.max - for point in move_points: - if not self._is_intersecting_area( - agent_x, agent_y, point[0], point[1], road + for blockade in self.world_info.get_blockades(road): + if self._is_intersecting_blockade(start_x, start_y, mid_x, mid_y, blockade): + if self._is_intersecting_blockade( + start_x, start_y, clear_x, clear_y, blockade ): - if not self._is_intersecting_area( - point_x, point_y, point[0], point[1], road + if action_clear is None: + action_clear = ActionClearArea(clear_x, clear_y) + clear_blockade = blockade + if self._equals_point( + self._old_clear_x, + self._old_clear_y, + clear_x, + clear_y, + 1000, ): - distance = self._get_distance(point_x, point_y, point[0], point[1]) - if distance < best_distance: - best_point = point - best_distance = distance - - if best_point is not None: - bp_x, bp_y = best_point - if road.get_blockades() is None: - return ActionMove([road.get_entity_id()], int(bp_x), int(bp_y)) - - action_clear: Optional[ActionClearArea] = None - clear_blockade: Optional[Blockade] = None - action_move: Optional[ActionMove] = None - - vector = self._scale_clear(self._get_vector(agent_x, agent_y, bp_x, bp_y)) - clear_x = int(agent_x + vector[0]) - clear_y = int(agent_x + vector[1]) + if self.count >= self._forced_move: + self.count = 0 + return ActionMove( + [road.get_entity_id()], + int(clear_x), + int(clear_y), + ) + self.count += 1 - vector = self._scale_back_clear(vector) - start_x = int(agent_x + vector[0]) - start_y = int(agent_y + vector[1]) + self._old_clear_x = clear_x + self._old_clear_y = clear_y + else: + if clear_blockade is not None: + if self._is_intersecting_blockades(blockade, clear_blockade): + return ActionClear(clear_blockade) - for blockade in self.world_info.get_blockades(road): - if self._is_intersecting_blockade( - start_x, start_y, bp_x, bp_y, blockade - ): - if self._is_intersecting_blockade( - start_x, start_y, clear_x, clear_y, blockade - ): - if action_clear is None: - action_clear = ActionClearArea(clear_x, clear_y) - clear_blockade = blockade - else: - if ( - clear_blockade is not None - and self._is_intersecting_blockades( - blockade, clear_blockade - ) - ): - return ActionClear(clear_blockade) - return action_clear - elif action_move is None: - action_move = ActionMove( - [road.get_entity_id()], int(bp_x), int(bp_y) - ) - - if action_clear is not None: return action_clear - if action_move is not None: - return action_move + elif action_move is None: + action_move = ActionMove([road.get_entity_id()], int(mid_x), int(mid_y)) - action = self._get_area_clear_action( - cast(PoliceForce, self.agent_info.get_myself()), road - ) - if action is None: - action = ActionMove([road.get_entity_id()], int(point_x), int(point_y)) - return action + if action_clear is not None: + return action_clear + if action_move is not None: + return action_move - def _get_move_points(self, road: Road) -> set[tuple[float, float]]: - points: Optional[set[tuple[float, float]]] = self._move_point_cache.get( - road.get_entity_id() - ) - if points is None: - points = set() - apex = road.get_apexes() - for i in range(0, len(apex), 2): - for j in range(i + 2, len(apex), 2): - mid_x = (apex[i] + apex[j]) / 2.0 - mid_y = (apex[i + 1] + apex[j + 1]) / 2.0 - if self._is_inside(mid_x, mid_y, apex): - points.add((mid_x, mid_y)) - - edges = road.get_edges() - if edges is not None: - for edge in edges: - mid_x = (edge.get_start_x() + edge.get_end_x()) / 2.0 - mid_y = (edge.get_start_y() + edge.get_end_y()) / 2.0 - if (mid_x, mid_y) in points: - points.remove((mid_x, mid_y)) - - self._move_point_cache[road.get_entity_id()] = points - - return points - - def _get_vector( - self, from_x: float, from_y: float, to_x: float, to_y: float - ) -> tuple[float, float]: - return (to_x - from_x, to_y - from_y) - - def _scale_clear(self, vector: tuple[float, float]) -> tuple[float, float]: - length = 1.0 / math.hypot(vector[0], vector[1]) - return ( - vector[0] * length * self._clear_distance, - vector[1] * length * self._clear_distance, - ) + if isinstance(target, Road): + road = target + if road.get_blockades() == []: + return ActionMove([position.get_entity_id(), target.get_entity_id()]) - def _scale_back_clear(self, vector: tuple[float, float]) -> tuple[float, float]: - length = 1.0 / math.hypot(vector[0], vector[1]) - return (vector[0] * length * -510, vector[1] * length * -510) - - def _is_intersecting_blockade( - self, - agent_x: float, - agent_y: float, - point_x: float, - point_y: float, - blockade: Blockade, - ) -> bool: + target_blockade: Optional[Blockade] = None + min_point_distance = sys.float_info.max + clear_x = 0 + clear_y = 0 + for blockade in self.world_info.get_blockades(road): apexes = blockade.get_apexes() if apexes is None or len(apexes) < 4: - return False - for i in range(0, len(apexes) - 3, 2): - line1 = LineString( - [(apexes[i], apexes[i + 1]), (apexes[i + 2], apexes[i + 3])] - ) - line2 = LineString([(agent_x, agent_y), (point_x, point_y)]) - if line1.intersects(line2): - return True - return False - - def _is_intersecting_blockades( - self, blockade1: Blockade, blockade2: Blockade - ) -> bool: - apexes1 = blockade1.get_apexes() - apexes2 = blockade2.get_apexes() - if apexes1 is None or apexes2 is None or len(apexes1) < 4 or len(apexes2) < 4: - return False - for i in range(0, len(apexes1) - 2, 2): - for j in range(0, len(apexes2) - 2, 2): - line1 = LineString( - [(apexes1[i], apexes1[i + 1]), (apexes1[i + 2], apexes1[i + 3])] - ) - line2 = LineString( - [(apexes2[j], apexes2[j + 1]), (apexes2[j + 2], apexes2[j + 3])] - ) - if line1.intersects(line2): - return True - - for i in range(0, len(apexes1) - 2, 2): - line1 = LineString( - [(apexes1[i], apexes1[i + 1]), (apexes1[i + 2], apexes1[i + 3])] - ) - line2 = LineString([(apexes2[-2], apexes2[-1]), (apexes2[0], apexes2[1])]) - if line1.intersects(line2): - return True - - for i in range(0, len(apexes2) - 2, 2): - line1 = LineString([(apexes1[-2], apexes1[-1]), (apexes1[0], apexes1[1])]) - line2 = LineString( - [(apexes2[i], apexes2[i + 1]), (apexes2[i + 2], apexes2[i + 3])] - ) - if line1.intersects(line2): - return True - - return False - - def _get_area_clear_action( - self, police_entity: PoliceForce, road: Road - ) -> Optional[Action]: - if road.get_blockades() == []: - return None - - blockades = set(self.world_info.get_blockades(road)) - min_distance = sys.float_info.max - clear_blockade: Optional[Blockade] = None - for blockade in blockades: - for another in blockades: - if blockade == another: - continue - - if self._is_intersecting_blockades(blockade, another): - distance1 = self.world_info.get_distance( - police_entity.get_entity_id(), blockade.get_entity_id() - ) - distance2 = self.world_info.get_distance( - police_entity.get_entity_id(), another.get_entity_id() - ) - if distance1 <= distance2 and distance1 < min_distance: - min_distance = distance1 - clear_blockade = blockade - elif distance2 < min_distance: - min_distance = distance2 - clear_blockade = another - - if clear_blockade is not None: - if min_distance < self._clear_distance: - return ActionClear(clear_blockade) - else: - position = police_entity.get_position() - if position is not None: - return ActionMove( - [position], - clear_blockade.get_x(), - clear_blockade.get_y(), - ) - - agent_x = police_entity.get_x() - agent_y = police_entity.get_y() - if agent_x is None or agent_y is None: - return None - clear_blockade = None - min_point_distance = sys.float_info.max - clear_x = 0 - clear_y = 0 - for blockade in blockades: - apexes = blockade.get_apexes() - if apexes is None or len(apexes) < 4: - continue - for i in range(0, len(apexes) - 2, 2): - distance = self._get_distance( - agent_x, agent_y, apexes[i], apexes[i + 1] - ) - if distance < min_point_distance: - clear_blockade = blockade - min_point_distance = distance - clear_x = apexes[i] - clear_y = apexes[i + 1] - - if clear_blockade is not None: - if min_point_distance < self._clear_distance: - vector = self._scale_clear( - self._get_vector(agent_x, agent_y, clear_x, clear_y) - ) - clear_x = int(agent_x + vector[0]) - clear_y = int(agent_y + vector[1]) - return ActionClearArea(clear_x, clear_y) - position = police_entity.get_position() - if position is not None: - return ActionMove([position], clear_x, clear_y) - - return None - - def _index_of(self, list: list[EntityID], x: EntityID) -> int: - return list.index(x) if x in list else -1 - - def _get_neighbour_position_action( - self, police_entity: PoliceForce, target: Area - ) -> Optional[Action]: - agent_x = police_entity.get_x() - agent_y = police_entity.get_y() - if agent_x is None or agent_y is None: - return None - position_id = police_entity.get_position() - if position_id is None: - return None - position = self.world_info.get_entity(position_id) - if position is None: - return None - - edge = target.get_edge_to(position.get_entity_id()) - if edge is None: - return None - - if isinstance(position, Road): - road = position - if road.get_blockades() != []: - mid_x = (edge.get_start_x() + edge.get_end_x()) / 2.0 - mid_y = (edge.get_start_y() + edge.get_end_y()) / 2.0 - if self._is_intersecting_area(agent_x, agent_y, mid_x, mid_y, road): - return self._get_intersect_edge_action( - agent_x, agent_y, mid_x, mid_y, road - ) - - action_clear: Optional[ActionClear | ActionClearArea] = None - clear_blockade: Optional[Blockade] = None - action_move: Optional[ActionMove] = None - - vector = self._scale_clear( - self._get_vector(agent_x, agent_y, mid_x, mid_y) - ) - clear_x = int(agent_x + vector[0]) - clear_y = int(agent_y + vector[1]) - - vector = self._scale_back_clear(vector) - start_x = int(agent_x + vector[0]) - start_y = int(agent_y + vector[1]) - - for blockade in self.world_info.get_blockades(road): - if self._is_intersecting_blockade( - start_x, start_y, mid_x, mid_y, blockade - ): - if self._is_intersecting_blockade( - start_x, start_y, clear_x, clear_y, blockade - ): - if action_clear is None: - action_clear = ActionClearArea(clear_x, clear_y) - clear_blockade = blockade - if self._equals_point( - self._old_clear_x, - self._old_clear_y, - clear_x, - clear_y, - 1000, - ): - if self.count >= self._forced_move: - self.count = 0 - return ActionMove( - [road.get_entity_id()], - int(clear_x), - int(clear_y), - ) - self.count += 1 - - self._old_clear_x = clear_x - self._old_clear_y = clear_y - else: - if clear_blockade is not None: - if self._is_intersecting_blockades( - blockade, clear_blockade - ): - return ActionClear(clear_blockade) - - return action_clear - elif action_move is None: - action_move = ActionMove( - [road.get_entity_id()], int(mid_x), int(mid_y) - ) - - if action_clear is not None: - return action_clear - if action_move is not None: - return action_move - - if isinstance(target, Road): - road = target - if road.get_blockades() == []: - return ActionMove([position.get_entity_id(), target.get_entity_id()]) - - target_blockade: Optional[Blockade] = None - min_point_distance = sys.float_info.max - clear_x = 0 - clear_y = 0 - for blockade in self.world_info.get_blockades(road): - apexes = blockade.get_apexes() - if apexes is None or len(apexes) < 4: - continue - for i in range(0, len(apexes) - 2, 2): - distance = self._get_distance( - agent_x, agent_y, apexes[i], apexes[i + 1] - ) - if distance < min_point_distance: - target_blockade = blockade - min_point_distance = distance - clear_x = apexes[i] - clear_y = apexes[i + 1] - - if ( - target_blockade is not None - and min_point_distance < self._clear_distance - ): - vector = self._scale_clear( - self._get_vector(agent_x, agent_y, clear_x, clear_y) - ) - clear_x = int(agent_x + vector[0]) - clear_y = int(agent_y + vector[1]) - if self._equals_point( - self._old_clear_x, self._old_clear_y, clear_x, clear_y, 1000 - ): - if self.count >= self._forced_move: - self.count = 0 - return ActionMove([road.get_entity_id()], clear_x, clear_y) - self.count += 1 + continue + for i in range(0, len(apexes) - 2, 2): + distance = self._get_distance(agent_x, agent_y, apexes[i], apexes[i + 1]) + if distance < min_point_distance: + target_blockade = blockade + min_point_distance = distance + clear_x = apexes[i] + clear_y = apexes[i + 1] + + if target_blockade is not None and min_point_distance < self._clear_distance: + vector = self._scale_clear(self._get_vector(agent_x, agent_y, clear_x, clear_y)) + clear_x = int(agent_x + vector[0]) + clear_y = int(agent_y + vector[1]) + if self._equals_point( + self._old_clear_x, self._old_clear_y, clear_x, clear_y, 1000 + ): + if self.count >= self._forced_move: + self.count = 0 + return ActionMove([road.get_entity_id()], clear_x, clear_y) + self.count += 1 - self._old_clear_x = clear_x - self._old_clear_y = clear_y - return ActionClearArea(clear_x, clear_y) + self._old_clear_x = clear_x + self._old_clear_y = clear_y + return ActionClearArea(clear_x, clear_y) - return ActionMove([position.get_entity_id(), target.get_entity_id()]) + return ActionMove([position.get_entity_id(), target.get_entity_id()]) diff --git a/src/adf_core_python/implement/action/default_extend_action_move.py b/src/adf_core_python/implement/action/default_extend_action_move.py index b14baf3..7287535 100644 --- a/src/adf_core_python/implement/action/default_extend_action_move.py +++ b/src/adf_core_python/implement/action/default_extend_action_move.py @@ -15,90 +15,90 @@ class DefaultExtendActionMove(ExtendAction): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - self._target_entity_id: Optional[EntityID] = None - self._threshold_to_rest: int = develop_data.get_value("threshold_to_rest", 100) - - 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) - if self.get_count_precompute() > 1: - return self - self._path_planning.precompute(precompute_data) + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + self._target_entity_id: Optional[EntityID] = None + self._threshold_to_rest: int = develop_data.get_value("threshold_to_rest", 100) + + 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) + if self.get_count_precompute() > 1: + return self + self._path_planning.precompute(precompute_data) + return self + + def resume(self, precompute_data: PrecomputeData) -> ExtendAction: + super().resume(precompute_data) + if self.get_count_resume() > 1: + return self + self._path_planning.resume(precompute_data) + return self + + def prepare(self) -> ExtendAction: + super().prepare() + if self.get_count_prepare() > 1: + return self + self._path_planning.prepare() + return self + + def update_info(self, message_manager: MessageManager) -> ExtendAction: + super().update_info(message_manager) + if self.get_count_update_info() > 1: + return self + self._path_planning.update_info(message_manager) + return self + + def set_target_entity_id(self, target_entity_id: EntityID) -> ExtendAction: + entity: Optional[Entity] = self.world_info.get_entity(target_entity_id) + self._target_entity_id = None + + if entity is None: + return self + + if isinstance(entity, Blockade) or isinstance(entity, Human): + position: Optional[EntityID] = entity.get_position() + if position is None: return self + entity = self.world_info.get_entity(position) - def resume(self, precompute_data: PrecomputeData) -> ExtendAction: - super().resume(precompute_data) - if self.get_count_resume() > 1: - return self - self._path_planning.resume(precompute_data) - return self - - def prepare(self) -> ExtendAction: - super().prepare() - if self.get_count_prepare() > 1: - return self - self._path_planning.prepare() - return self + if entity is not None and isinstance(entity, Area): + self._target_entity_id = entity.get_entity_id() - def update_info(self, message_manager: MessageManager) -> ExtendAction: - super().update_info(message_manager) - if self.get_count_update_info() > 1: - return self - self._path_planning.update_info(message_manager) - return self - - def set_target_entity_id(self, target_entity_id: EntityID) -> ExtendAction: - entity: Optional[Entity] = self.world_info.get_entity(target_entity_id) - self._target_entity_id = None + return self - if entity is None: - return self + def calculate(self) -> ExtendAction: + self.result = None + agent: Human = cast(Human, self.agent_info.get_myself()) - if isinstance(entity, Blockade) or isinstance(entity, Human): - position: Optional[EntityID] = entity.get_position() - if position is None: - return self - entity = self.world_info.get_entity(position) + if self._target_entity_id is None: + return self - if entity is not None and isinstance(entity, Area): - self._target_entity_id = entity.get_entity_id() + agent_position = agent.get_position() + if agent_position is None: + return self - return self + path: list[EntityID] = self._path_planning.get_path( + agent_position, self._target_entity_id + ) - def calculate(self) -> ExtendAction: - self.result = None - agent: Human = cast(Human, self.agent_info.get_myself()) + if path is not None and len(path) != 0: + self.result = ActionMove(path) - if self._target_entity_id is None: - return self - - agent_position = agent.get_position() - if agent_position is None: - return self - - path: list[EntityID] = self._path_planning.get_path( - agent_position, self._target_entity_id - ) - - if path is not None and len(path) != 0: - self.result = ActionMove(path) - - return self + return self diff --git a/src/adf_core_python/implement/action/default_extend_action_rescue.py b/src/adf_core_python/implement/action/default_extend_action_rescue.py index b4624bb..489f5d5 100644 --- a/src/adf_core_python/implement/action/default_extend_action_rescue.py +++ b/src/adf_core_python/implement/action/default_extend_action_rescue.py @@ -9,8 +9,8 @@ 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 ( - ScenarioInfo, - ScenarioInfoKeys, + ScenarioInfo, + ScenarioInfoKeys, ) from adf_core_python.core.agent.info.world_info import WorldInfo from adf_core_python.core.agent.module.module_manager import ModuleManager @@ -20,136 +20,136 @@ class DefaultExtendActionRescue(ExtendAction): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - self._kernel_time: int = -1 - self._target_entity_id: Optional[EntityID] = None - self._threshold_rest = develop_data.get_value( - "adf_core_python.implement.action.DefaultExtendActionRescue.rest", 100 - ) - - 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) - if self.get_count_precompute() >= 2: - return self - self._path_planning.precompute(precompute_data) - self._kernel_time = self.scenario_info.get_value( - ScenarioInfoKeys.KERNEL_TIMESTEPS, -1 - ) + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + self._kernel_time: int = -1 + self._target_entity_id: Optional[EntityID] = None + self._threshold_rest = develop_data.get_value( + "adf_core_python.implement.action.DefaultExtendActionRescue.rest", 100 + ) + + 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) + if self.get_count_precompute() >= 2: + return self + self._path_planning.precompute(precompute_data) + self._kernel_time = self.scenario_info.get_value( + ScenarioInfoKeys.KERNEL_TIMESTEPS, -1 + ) + return self + + def resume(self, precompute_data: PrecomputeData) -> ExtendAction: + super().resume(precompute_data) + if self.get_count_resume() >= 2: + return self + self._path_planning.resume(precompute_data) + self._kernel_time = self.scenario_info.get_value( + ScenarioInfoKeys.KERNEL_TIMESTEPS, -1 + ) + return self + + def prepare(self) -> ExtendAction: + super().prepare() + if self.get_count_prepare() >= 2: + return self + self._path_planning.prepare() + self._kernel_time = self.scenario_info.get_value( + ScenarioInfoKeys.KERNEL_TIMESTEPS, -1 + ) + return self + + def update_info(self, message_manager: MessageManager) -> ExtendAction: + super().update_info(message_manager) + if self.get_count_update_info() >= 2: + return self + self._path_planning.update_info(message_manager) + return self + + def set_target_entity_id(self, target_entity_id: EntityID) -> ExtendAction: + self._target_entity_id = None + if target_entity_id is not None: + entity = self.world_info.get_entity(target_entity_id) + if isinstance(entity, Human) or isinstance(entity, Area): + self._target_entity_id = target_entity_id return self + return self + + def calculate(self) -> ExtendAction: + self.result = None + agent = cast(FireBrigade, self.agent_info.get_myself()) + + if self._target_entity_id is not None: + self.result = self._calc_rescue( + agent, self._path_planning, self._target_entity_id + ) + + return self + + def _calc_rescue( + self, + agent: FireBrigade, + path_planning: PathPlanning, + target_entity_id: EntityID, + ) -> Optional[Action]: + target_entity = self.world_info.get_entity(target_entity_id) + if target_entity is None: + return None + + agent_position_entity_id = agent.get_position() + if agent_position_entity_id is None: + return None + + if isinstance(target_entity, Human): + human = target_entity + if human.get_hp() == 0: + return None - def resume(self, precompute_data: PrecomputeData) -> ExtendAction: - super().resume(precompute_data) - if self.get_count_resume() >= 2: - return self - self._path_planning.resume(precompute_data) - self._kernel_time = self.scenario_info.get_value( - ScenarioInfoKeys.KERNEL_TIMESTEPS, -1 - ) - return self + target_position_entity_id = human.get_position() + if target_position_entity_id is None: + return None - def prepare(self) -> ExtendAction: - super().prepare() - if self.get_count_prepare() >= 2: - return self - self._path_planning.prepare() - self._kernel_time = self.scenario_info.get_value( - ScenarioInfoKeys.KERNEL_TIMESTEPS, -1 + if agent_position_entity_id == target_position_entity_id: + buriedness = human.get_buriedness() + if buriedness is not None and buriedness > 0: + return ActionRescue(target_entity_id) + else: + path = path_planning.get_path( + agent_position_entity_id, target_position_entity_id ) - return self - - def update_info(self, message_manager: MessageManager) -> ExtendAction: - super().update_info(message_manager) - if self.get_count_update_info() >= 2: - return self - self._path_planning.update_info(message_manager) - return self - - def set_target_entity_id(self, target_entity_id: EntityID) -> ExtendAction: - self._target_entity_id = None - if target_entity_id is not None: - entity = self.world_info.get_entity(target_entity_id) - if isinstance(entity, Human) or isinstance(entity, Area): - self._target_entity_id = target_entity_id - return self - return self + if path != []: + return ActionMove(path) - def calculate(self) -> ExtendAction: - self.result = None - agent = cast(FireBrigade, self.agent_info.get_myself()) + return None - if self._target_entity_id is not None: - self.result = self._calc_rescue( - agent, self._path_planning, self._target_entity_id - ) - - return self + if isinstance(target_entity, Blockade): + blockade = target_entity + blockade_position = blockade.get_position() + if blockade_position is None: + return None - def _calc_rescue( - self, - agent: FireBrigade, - path_planning: PathPlanning, - target_entity_id: EntityID, - ) -> Optional[Action]: - target_entity = self.world_info.get_entity(target_entity_id) - if target_entity is None: - return None - - agent_position_entity_id = agent.get_position() - if agent_position_entity_id is None: - return None - - if isinstance(target_entity, Human): - human = target_entity - if human.get_hp() == 0: - return None - - target_position_entity_id = human.get_position() - if target_position_entity_id is None: - return None - - if agent_position_entity_id == target_position_entity_id: - buriedness = human.get_buriedness() - if buriedness is not None and buriedness > 0: - return ActionRescue(target_entity_id) - else: - path = path_planning.get_path( - agent_position_entity_id, target_position_entity_id - ) - if path != []: - return ActionMove(path) - - return None - - if isinstance(target_entity, Blockade): - blockade = target_entity - blockade_position = blockade.get_position() - if blockade_position is None: - return None - - target_entity = self.world_info.get_entity(blockade_position) - if isinstance(target_entity, Area): - path = self._path_planning.get_path( - agent_position_entity_id, target_entity.get_entity_id() - ) - if path != []: - return ActionMove(path) + target_entity = self.world_info.get_entity(blockade_position) + if isinstance(target_entity, Area): + path = self._path_planning.get_path( + agent_position_entity_id, target_entity.get_entity_id() + ) + if path != []: + return ActionMove(path) - return None + return None diff --git a/src/adf_core_python/implement/action/default_extend_action_transport.py b/src/adf_core_python/implement/action/default_extend_action_transport.py index 5fe0b9d..b647668 100644 --- a/src/adf_core_python/implement/action/default_extend_action_transport.py +++ b/src/adf_core_python/implement/action/default_extend_action_transport.py @@ -1,13 +1,13 @@ from typing import Optional, Union, cast from rcrscore.entities import ( - AmbulanceTeam, - Area, - Civilian, - Entity, - EntityID, - Human, - Refuge, + AmbulanceTeam, + Area, + Civilian, + Entity, + EntityID, + Human, + Refuge, ) from adf_core_python.core.agent.action.ambulance.action_load import ActionLoad @@ -27,234 +27,228 @@ class DefaultExtendActionTransport(ExtendAction): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - self._target_entity_id: Optional[EntityID] = None - self._threshold_to_rest: int = develop_data.get_value("threshold_to_rest", 100) - self._logger = get_agent_logger( - f"{self.__class__.__module__}.{self.__class__.__qualname__}", - self.agent_info, - ) - - 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) - if self.get_count_precompute() > 1: - return self - self._path_planning.precompute(precompute_data) + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + self._target_entity_id: Optional[EntityID] = None + self._threshold_to_rest: int = develop_data.get_value("threshold_to_rest", 100) + self._logger = get_agent_logger( + f"{self.__class__.__module__}.{self.__class__.__qualname__}", + self.agent_info, + ) + + 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) + if self.get_count_precompute() > 1: + return self + self._path_planning.precompute(precompute_data) + return self + + def resume(self, precompute_data: PrecomputeData) -> ExtendAction: + super().resume(precompute_data) + if self.get_count_resume() > 1: + return self + self._path_planning.resume(precompute_data) + return self + + def prepare(self) -> ExtendAction: + super().prepare() + if self.get_count_prepare() > 1: + return self + self._path_planning.prepare() + return self + + def update_info(self, message_manager: MessageManager) -> ExtendAction: + super().update_info(message_manager) + if self.get_count_update_info() > 1: + return self + self._path_planning.update_info(message_manager) + return self + + def set_target_entity_id(self, target_entity_id: EntityID) -> ExtendAction: + entity: Optional[Entity] = self.world_info.get_world_model().get_entity( + target_entity_id + ) + self._target_entity_id = None + + if entity is None: + return self + + if isinstance(entity, Human) or isinstance(entity, Area): + self._target_entity_id = target_entity_id + + return self + + def calculate(self) -> ExtendAction: + self._result = None + agent: AmbulanceTeam = cast(AmbulanceTeam, self.agent_info.get_myself()) + transport_human: Optional[Human] = self.agent_info.some_one_on_board() + if transport_human is not None: + self._logger.debug(f"transport_human: {transport_human.get_entity_id()}") + self.result = self.calc_unload( + agent, self._path_planning, transport_human, self._target_entity_id + ) + if self.result is not None: return self - def resume(self, precompute_data: PrecomputeData) -> ExtendAction: - super().resume(precompute_data) - if self.get_count_resume() > 1: - return self - self._path_planning.resume(precompute_data) - return self - - def prepare(self) -> ExtendAction: - super().prepare() - if self.get_count_prepare() > 1: - return self - self._path_planning.prepare() - return self - - def update_info(self, message_manager: MessageManager) -> ExtendAction: - super().update_info(message_manager) - if self.get_count_update_info() > 1: - return self - self._path_planning.update_info(message_manager) - return self - - def set_target_entity_id(self, target_entity_id: EntityID) -> ExtendAction: - entity: Optional[Entity] = self.world_info.get_world_model().get_entity( - target_entity_id - ) - self._target_entity_id = None - - if entity is None: - return self - - if isinstance(entity, Human) or isinstance(entity, Area): - self._target_entity_id = target_entity_id - - return self - - def calculate(self) -> ExtendAction: - self._result = None - agent: AmbulanceTeam = cast(AmbulanceTeam, self.agent_info.get_myself()) - transport_human: Optional[Human] = self.agent_info.some_one_on_board() - if transport_human is not None: - self._logger.debug(f"transport_human: {transport_human.get_entity_id()}") - self.result = self.calc_unload( - agent, self._path_planning, transport_human, self._target_entity_id - ) - if self.result is not None: - return self - - if self._target_entity_id is not None: - self.result = self.calc_rescue( - agent, self._path_planning, self._target_entity_id - ) - - return self - - def calc_rescue( - self, - agent: AmbulanceTeam, - path_planning: PathPlanning, - target_id: EntityID, - ) -> Optional[Union[ActionMove, ActionLoad]]: - target_entity = self.world_info.get_entity(target_id) - if target_entity is None: - return None - - agent_position = agent.get_position() - if agent_position is None: - return None - if isinstance(target_entity, Human): - human = target_entity - if human.get_position() is None: - return None - if human.get_hp() is None or human.get_hp() == 0: - return None - - target_position = human.get_position() - if target_position is None: - return None - if agent_position == target_position: - if isinstance(human, Civilian) and ((human.get_buriedness() or 0) == 0): - return ActionLoad(human.get_entity_id()) - else: - path = path_planning.get_path(agent_position, target_position) - if path is not None and len(path) > 0: - return ActionMove(path) - return None - - if isinstance(target_entity, Area): - if agent_position is None: - return None - path = path_planning.get_path(agent_position, target_entity.get_entity_id()) - if path is not None and len(path) > 0: - return ActionMove(path) - + if self._target_entity_id is not None: + self.result = self.calc_rescue(agent, self._path_planning, self._target_entity_id) + + return self + + def calc_rescue( + self, + agent: AmbulanceTeam, + path_planning: PathPlanning, + target_id: EntityID, + ) -> Optional[Union[ActionMove, ActionLoad]]: + target_entity = self.world_info.get_entity(target_id) + if target_entity is None: + return None + + agent_position = agent.get_position() + if agent_position is None: + return None + if isinstance(target_entity, Human): + human = target_entity + if human.get_position() is None: + return None + if human.get_hp() is None or human.get_hp() == 0: return None - def calc_unload( - self, - agent: AmbulanceTeam, - path_planning: PathPlanning, - transport_human: Optional[Human], - target_id: Optional[EntityID], - ) -> Optional[ActionMove | ActionUnload | ActionRest]: - if transport_human is None: - return None - - if not transport_human.get_hp() or transport_human.get_hp() == 0: - return ActionUnload() - - agent_position = agent.get_position() - if agent_position is None: - return None - if target_id is None or transport_human.get_entity_id() == target_id: - position = self.world_info.get_entity(agent_position) - if position is None: - return None - - if isinstance(position, Refuge): - return ActionUnload() - else: - path = self.get_nearest_refuge_path(agent, path_planning) - if path is not None and len(path) > 0: - return ActionMove(path) - - if target_id is None: - return None - - target_entity = self.world_info.get_entity(target_id) - - if isinstance(target_entity, Human): - human = target_entity - human_position = human.get_position() - if human_position is not None: - return self.calc_refuge_action( - agent, path_planning, human_position, True - ) - path = self.get_nearest_refuge_path(agent, path_planning) - if path is not None and len(path) > 0: - return ActionMove(path) - + target_position = human.get_position() + if target_position is None: + return None + if agent_position == target_position: + if isinstance(human, Civilian) and ((human.get_buriedness() or 0) == 0): + return ActionLoad(human.get_entity_id()) + else: + path = path_planning.get_path(agent_position, target_position) + if path is not None and len(path) > 0: + return ActionMove(path) + return None + + if isinstance(target_entity, Area): + if agent_position is None: + return None + path = path_planning.get_path(agent_position, target_entity.get_entity_id()) + if path is not None and len(path) > 0: + return ActionMove(path) + + return None + + def calc_unload( + self, + agent: AmbulanceTeam, + path_planning: PathPlanning, + transport_human: Optional[Human], + target_id: Optional[EntityID], + ) -> Optional[ActionMove | ActionUnload | ActionRest]: + if transport_human is None: + return None + + if not transport_human.get_hp() or transport_human.get_hp() == 0: + return ActionUnload() + + agent_position = agent.get_position() + if agent_position is None: + return None + if target_id is None or transport_human.get_entity_id() == target_id: + position = self.world_info.get_entity(agent_position) + if position is None: return None - def calc_refuge_action( - self, - human: Human, - path_planning: PathPlanning, - target_entity_id: EntityID, - is_unload: bool, - ) -> Optional[ActionMove | ActionUnload | ActionRest]: - position = human.get_position() - if position is None: - return None - refuges = self.world_info.get_entity_ids_of_types([Refuge]) + if isinstance(position, Refuge): + return ActionUnload() + else: + path = self.get_nearest_refuge_path(agent, path_planning) + if path is not None and len(path) > 0: + return ActionMove(path) + + if target_id is None: + return None + + target_entity = self.world_info.get_entity(target_id) + + if isinstance(target_entity, Human): + human = target_entity + human_position = human.get_position() + if human_position is not None: + return self.calc_refuge_action(agent, path_planning, human_position, True) + path = self.get_nearest_refuge_path(agent, path_planning) + if path is not None and len(path) > 0: + return ActionMove(path) + + return None + + def calc_refuge_action( + self, + human: Human, + path_planning: PathPlanning, + target_entity_id: EntityID, + is_unload: bool, + ) -> Optional[ActionMove | ActionUnload | ActionRest]: + position = human.get_position() + if position is None: + return None + refuges = self.world_info.get_entity_ids_of_types([Refuge]) + size = len(refuges) + + if position in refuges: + return ActionUnload() if is_unload else ActionRest() + + first_result = None + while len(refuges) > 0: + path = path_planning.get_path(position, refuges[0]) + + if path is not None and len(path) > 0: + if first_result is None: + first_result = path.copy() + + refuge_id = path[-1] + from_refuge_to_target = path_planning.get_path(refuge_id, target_entity_id) + + if from_refuge_to_target is not None and len(from_refuge_to_target) > 0: + return ActionMove(path) + + refuges.remove(refuge_id) + if size == len(refuges): + break size = len(refuges) - - if position in refuges: - return ActionUnload() if is_unload else ActionRest() - - first_result = None - while len(refuges) > 0: - path = path_planning.get_path(position, refuges[0]) - - if path is not None and len(path) > 0: - if first_result is None: - first_result = path.copy() - - refuge_id = path[-1] - from_refuge_to_target = path_planning.get_path( - refuge_id, target_entity_id - ) - - if from_refuge_to_target is not None and len(from_refuge_to_target) > 0: - return ActionMove(path) - - refuges.remove(refuge_id) - if size == len(refuges): - break - size = len(refuges) - else: - break - - return ActionMove(first_result) if first_result is not None else None - - def get_nearest_refuge_path( - self, human: Human, path_planning: PathPlanning - ) -> list[EntityID]: - position = human.get_position() - if position is None: - return [] - refuges = self.world_info.get_entity_ids_of_types([Refuge]) - nearest_path = None - - for refuge_id in refuges: - path: list[EntityID] = path_planning.get_path(position, refuge_id) - if len(path) > 0: - if nearest_path is None or len(path) < len(nearest_path): - nearest_path = path - - return nearest_path if nearest_path is not None else [] + else: + break + + return ActionMove(first_result) if first_result is not None else None + + def get_nearest_refuge_path( + self, human: Human, path_planning: PathPlanning + ) -> list[EntityID]: + position = human.get_position() + if position is None: + return [] + refuges = self.world_info.get_entity_ids_of_types([Refuge]) + nearest_path = None + + for refuge_id in refuges: + path: list[EntityID] = path_planning.get_path(position, refuge_id) + if len(path) > 0: + if nearest_path is None or len(path) < len(nearest_path): + nearest_path = path + + return nearest_path if nearest_path is not None else [] diff --git a/src/adf_core_python/implement/centralized/default_command_executor_ambulance.py b/src/adf_core_python/implement/centralized/default_command_executor_ambulance.py index d4783c6..ffd0a7d 100644 --- a/src/adf_core_python/implement/centralized/default_command_executor_ambulance.py +++ b/src/adf_core_python/implement/centralized/default_command_executor_ambulance.py @@ -6,13 +6,13 @@ from adf_core_python.core.agent.action.common.action_rest import ActionRest from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.communication.standard.bundle.centralized.command_ambulance import ( - CommandAmbulance, + CommandAmbulance, ) from adf_core_python.core.agent.communication.standard.bundle.centralized.message_report import ( - MessageReport, + MessageReport, ) from adf_core_python.core.agent.communication.standard.bundle.standard_message_priority import ( - StandardMessagePriority, + StandardMessagePriority, ) from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo @@ -25,272 +25,268 @@ class DefaultCommandExecutorAmbulance(CommandExecutor): - ACTION_UNKNOWN: int = -1 - ACTION_REST = CommandAmbulance.ACTION_REST - ACTION_MOVE = CommandAmbulance.ACTION_MOVE - ACTION_RESCUE = CommandAmbulance.ACTION_RESCUE - ACTION_LOAD = CommandAmbulance.ACTION_LOAD - ACTION_UNLOAD = CommandAmbulance.ACTION_UNLOAD - ACTION_AUTONOMY = CommandAmbulance.ACTION_AUTONOMY + ACTION_UNKNOWN: int = -1 + ACTION_REST = CommandAmbulance.ACTION_REST + ACTION_MOVE = CommandAmbulance.ACTION_MOVE + ACTION_RESCUE = CommandAmbulance.ACTION_RESCUE + ACTION_LOAD = CommandAmbulance.ACTION_LOAD + ACTION_UNLOAD = CommandAmbulance.ACTION_UNLOAD + ACTION_AUTONOMY = CommandAmbulance.ACTION_AUTONOMY - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) - self._path_planning: PathPlanning = cast( - PathPlanning, - module_manager.get_module( - "DefaultCommandExecutorAmbulance.PathPlanning", - "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", - ), - ) - self._action_transport = module_manager.get_extend_action( - "DefaultCommandExecutorAmbulance.ExtendActionTransport", - "adf_core_python.implement.action.default_extend_action_transport.DefaultExtendActionTransport", - ) - self._action_move = module_manager.get_extend_action( - "DefaultCommandExecutorAmbulance.ExtendActionMove", - "adf_core_python.implement.action.default_extend_action_move.DefaultExtendActionMove", - ) + self._path_planning: PathPlanning = cast( + PathPlanning, + module_manager.get_module( + "DefaultCommandExecutorAmbulance.PathPlanning", + "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", + ), + ) + self._action_transport = module_manager.get_extend_action( + "DefaultCommandExecutorAmbulance.ExtendActionTransport", + "adf_core_python.implement.action.default_extend_action_transport.DefaultExtendActionTransport", + ) + self._action_move = module_manager.get_extend_action( + "DefaultCommandExecutorAmbulance.ExtendActionMove", + "adf_core_python.implement.action.default_extend_action_move.DefaultExtendActionMove", + ) - self._command_type: int = self.ACTION_UNKNOWN - self._target: Optional[EntityID] = None - self._commander: Optional[EntityID] = None + self._command_type: int = self.ACTION_UNKNOWN + self._target: Optional[EntityID] = None + self._commander: Optional[EntityID] = None - def set_command(self, command: CommandAmbulance) -> CommandExecutor: - agent_id: EntityID = self._agent_info.get_entity_id() - if command.get_command_executor_agent_entity_id() != agent_id: - return self + def set_command(self, command: CommandAmbulance) -> CommandExecutor: + agent_id: EntityID = self._agent_info.get_entity_id() + if command.get_command_executor_agent_entity_id() != agent_id: + return self - self._command_type = command.get_execute_action() or self.ACTION_UNKNOWN - self._target = command.get_command_target_entity_id() - self._commander = command.get_sender_entity_id() - return self + self._command_type = command.get_execute_action() or self.ACTION_UNKNOWN + self._target = command.get_command_target_entity_id() + self._commander = command.get_sender_entity_id() + return self - def calculate(self) -> CommandExecutor: - self._result = None - match self._command_type: - case self.ACTION_REST: - position = self._agent_info.get_entity_id() - if self._target is None: - refuges = self._world_info.get_entity_ids_of_types([Refuge]) - if position in refuges: - self._result = ActionRest() - else: - path = self._path_planning.get_path(position, refuges[0]) - if path: - self._result = ActionMove(path) - else: - self._result = ActionRest() - return self - if position != self._target: - path = self._path_planning.get_path(position, self._target) - if path: - self._result = ActionMove(path) - return self - self._result = ActionRest() - return self - case self.ACTION_MOVE: - if self._target: - self._result = ( - self._action_move.set_target_entity_id(self._target) - .calculate() - .get_action() - ) - return self - case self.ACTION_RESCUE: - if self._target: - self._result = ( - self._action_move.set_target_entity_id(self._target) - .calculate() - .get_action() - ) - return self - case self.ACTION_LOAD: - if self._target: - self._result = ( - self._action_move.set_target_entity_id(self._target) - .calculate() - .get_action() - ) - return self - case self.ACTION_UNLOAD: - if self._target: - self._result = ( - self._action_move.set_target_entity_id(self._target) - .calculate() - .get_action() - ) - return self - case self.ACTION_AUTONOMY: - if self._target is None: - return self - target_entity = self._world_info.get_entity(self._target) - if isinstance(target_entity, Area): - if self._agent_info.some_one_on_board() is None: - self._result = ( - self._action_move.set_target_entity_id(self._target) - .calculate() - .get_action() - ) - else: - self._result = ( - self._action_transport.set_target_entity_id(self._target) - .calculate() - .get_action() - ) - elif isinstance(target_entity, Human): - self._result = ( - self._action_transport.set_target_entity_id(self._target) - .calculate() - .get_action() - ) + def calculate(self) -> CommandExecutor: + self._result = None + match self._command_type: + case self.ACTION_REST: + position = self._agent_info.get_entity_id() + if self._target is None: + refuges = self._world_info.get_entity_ids_of_types([Refuge]) + if position in refuges: + self._result = ActionRest() + else: + path = self._path_planning.get_path(position, refuges[0]) + if path: + self._result = ActionMove(path) + else: + self._result = ActionRest() + return self + if position != self._target: + path = self._path_planning.get_path(position, self._target) + if path: + self._result = ActionMove(path) + return self + self._result = ActionRest() return self + case self.ACTION_MOVE: + if self._target: + self._result = ( + self._action_move.set_target_entity_id(self._target) + .calculate() + .get_action() + ) + return self + case self.ACTION_RESCUE: + if self._target: + self._result = ( + self._action_move.set_target_entity_id(self._target) + .calculate() + .get_action() + ) + return self + case self.ACTION_LOAD: + if self._target: + self._result = ( + self._action_move.set_target_entity_id(self._target) + .calculate() + .get_action() + ) + return self + case self.ACTION_UNLOAD: + if self._target: + self._result = ( + self._action_move.set_target_entity_id(self._target) + .calculate() + .get_action() + ) + return self + case self.ACTION_AUTONOMY: + if self._target is None: + return self + target_entity = self._world_info.get_entity(self._target) + if isinstance(target_entity, Area): + if self._agent_info.some_one_on_board() is None: + self._result = ( + self._action_move.set_target_entity_id(self._target) + .calculate() + .get_action() + ) + else: + self._result = ( + self._action_transport.set_target_entity_id(self._target) + .calculate() + .get_action() + ) + elif isinstance(target_entity, Human): + self._result = ( + self._action_transport.set_target_entity_id(self._target) + .calculate() + .get_action() + ) + return self - def update_info(self, message_manager: MessageManager) -> CommandExecutor: - super().update_info(message_manager) - if self.get_count_update_info() >= 2: - return self + def update_info(self, message_manager: MessageManager) -> CommandExecutor: + super().update_info(message_manager) + if self.get_count_update_info() >= 2: + return self - self._path_planning.update_info(message_manager) - self._action_transport.update_info(message_manager) - self._action_move.update_info(message_manager) + self._path_planning.update_info(message_manager) + self._action_transport.update_info(message_manager) + self._action_move.update_info(message_manager) - if self._is_command_completed(): - if self._command_type == self.ACTION_UNKNOWN: - return self - if self._commander is None: - return self + if self._is_command_completed(): + if self._command_type == self.ACTION_UNKNOWN: + return self + if self._commander is None: + return self - message_manager.add_message( - MessageReport( - True, - True, - False, - self._commander, - StandardMessagePriority.NORMAL, - ) - ) + message_manager.add_message( + MessageReport( + True, + True, + False, + self._commander, + StandardMessagePriority.NORMAL, + ) + ) - if self._command_type == self.ACTION_LOAD: - self._command_type = self.ACTION_UNLOAD - self._target = None - else: - self._command_type = self.ACTION_UNKNOWN - self._target = None - self._commander = None + if self._command_type == self.ACTION_LOAD: + self._command_type = self.ACTION_UNLOAD + self._target = None + else: + self._command_type = self.ACTION_UNKNOWN + self._target = None + self._commander = None - return self + return self - def precompute(self, precompute_data: PrecomputeData) -> CommandExecutor: - super().precompute(precompute_data) - if self.get_count_precompute() >= 2: - return self - self._path_planning.precompute(precompute_data) - self._action_transport.precompute(precompute_data) - self._action_move.precompute(precompute_data) - return self + def precompute(self, precompute_data: PrecomputeData) -> CommandExecutor: + super().precompute(precompute_data) + if self.get_count_precompute() >= 2: + return self + self._path_planning.precompute(precompute_data) + self._action_transport.precompute(precompute_data) + self._action_move.precompute(precompute_data) + return self - def resume(self, precompute_data: PrecomputeData) -> CommandExecutor: - super().resume(precompute_data) - if self.get_count_resume() >= 2: - return self - self._path_planning.resume(precompute_data) - self._action_transport.resume(precompute_data) - self._action_move.resume(precompute_data) - return self + def resume(self, precompute_data: PrecomputeData) -> CommandExecutor: + super().resume(precompute_data) + if self.get_count_resume() >= 2: + return self + self._path_planning.resume(precompute_data) + self._action_transport.resume(precompute_data) + self._action_move.resume(precompute_data) + return self - def prepare(self) -> CommandExecutor: - super().prepare() - if self.get_count_prepare() >= 2: - return self - self._path_planning.prepare() - self._action_transport.prepare() - self._action_move.prepare() - return self + def prepare(self) -> CommandExecutor: + super().prepare() + if self.get_count_prepare() >= 2: + return self + self._path_planning.prepare() + self._action_transport.prepare() + self._action_move.prepare() + return self - def _is_command_completed(self) -> bool: - agent = self._agent_info.get_myself() - if not isinstance(agent, Human): - return False + def _is_command_completed(self) -> bool: + agent = self._agent_info.get_myself() + if not isinstance(agent, Human): + return False - match self._command_type: - case self.ACTION_REST: - if self._target is None: - return agent.get_damage() == 0 - if (target_entity := self._world_info.get_entity(self._target)) is None: - return False - if isinstance(target_entity, Refuge): - return agent.get_damage() == 0 - return False - case self.ACTION_MOVE: - return ( - self._target is None - or self._agent_info.get_position_entity_id() == self._target - ) - case self.ACTION_RESCUE: - if self._target is None: - return True - human = self._world_info.get_entity(self._target) - if not isinstance(human, Human): - return True - return human.get_buriedness() == 0 or human.get_hp() == 0 - case self.ACTION_LOAD: - if self._target is None: - return True - human = self._world_info.get_entity(self._target) - if not isinstance(human, Human): - return True - if human.get_hp() == 0: - return True - if isinstance(human, Civilian): - self._command_type = self.ACTION_RESCUE - return self._is_command_completed() - position = human.get_position() - if position is not None: - if position in self._world_info.get_entity_ids_of_types( - [AmbulanceTeam] - ): - return True - elif isinstance(self._world_info.get_entity(position), Refuge): - return True - return False + match self._command_type: + case self.ACTION_REST: + if self._target is None: + return agent.get_damage() == 0 + if (target_entity := self._world_info.get_entity(self._target)) is None: + return False + if isinstance(target_entity, Refuge): + return agent.get_damage() == 0 + return False + case self.ACTION_MOVE: + return ( + self._target is None + or self._agent_info.get_position_entity_id() == self._target + ) + case self.ACTION_RESCUE: + if self._target is None: + return True + human = self._world_info.get_entity(self._target) + if not isinstance(human, Human): + return True + return human.get_buriedness() == 0 or human.get_hp() == 0 + case self.ACTION_LOAD: + if self._target is None: + return True + human = self._world_info.get_entity(self._target) + if not isinstance(human, Human): + return True + if human.get_hp() == 0: + return True + if isinstance(human, Civilian): + self._command_type = self.ACTION_RESCUE + return self._is_command_completed() + position = human.get_position() + if position is not None: + if position in self._world_info.get_entity_ids_of_types([AmbulanceTeam]): + return True + elif isinstance(self._world_info.get_entity(position), Refuge): + return True + return False - case self.ACTION_UNLOAD: - if self._target is not None: - entity = self._world_info.get_entity(self._target) - if entity is not None and isinstance(entity, Refuge): - if self._target == self._agent_info.get_position_entity_id(): - return False - return self._agent_info.some_one_on_board() is None - case self.ACTION_AUTONOMY: - if self._target is not None: - target_entity = self._world_info.get_entity(self._target) - if isinstance(target_entity, Area): - self._command_type = ( - self._agent_info.some_one_on_board() is None - and self.ACTION_MOVE - or self.ACTION_UNLOAD - ) - return self._is_command_completed() - elif isinstance(target_entity, Human): - human = target_entity - if human.get_hp() == 0: - return True - self._command_type = ( - isinstance(human, Civilian) - and self.ACTION_LOAD - or self.ACTION_RESCUE - ) - return self._is_command_completed() - return True - case _: - return True + case self.ACTION_UNLOAD: + if self._target is not None: + entity = self._world_info.get_entity(self._target) + if entity is not None and isinstance(entity, Refuge): + if self._target == self._agent_info.get_position_entity_id(): + return False + return self._agent_info.some_one_on_board() is None + case self.ACTION_AUTONOMY: + if self._target is not None: + target_entity = self._world_info.get_entity(self._target) + if isinstance(target_entity, Area): + self._command_type = ( + self._agent_info.some_one_on_board() is None + and self.ACTION_MOVE + or self.ACTION_UNLOAD + ) + return self._is_command_completed() + elif isinstance(target_entity, Human): + human = target_entity + if human.get_hp() == 0: + return True + self._command_type = ( + isinstance(human, Civilian) and self.ACTION_LOAD or self.ACTION_RESCUE + ) + return self._is_command_completed() + return True + case _: + return True diff --git a/src/adf_core_python/implement/centralized/default_command_executor_fire.py b/src/adf_core_python/implement/centralized/default_command_executor_fire.py index 7def460..9b0451a 100644 --- a/src/adf_core_python/implement/centralized/default_command_executor_fire.py +++ b/src/adf_core_python/implement/centralized/default_command_executor_fire.py @@ -6,13 +6,13 @@ from adf_core_python.core.agent.action.common.action_rest import ActionRest from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.communication.standard.bundle.centralized.command_ambulance import ( - CommandAmbulance, + CommandAmbulance, ) from adf_core_python.core.agent.communication.standard.bundle.centralized.message_report import ( - MessageReport, + MessageReport, ) from adf_core_python.core.agent.communication.standard.bundle.standard_message_priority import ( - StandardMessagePriority, + StandardMessagePriority, ) from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo @@ -25,214 +25,214 @@ class DefaultCommandExecutorFire(CommandExecutor): - ACTION_UNKNOWN: int = -1 - ACTION_REST = CommandAmbulance.ACTION_REST - ACTION_MOVE = CommandAmbulance.ACTION_MOVE - ACTION_RESCUE = CommandAmbulance.ACTION_RESCUE - ACTION_AUTONOMY = CommandAmbulance.ACTION_AUTONOMY - - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - - self._path_planning: PathPlanning = cast( - PathPlanning, - module_manager.get_module( - "DefaultCommandExecutorFire.PathPlanning", - "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", - ), - ) - self._action_fire_rescue = module_manager.get_extend_action( - "DefaultCommandExecutorFire.ExtendActionFireRescue", - "adf_core_python.implement.action.default_extend_action_rescue.DefaultExtendActionRescue", - ) - self._action_move = module_manager.get_extend_action( - "DefaultCommandExecutorFire.ExtendActionMove", - "adf_core_python.implement.action.default_extend_action_move.DefaultExtendActionMove", - ) - - self._command_type: int = self.ACTION_UNKNOWN - self._target: Optional[EntityID] = None - self._commander: Optional[EntityID] = None - - def set_command(self, command: CommandAmbulance) -> CommandExecutor: - agent_id: EntityID = self._agent_info.get_entity_id() - if command.get_command_executor_agent_entity_id() != agent_id: + ACTION_UNKNOWN: int = -1 + ACTION_REST = CommandAmbulance.ACTION_REST + ACTION_MOVE = CommandAmbulance.ACTION_MOVE + ACTION_RESCUE = CommandAmbulance.ACTION_RESCUE + ACTION_AUTONOMY = CommandAmbulance.ACTION_AUTONOMY + + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + + self._path_planning: PathPlanning = cast( + PathPlanning, + module_manager.get_module( + "DefaultCommandExecutorFire.PathPlanning", + "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", + ), + ) + self._action_fire_rescue = module_manager.get_extend_action( + "DefaultCommandExecutorFire.ExtendActionFireRescue", + "adf_core_python.implement.action.default_extend_action_rescue.DefaultExtendActionRescue", + ) + self._action_move = module_manager.get_extend_action( + "DefaultCommandExecutorFire.ExtendActionMove", + "adf_core_python.implement.action.default_extend_action_move.DefaultExtendActionMove", + ) + + self._command_type: int = self.ACTION_UNKNOWN + self._target: Optional[EntityID] = None + self._commander: Optional[EntityID] = None + + def set_command(self, command: CommandAmbulance) -> CommandExecutor: + agent_id: EntityID = self._agent_info.get_entity_id() + if command.get_command_executor_agent_entity_id() != agent_id: + return self + + self._command_type = command.get_execute_action() or self.ACTION_UNKNOWN + self._target = command.get_command_target_entity_id() + self._commander = command.get_sender_entity_id() + return self + + def calculate(self) -> CommandExecutor: + self._result = None + match self._command_type: + case self.ACTION_REST: + position = self._agent_info.get_entity_id() + if self._target is None: + refuges = self._world_info.get_entity_ids_of_types([Refuge]) + if position in refuges: + self._result = ActionRest() + else: + path = self._path_planning.get_path(position, refuges[0]) + if path: + self._result = ActionMove(path) + else: + self._result = ActionRest() + return self + if position != self._target: + path = self._path_planning.get_path(position, self._target) + if path: + self._result = ActionMove(path) return self - - self._command_type = command.get_execute_action() or self.ACTION_UNKNOWN - self._target = command.get_command_target_entity_id() - self._commander = command.get_sender_entity_id() + self._result = ActionRest() return self - - def calculate(self) -> CommandExecutor: - self._result = None - match self._command_type: - case self.ACTION_REST: - position = self._agent_info.get_entity_id() - if self._target is None: - refuges = self._world_info.get_entity_ids_of_types([Refuge]) - if position in refuges: - self._result = ActionRest() - else: - path = self._path_planning.get_path(position, refuges[0]) - if path: - self._result = ActionMove(path) - else: - self._result = ActionRest() - return self - if position != self._target: - path = self._path_planning.get_path(position, self._target) - if path: - self._result = ActionMove(path) - return self - self._result = ActionRest() - return self - case self.ACTION_MOVE: - if self._target: - self._result = ( - self._action_move.set_target_entity_id(self._target) - .calculate() - .get_action() - ) - return self - case self.ACTION_RESCUE: - if self._target: - self._result = ( - self._action_fire_rescue.set_target_entity_id(self._target) - .calculate() - .get_action() - ) - return self - case self.ACTION_AUTONOMY: - if self._target is None: - return self - target_entity = self._world_info.get_entity(self._target) - if isinstance(target_entity, Area): - if self._agent_info.some_one_on_board() is None: - self._result = ( - self._action_move.set_target_entity_id(self._target) - .calculate() - .get_action() - ) - else: - self._result = ( - self._action_move.set_target_entity_id(self._target) - .calculate() - .get_action() - ) - elif isinstance(target_entity, Human): - self._result = ( - self._action_fire_rescue.set_target_entity_id(self._target) - .calculate() - .get_action() - ) + case self.ACTION_MOVE: + if self._target: + self._result = ( + self._action_move.set_target_entity_id(self._target) + .calculate() + .get_action() + ) return self - - def update_info(self, message_manager: MessageManager) -> CommandExecutor: - super().update_info(message_manager) - if self.get_count_update_info() >= 2: - return self - - self._path_planning.update_info(message_manager) - self._action_fire_rescue.update_info(message_manager) - self._action_move.update_info(message_manager) - - if self._is_command_completed(): - if self._command_type == self.ACTION_UNKNOWN: - return self - if self._commander is None: - return self - - message_manager.add_message( - MessageReport( - True, - True, - False, - self._commander, - StandardMessagePriority.NORMAL, - ) - ) - self._command_type = self.ACTION_UNKNOWN - self._target = None - self._commander = None - - return self - - def precompute(self, precompute_data: PrecomputeData) -> CommandExecutor: - super().precompute(precompute_data) - if self.get_count_precompute() >= 2: - return self - self._path_planning.precompute(precompute_data) - self._action_fire_rescue.precompute(precompute_data) - self._action_move.precompute(precompute_data) + case self.ACTION_RESCUE: + if self._target: + self._result = ( + self._action_fire_rescue.set_target_entity_id(self._target) + .calculate() + .get_action() + ) return self - - def resume(self, precompute_data: PrecomputeData) -> CommandExecutor: - super().resume(precompute_data) - if self.get_count_resume() >= 2: - return self - self._path_planning.resume(precompute_data) - self._action_fire_rescue.resume(precompute_data) - self._action_move.resume(precompute_data) + case self.ACTION_AUTONOMY: + if self._target is None: + return self + target_entity = self._world_info.get_entity(self._target) + if isinstance(target_entity, Area): + if self._agent_info.some_one_on_board() is None: + self._result = ( + self._action_move.set_target_entity_id(self._target) + .calculate() + .get_action() + ) + else: + self._result = ( + self._action_move.set_target_entity_id(self._target) + .calculate() + .get_action() + ) + elif isinstance(target_entity, Human): + self._result = ( + self._action_fire_rescue.set_target_entity_id(self._target) + .calculate() + .get_action() + ) + return self + + def update_info(self, message_manager: MessageManager) -> CommandExecutor: + super().update_info(message_manager) + if self.get_count_update_info() >= 2: + return self + + self._path_planning.update_info(message_manager) + self._action_fire_rescue.update_info(message_manager) + self._action_move.update_info(message_manager) + + if self._is_command_completed(): + if self._command_type == self.ACTION_UNKNOWN: return self - - def prepare(self) -> CommandExecutor: - super().prepare() - if self.get_count_prepare() >= 2: - return self - self._path_planning.prepare() - self._action_fire_rescue.prepare() - self._action_move.prepare() + if self._commander is None: return self - def _is_command_completed(self) -> bool: - agent = self._agent_info.get_myself() - if not isinstance(agent, Human): - return False - - match self._command_type: - case self.ACTION_REST: - if self._target is None: - return agent.get_damage() == 0 - if (target_entity := self._world_info.get_entity(self._target)) is None: - return False - if isinstance(target_entity, Refuge): - return agent.get_damage() == 0 - return False - case self.ACTION_MOVE: - return ( - self._target is None - or self._agent_info.get_position_entity_id() == self._target - ) - case self.ACTION_RESCUE: - if self._target is None: - return True - human = self._world_info.get_entity(self._target) - if not isinstance(human, Human): - return True - return human.get_buriedness() == 0 or human.get_hp() == 0 - case self.ACTION_AUTONOMY: - if self._target is not None: - target_entity = self._world_info.get_entity(self._target) - if isinstance(target_entity, Area): - self._command_type = self.ACTION_MOVE - return self._is_command_completed() - elif isinstance(target_entity, Human): - human = target_entity - if human.get_hp() == 0: - return True - if isinstance(human, Civilian): - self._command_type = self.ACTION_RESCUE - return self._is_command_completed() - return True - case _: - return True + message_manager.add_message( + MessageReport( + True, + True, + False, + self._commander, + StandardMessagePriority.NORMAL, + ) + ) + self._command_type = self.ACTION_UNKNOWN + self._target = None + self._commander = None + + return self + + def precompute(self, precompute_data: PrecomputeData) -> CommandExecutor: + super().precompute(precompute_data) + if self.get_count_precompute() >= 2: + return self + self._path_planning.precompute(precompute_data) + self._action_fire_rescue.precompute(precompute_data) + self._action_move.precompute(precompute_data) + return self + + def resume(self, precompute_data: PrecomputeData) -> CommandExecutor: + super().resume(precompute_data) + if self.get_count_resume() >= 2: + return self + self._path_planning.resume(precompute_data) + self._action_fire_rescue.resume(precompute_data) + self._action_move.resume(precompute_data) + return self + + def prepare(self) -> CommandExecutor: + super().prepare() + if self.get_count_prepare() >= 2: + return self + self._path_planning.prepare() + self._action_fire_rescue.prepare() + self._action_move.prepare() + return self + + def _is_command_completed(self) -> bool: + agent = self._agent_info.get_myself() + if not isinstance(agent, Human): + return False + + match self._command_type: + case self.ACTION_REST: + if self._target is None: + return agent.get_damage() == 0 + if (target_entity := self._world_info.get_entity(self._target)) is None: + return False + if isinstance(target_entity, Refuge): + return agent.get_damage() == 0 + return False + case self.ACTION_MOVE: + return ( + self._target is None + or self._agent_info.get_position_entity_id() == self._target + ) + case self.ACTION_RESCUE: + if self._target is None: + return True + human = self._world_info.get_entity(self._target) + if not isinstance(human, Human): + return True + return human.get_buriedness() == 0 or human.get_hp() == 0 + case self.ACTION_AUTONOMY: + if self._target is not None: + target_entity = self._world_info.get_entity(self._target) + if isinstance(target_entity, Area): + self._command_type = self.ACTION_MOVE + return self._is_command_completed() + elif isinstance(target_entity, Human): + human = target_entity + if human.get_hp() == 0: + return True + if isinstance(human, Civilian): + self._command_type = self.ACTION_RESCUE + return self._is_command_completed() + return True + case _: + return True diff --git a/src/adf_core_python/implement/centralized/default_command_executor_police.py b/src/adf_core_python/implement/centralized/default_command_executor_police.py index abfb51f..94367c9 100644 --- a/src/adf_core_python/implement/centralized/default_command_executor_police.py +++ b/src/adf_core_python/implement/centralized/default_command_executor_police.py @@ -6,13 +6,13 @@ from adf_core_python.core.agent.action.common.action_rest import ActionRest from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.communication.standard.bundle.centralized.command_police import ( - CommandPolice, + CommandPolice, ) from adf_core_python.core.agent.communication.standard.bundle.centralized.message_report import ( - MessageReport, + MessageReport, ) from adf_core_python.core.agent.communication.standard.bundle.standard_message_priority import ( - StandardMessagePriority, + StandardMessagePriority, ) from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo @@ -25,236 +25,236 @@ class DefaultCommandExecutorPolice(CommandExecutor): - ACTION_UNKNOWN: int = -1 - ACTION_REST = CommandPolice.ACTION_REST - ACTION_MOVE = CommandPolice.ACTION_MOVE - ACTION_CLEAR = CommandPolice.ACTION_CLEAR - ACTION_AUTONOMY = CommandPolice.ACTION_AUTONOMY + ACTION_UNKNOWN: int = -1 + ACTION_REST = CommandPolice.ACTION_REST + ACTION_MOVE = CommandPolice.ACTION_MOVE + ACTION_CLEAR = CommandPolice.ACTION_CLEAR + ACTION_AUTONOMY = CommandPolice.ACTION_AUTONOMY - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) - self._path_planning: PathPlanning = cast( - PathPlanning, - module_manager.get_module( - "DefaultCommandExecutorPolice.PathPlanning", - "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", - ), - ) - self._action_clear = module_manager.get_extend_action( - "DefaultCommandExecutorPolice.ExtendActionClear", - "adf_core_python.implement.action.default_extend_action_clear.DefaultExtendActionClear", - ) - self._action_move = module_manager.get_extend_action( - "DefaultCommandExecutorPolice.ExtendActionMove", - "adf_core_python.implement.action.default_extend_action_move.DefaultExtendActionMove", - ) + self._path_planning: PathPlanning = cast( + PathPlanning, + module_manager.get_module( + "DefaultCommandExecutorPolice.PathPlanning", + "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", + ), + ) + self._action_clear = module_manager.get_extend_action( + "DefaultCommandExecutorPolice.ExtendActionClear", + "adf_core_python.implement.action.default_extend_action_clear.DefaultExtendActionClear", + ) + self._action_move = module_manager.get_extend_action( + "DefaultCommandExecutorPolice.ExtendActionMove", + "adf_core_python.implement.action.default_extend_action_move.DefaultExtendActionMove", + ) - self._command_type: int = self.ACTION_UNKNOWN - self._target: Optional[EntityID] = None - self._commander: Optional[EntityID] = None + self._command_type: int = self.ACTION_UNKNOWN + self._target: Optional[EntityID] = None + self._commander: Optional[EntityID] = None - def set_command(self, command: CommandPolice) -> CommandExecutor: - agent_id: EntityID = self._agent_info.get_entity_id() - if command.get_command_executor_agent_entity_id() != agent_id: - return self + def set_command(self, command: CommandPolice) -> CommandExecutor: + agent_id: EntityID = self._agent_info.get_entity_id() + if command.get_command_executor_agent_entity_id() != agent_id: + return self - self._command_type = command.get_execute_action() or self.ACTION_UNKNOWN - self._target = command.get_command_target_entity_id() - self._commander = command.get_sender_entity_id() - return self + self._command_type = command.get_execute_action() or self.ACTION_UNKNOWN + self._target = command.get_command_target_entity_id() + self._commander = command.get_sender_entity_id() + return self - def calculate(self) -> CommandExecutor: - self._result = None - match self._command_type: - case self.ACTION_REST: - position = self._agent_info.get_entity_id() - if self._target is None: - refuges = self._world_info.get_entity_ids_of_types([Refuge]) - if position in refuges: - self._result = ActionRest() - else: - path = self._path_planning.get_path(position, refuges[0]) - if path: - self._result = ActionMove(path) - else: - self._result = ActionRest() - return self - if position != self._target: - path = self._path_planning.get_path(position, self._target) - if path: - self._result = ActionMove(path) - return self - self._result = ActionRest() - return self - case self.ACTION_MOVE: - if self._target: - self._result = ( - self._action_move.set_target_entity_id(self._target) - .calculate() - .get_action() - ) - return self - case self.ACTION_CLEAR: - if self._target: - self._result = ( - self._action_clear.set_target_entity_id(self._target) - .calculate() - .get_action() - ) - return self - case self.ACTION_AUTONOMY: - if self._target is None: - return self - target_entity = self._world_info.get_entity(self._target) - if isinstance(target_entity, Area): - if self._agent_info.some_one_on_board() is None: - self._result = ( - self._action_move.set_target_entity_id(self._target) - .calculate() - .get_action() - ) - else: - self._result = ( - self._action_move.set_target_entity_id(self._target) - .calculate() - .get_action() - ) - elif isinstance(target_entity, Human): - self._result = ( - self._action_clear.set_target_entity_id(self._target) - .calculate() - .get_action() - ) + def calculate(self) -> CommandExecutor: + self._result = None + match self._command_type: + case self.ACTION_REST: + position = self._agent_info.get_entity_id() + if self._target is None: + refuges = self._world_info.get_entity_ids_of_types([Refuge]) + if position in refuges: + self._result = ActionRest() + else: + path = self._path_planning.get_path(position, refuges[0]) + if path: + self._result = ActionMove(path) + else: + self._result = ActionRest() + return self + if position != self._target: + path = self._path_planning.get_path(position, self._target) + if path: + self._result = ActionMove(path) + return self + self._result = ActionRest() return self + case self.ACTION_MOVE: + if self._target: + self._result = ( + self._action_move.set_target_entity_id(self._target) + .calculate() + .get_action() + ) + return self + case self.ACTION_CLEAR: + if self._target: + self._result = ( + self._action_clear.set_target_entity_id(self._target) + .calculate() + .get_action() + ) + return self + case self.ACTION_AUTONOMY: + if self._target is None: + return self + target_entity = self._world_info.get_entity(self._target) + if isinstance(target_entity, Area): + if self._agent_info.some_one_on_board() is None: + self._result = ( + self._action_move.set_target_entity_id(self._target) + .calculate() + .get_action() + ) + else: + self._result = ( + self._action_move.set_target_entity_id(self._target) + .calculate() + .get_action() + ) + elif isinstance(target_entity, Human): + self._result = ( + self._action_clear.set_target_entity_id(self._target) + .calculate() + .get_action() + ) + return self - def update_info(self, message_manager: MessageManager) -> CommandExecutor: - super().update_info(message_manager) - if self.get_count_update_info() >= 2: - return self + def update_info(self, message_manager: MessageManager) -> CommandExecutor: + super().update_info(message_manager) + if self.get_count_update_info() >= 2: + return self - self._path_planning.update_info(message_manager) - self._action_clear.update_info(message_manager) - self._action_move.update_info(message_manager) + self._path_planning.update_info(message_manager) + self._action_clear.update_info(message_manager) + self._action_move.update_info(message_manager) - if self._is_command_completed(): - if self._command_type == self.ACTION_UNKNOWN: - return self - if self._commander is None: - return self + if self._is_command_completed(): + if self._command_type == self.ACTION_UNKNOWN: + return self + if self._commander is None: + return self - message_manager.add_message( - MessageReport( - True, - True, - False, - self._commander, - StandardMessagePriority.NORMAL, - ) - ) - self._command_type = self.ACTION_UNKNOWN - self._target = None - self._commander = None + message_manager.add_message( + MessageReport( + True, + True, + False, + self._commander, + StandardMessagePriority.NORMAL, + ) + ) + self._command_type = self.ACTION_UNKNOWN + self._target = None + self._commander = None - return self + return self - def precompute(self, precompute_data: PrecomputeData) -> CommandExecutor: - super().precompute(precompute_data) - if self.get_count_precompute() >= 2: - return self - self._path_planning.precompute(precompute_data) - self._action_clear.precompute(precompute_data) - self._action_move.precompute(precompute_data) - return self + def precompute(self, precompute_data: PrecomputeData) -> CommandExecutor: + super().precompute(precompute_data) + if self.get_count_precompute() >= 2: + return self + self._path_planning.precompute(precompute_data) + self._action_clear.precompute(precompute_data) + self._action_move.precompute(precompute_data) + return self - def resume(self, precompute_data: PrecomputeData) -> CommandExecutor: - super().resume(precompute_data) - if self.get_count_resume() >= 2: - return self - self._path_planning.resume(precompute_data) - self._action_clear.resume(precompute_data) - self._action_move.resume(precompute_data) - return self + def resume(self, precompute_data: PrecomputeData) -> CommandExecutor: + super().resume(precompute_data) + if self.get_count_resume() >= 2: + return self + self._path_planning.resume(precompute_data) + self._action_clear.resume(precompute_data) + self._action_move.resume(precompute_data) + return self - def prepare(self) -> CommandExecutor: - super().prepare() - if self.get_count_prepare() >= 2: - return self - self._path_planning.prepare() - self._action_clear.prepare() - self._action_move.prepare() - return self + def prepare(self) -> CommandExecutor: + super().prepare() + if self.get_count_prepare() >= 2: + return self + self._path_planning.prepare() + self._action_clear.prepare() + self._action_move.prepare() + return self - def _is_command_completed(self) -> bool: - agent = self._agent_info.get_myself() - if not isinstance(agent, Human): - return False + def _is_command_completed(self) -> bool: + agent = self._agent_info.get_myself() + if not isinstance(agent, Human): + return False - match self._command_type: - case self.ACTION_REST: - if self._target is None: - damage = agent.get_damage() - return damage is not None and damage == 0 - if (target_entity := self._world_info.get_entity(self._target)) is None: - return False - if isinstance(target_entity, Refuge): - damage = agent.get_damage() - return damage is not None and damage == 0 - return False - case self.ACTION_MOVE: - return ( - self._target is None - or self._agent_info.get_position_entity_id() == self._target - ) - case self.ACTION_CLEAR: - if self._target is None: - return True - entity = self._world_info.get_entity(self._target) - if isinstance(entity, Road): - blockades = entity.get_blockades() - if blockades is not None: - return len(blockades) == 0 - return self._agent_info.get_position_entity_id() == self._target - return True - case self.ACTION_AUTONOMY: - if self._target is not None: - target_entity = self._world_info.get_entity(self._target) - if isinstance(target_entity, Refuge): - damage = agent.get_damage() - self._command_type = ( - self.ACTION_REST - if damage is not None and damage > 0 - else self.ACTION_CLEAR - ) - return self._is_command_completed() - elif isinstance(target_entity, Area): - self._command_type = self.ACTION_CLEAR - return self._is_command_completed() - elif isinstance(target_entity, Human): - if target_entity.get_hp() == 0: - return True - position = target_entity.get_position() - if position is not None and isinstance( - self._world_info.get_entity(position), - Area, - ): - self._target = target_entity.get_position() - self._command_type = self.ACTION_CLEAR - return self._is_command_completed() - elif isinstance(target_entity, Blockade): - if target_entity.get_position() is not None: - self._target = target_entity.get_position() - self._command_type = self.ACTION_CLEAR - return self._is_command_completed() - return True - case _: - return True + match self._command_type: + case self.ACTION_REST: + if self._target is None: + damage = agent.get_damage() + return damage is not None and damage == 0 + if (target_entity := self._world_info.get_entity(self._target)) is None: + return False + if isinstance(target_entity, Refuge): + damage = agent.get_damage() + return damage is not None and damage == 0 + return False + case self.ACTION_MOVE: + return ( + self._target is None + or self._agent_info.get_position_entity_id() == self._target + ) + case self.ACTION_CLEAR: + if self._target is None: + return True + entity = self._world_info.get_entity(self._target) + if isinstance(entity, Road): + blockades = entity.get_blockades() + if blockades is not None: + return len(blockades) == 0 + return self._agent_info.get_position_entity_id() == self._target + return True + case self.ACTION_AUTONOMY: + if self._target is not None: + target_entity = self._world_info.get_entity(self._target) + if isinstance(target_entity, Refuge): + damage = agent.get_damage() + self._command_type = ( + self.ACTION_REST + if damage is not None and damage > 0 + else self.ACTION_CLEAR + ) + return self._is_command_completed() + elif isinstance(target_entity, Area): + self._command_type = self.ACTION_CLEAR + return self._is_command_completed() + elif isinstance(target_entity, Human): + if target_entity.get_hp() == 0: + return True + position = target_entity.get_position() + if position is not None and isinstance( + self._world_info.get_entity(position), + Area, + ): + self._target = target_entity.get_position() + self._command_type = self.ACTION_CLEAR + return self._is_command_completed() + elif isinstance(target_entity, Blockade): + if target_entity.get_position() is not None: + self._target = target_entity.get_position() + self._command_type = self.ACTION_CLEAR + return self._is_command_completed() + return True + case _: + return True diff --git a/src/adf_core_python/implement/centralized/default_command_executor_scout.py b/src/adf_core_python/implement/centralized/default_command_executor_scout.py index 7941ed5..8693cdf 100644 --- a/src/adf_core_python/implement/centralized/default_command_executor_scout.py +++ b/src/adf_core_python/implement/centralized/default_command_executor_scout.py @@ -5,13 +5,13 @@ from adf_core_python.core.agent.action.common.action_move import ActionMove from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.communication.standard.bundle.centralized.command_scout import ( - CommandScout, + CommandScout, ) from adf_core_python.core.agent.communication.standard.bundle.centralized.message_report import ( - MessageReport, + MessageReport, ) from adf_core_python.core.agent.communication.standard.bundle.standard_message_priority import ( - StandardMessagePriority, + StandardMessagePriority, ) from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo @@ -24,139 +24,136 @@ class DefaultCommandExecutorScout(CommandExecutor): - ACTION_UNKNOWN: int = -1 - ACTION_SCOUT: int = 1 - - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - - self._path_planning: PathPlanning = cast( - PathPlanning, - module_manager.get_module( - "DefaultCommandExecutorScout.PathPlanning", - "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", - ), - ) - - self._command_type: int = self.ACTION_UNKNOWN - self._targets: list[EntityID] = [] - self._commander: Optional[EntityID] = None - - def set_command(self, command: CommandScout) -> CommandExecutor: - agent_id: EntityID = self._agent_info.get_entity_id() - if command.get_command_executor_agent_entity_id() != agent_id: - return self - - target = command.get_command_target_entity_id() - if target is None: - target = self._agent_info.get_position_entity_id() - if target is None: - return self - - self._command_type = self.ACTION_SCOUT - self._commander = command.get_sender_entity_id() - self._targets = [] - if (scout_distance := command.get_scout_range()) is None: - return self - - for entity in self._world_info.get_entities_of_types([Road, Building]): - if isinstance(entity, Refuge): - continue - if ( - self._world_info.get_distance(target, entity.get_entity_id()) - <= scout_distance - ): - self._targets.append(entity.get_entity_id()) - + ACTION_UNKNOWN: int = -1 + ACTION_SCOUT: int = 1 + + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + + self._path_planning: PathPlanning = cast( + PathPlanning, + module_manager.get_module( + "DefaultCommandExecutorScout.PathPlanning", + "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", + ), + ) + + self._command_type: int = self.ACTION_UNKNOWN + self._targets: list[EntityID] = [] + self._commander: Optional[EntityID] = None + + def set_command(self, command: CommandScout) -> CommandExecutor: + agent_id: EntityID = self._agent_info.get_entity_id() + if command.get_command_executor_agent_entity_id() != agent_id: + return self + + target = command.get_command_target_entity_id() + if target is None: + target = self._agent_info.get_position_entity_id() + if target is None: return self - def calculate(self) -> CommandExecutor: - self._result = None - match self._command_type: - case self.ACTION_SCOUT: - if len(self._targets) == 0: - return self - agent_position = self._agent_info.get_position_entity_id() - if agent_position is None: - return self - path = self._path_planning.get_path(agent_position, self._targets[0]) - if path is None: - return self - self._result = ActionMove(path) - case _: - return self + self._command_type = self.ACTION_SCOUT + self._commander = command.get_sender_entity_id() + self._targets = [] + if (scout_distance := command.get_scout_range()) is None: + return self + + for entity in self._world_info.get_entities_of_types([Road, Building]): + if isinstance(entity, Refuge): + continue + if ( + self._world_info.get_distance(target, entity.get_entity_id()) <= scout_distance + ): + self._targets.append(entity.get_entity_id()) + + return self + + def calculate(self) -> CommandExecutor: + self._result = None + match self._command_type: + case self.ACTION_SCOUT: + if len(self._targets) == 0: + return self + agent_position = self._agent_info.get_position_entity_id() + if agent_position is None: + return self + path = self._path_planning.get_path(agent_position, self._targets[0]) + if path is None: + return self + self._result = ActionMove(path) + case _: return self + return self - def update_info(self, message_manager: MessageManager) -> CommandExecutor: - super().update_info(message_manager) - if self.get_count_update_info() >= 2: - return self - - self._path_planning.update_info(message_manager) - - if self._is_command_completed(): - if self._command_type == self.ACTION_UNKNOWN: - return self - if self._commander is None: - return self - - message_manager.add_message( - MessageReport( - True, - True, - False, - self._commander, - StandardMessagePriority.NORMAL, - ) - ) - self._command_type = self.ACTION_UNKNOWN - self._target = None - self._commander = None + def update_info(self, message_manager: MessageManager) -> CommandExecutor: + super().update_info(message_manager) + if self.get_count_update_info() >= 2: + return self - return self + self._path_planning.update_info(message_manager) - def precompute(self, precompute_data: PrecomputeData) -> CommandExecutor: - super().precompute(precompute_data) - if self.get_count_precompute() >= 2: - return self - self._path_planning.precompute(precompute_data) + if self._is_command_completed(): + if self._command_type == self.ACTION_UNKNOWN: return self - - def resume(self, precompute_data: PrecomputeData) -> CommandExecutor: - super().resume(precompute_data) - if self.get_count_resume() >= 2: - return self - self._path_planning.resume(precompute_data) + if self._commander is None: return self - def prepare(self) -> CommandExecutor: - super().prepare() - if self.get_count_prepare() >= 2: - return self - self._path_planning.prepare() - return self - - def _is_command_completed(self) -> bool: - agent = self._agent_info.get_myself() - if not isinstance(agent, Human): - return False - - match self._command_type: - case self.ACTION_SCOUT: - if len(self._targets) != 0: - for entity in self._world_info.get_entities_of_types( - [Road, Building] - ): - self._targets.remove(entity.get_entity_id()) - return len(self._targets) == 0 - case _: - return True + message_manager.add_message( + MessageReport( + True, + True, + False, + self._commander, + StandardMessagePriority.NORMAL, + ) + ) + self._command_type = self.ACTION_UNKNOWN + self._target = None + self._commander = None + + return self + + def precompute(self, precompute_data: PrecomputeData) -> CommandExecutor: + super().precompute(precompute_data) + if self.get_count_precompute() >= 2: + return self + self._path_planning.precompute(precompute_data) + return self + + def resume(self, precompute_data: PrecomputeData) -> CommandExecutor: + super().resume(precompute_data) + if self.get_count_resume() >= 2: + return self + self._path_planning.resume(precompute_data) + return self + + def prepare(self) -> CommandExecutor: + super().prepare() + if self.get_count_prepare() >= 2: + return self + self._path_planning.prepare() + return self + + def _is_command_completed(self) -> bool: + agent = self._agent_info.get_myself() + if not isinstance(agent, Human): + return False + + match self._command_type: + case self.ACTION_SCOUT: + if len(self._targets) != 0: + for entity in self._world_info.get_entities_of_types([Road, Building]): + self._targets.remove(entity.get_entity_id()) + return len(self._targets) == 0 + case _: + return True diff --git a/src/adf_core_python/implement/centralized/default_command_executor_scout_police.py b/src/adf_core_python/implement/centralized/default_command_executor_scout_police.py index f1806ad..00d4f47 100644 --- a/src/adf_core_python/implement/centralized/default_command_executor_scout_police.py +++ b/src/adf_core_python/implement/centralized/default_command_executor_scout_police.py @@ -5,13 +5,13 @@ from adf_core_python.core.agent.action.common.action_move import ActionMove from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.communication.standard.bundle.centralized.command_scout import ( - CommandScout, + CommandScout, ) from adf_core_python.core.agent.communication.standard.bundle.centralized.message_report import ( - MessageReport, + MessageReport, ) from adf_core_python.core.agent.communication.standard.bundle.standard_message_priority import ( - StandardMessagePriority, + StandardMessagePriority, ) from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo @@ -25,150 +25,149 @@ class DefaultCommandExecutorScoutPolice(CommandExecutor): - ACTION_UNKNOWN: int = -1 - ACTION_SCOUT: int = 1 - - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - - self._path_planning: PathPlanning = cast( - PathPlanning, - module_manager.get_module( - "DefaultCommandExecutorScoutPolice.PathPlanning", - "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", - ), - ) - self._action_clear: ExtendAction = module_manager.get_extend_action( - "DefaultCommandExecutorScoutPolice.ExtendActionClear", - "adf_core_python.implement.action.default_extend_action_clear.DefaultExtendActionClear", - ) - - self._command_type: int = self.ACTION_UNKNOWN - self._targets: list[EntityID] = [] - self._commander: Optional[EntityID] = None - - def set_command(self, command: CommandScout) -> CommandExecutor: - agent_id: EntityID = self._agent_info.get_entity_id() - if command.get_command_executor_agent_entity_id() != agent_id: - return self - - target = command.get_command_target_entity_id() - if target is None: - target = self._agent_info.get_position_entity_id() - if target is None: - return self - - self._command_type = self.ACTION_SCOUT - self._commander = command.get_sender_entity_id() - self._targets = [] - if (scout_distance := command.get_scout_range()) is None: - return self - - for entity in self._world_info.get_entities_of_types([Road, Building, Refuge]): - if isinstance(entity, Refuge): - continue - if ( - self._world_info.get_distance(target, entity.get_entity_id()) - <= scout_distance - ): - self._targets.append(entity.get_entity_id()) - + ACTION_UNKNOWN: int = -1 + ACTION_SCOUT: int = 1 + + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + + self._path_planning: PathPlanning = cast( + PathPlanning, + module_manager.get_module( + "DefaultCommandExecutorScoutPolice.PathPlanning", + "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", + ), + ) + self._action_clear: ExtendAction = module_manager.get_extend_action( + "DefaultCommandExecutorScoutPolice.ExtendActionClear", + "adf_core_python.implement.action.default_extend_action_clear.DefaultExtendActionClear", + ) + + self._command_type: int = self.ACTION_UNKNOWN + self._targets: list[EntityID] = [] + self._commander: Optional[EntityID] = None + + def set_command(self, command: CommandScout) -> CommandExecutor: + agent_id: EntityID = self._agent_info.get_entity_id() + if command.get_command_executor_agent_entity_id() != agent_id: + return self + + target = command.get_command_target_entity_id() + if target is None: + target = self._agent_info.get_position_entity_id() + if target is None: return self - def calculate(self) -> CommandExecutor: - self._result = None - match self._command_type: - case self.ACTION_SCOUT: - if len(self._targets) == 0: - return self - agent_position = self._agent_info.get_position_entity_id() - if agent_position is None: - return self - path = self._path_planning.get_path(agent_position, self._targets[0]) - if path is None: - return self - action = ( - self._action_clear.set_target_entity_id(self._targets[0]) - .calculate() - .get_action() - ) - if action is None: - action = ActionMove(path) - self._result = action - case _: - return self + self._command_type = self.ACTION_SCOUT + self._commander = command.get_sender_entity_id() + self._targets = [] + if (scout_distance := command.get_scout_range()) is None: + return self + + for entity in self._world_info.get_entities_of_types([Road, Building, Refuge]): + if isinstance(entity, Refuge): + continue + if ( + self._world_info.get_distance(target, entity.get_entity_id()) <= scout_distance + ): + self._targets.append(entity.get_entity_id()) + + return self + + def calculate(self) -> CommandExecutor: + self._result = None + match self._command_type: + case self.ACTION_SCOUT: + if len(self._targets) == 0: + return self + agent_position = self._agent_info.get_position_entity_id() + if agent_position is None: + return self + path = self._path_planning.get_path(agent_position, self._targets[0]) + if path is None: + return self + action = ( + self._action_clear.set_target_entity_id(self._targets[0]) + .calculate() + .get_action() + ) + if action is None: + action = ActionMove(path) + self._result = action + case _: return self + return self - def update_info(self, message_manager: MessageManager) -> CommandExecutor: - super().update_info(message_manager) - if self.get_count_update_info() >= 2: - return self - - self._path_planning.update_info(message_manager) - - if self._is_command_completed(): - if self._command_type == self.ACTION_UNKNOWN: - return self - if self._commander is None: - return self - - message_manager.add_message( - MessageReport( - True, - True, - False, - self._commander, - StandardMessagePriority.NORMAL, - ) - ) - self._command_type = self.ACTION_UNKNOWN - self._target = None - self._commander = None - - return self + def update_info(self, message_manager: MessageManager) -> CommandExecutor: + super().update_info(message_manager) + if self.get_count_update_info() >= 2: + return self - def precompute(self, precompute_data: PrecomputeData) -> CommandExecutor: - super().precompute(precompute_data) - if self.get_count_precompute() >= 2: - return self - self._path_planning.precompute(precompute_data) - return self + self._path_planning.update_info(message_manager) - def resume(self, precompute_data: PrecomputeData) -> CommandExecutor: - super().resume(precompute_data) - if self.get_count_resume() >= 2: - return self - self._path_planning.resume(precompute_data) + if self._is_command_completed(): + if self._command_type == self.ACTION_UNKNOWN: return self - - def prepare(self) -> CommandExecutor: - super().prepare() - if self.get_count_prepare() >= 2: - return self - self._path_planning.prepare() + if self._commander is None: return self - def _is_command_completed(self) -> bool: - agent = self._agent_info.get_myself() - if not isinstance(agent, Human): - return False - - match self._command_type: - case self.ACTION_SCOUT: - if len(self._targets) != 0: - for entity in self._world_info.get_entities_of_types( - [Road, Building, Refuge] - ): - self._targets.remove(entity.get_entity_id()) - return len(self._targets) == 0 - case _: - return True + message_manager.add_message( + MessageReport( + True, + True, + False, + self._commander, + StandardMessagePriority.NORMAL, + ) + ) + self._command_type = self.ACTION_UNKNOWN + self._target = None + self._commander = None + + return self + + def precompute(self, precompute_data: PrecomputeData) -> CommandExecutor: + super().precompute(precompute_data) + if self.get_count_precompute() >= 2: + return self + self._path_planning.precompute(precompute_data) + return self + + def resume(self, precompute_data: PrecomputeData) -> CommandExecutor: + super().resume(precompute_data) + if self.get_count_resume() >= 2: + return self + self._path_planning.resume(precompute_data) + return self + + def prepare(self) -> CommandExecutor: + super().prepare() + if self.get_count_prepare() >= 2: + return self + self._path_planning.prepare() + return self + + def _is_command_completed(self) -> bool: + agent = self._agent_info.get_myself() + if not isinstance(agent, Human): + return False + + match self._command_type: + case self.ACTION_SCOUT: + if len(self._targets) != 0: + for entity in self._world_info.get_entities_of_types( + [Road, Building, Refuge] + ): + self._targets.remove(entity.get_entity_id()) + return len(self._targets) == 0 + case _: + return True diff --git a/src/adf_core_python/implement/centralized/default_command_picker_ambulance.py b/src/adf_core_python/implement/centralized/default_command_picker_ambulance.py index edddf4e..753b188 100644 --- a/src/adf_core_python/implement/centralized/default_command_picker_ambulance.py +++ b/src/adf_core_python/implement/centralized/default_command_picker_ambulance.py @@ -3,13 +3,13 @@ from rcrscore.entities import AmbulanceTeam, Area, EntityID, Human from adf_core_python.core.agent.communication.standard.bundle.centralized.command_ambulance import ( - CommandAmbulance, + CommandAmbulance, ) from adf_core_python.core.agent.communication.standard.bundle.centralized.command_scout import ( - CommandScout, + CommandScout, ) from adf_core_python.core.agent.communication.standard.bundle.standard_message_priority import ( - StandardMessagePriority, + StandardMessagePriority, ) from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo @@ -18,69 +18,69 @@ from adf_core_python.core.agent.module.module_manager import ModuleManager from adf_core_python.core.component.centralized.command_picker import CommandPicker from adf_core_python.core.component.communication.communication_message import ( - CommunicationMessage, + CommunicationMessage, ) class DefaultCommandPickerAmbulance(CommandPicker): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - self.messages: list[CommunicationMessage] = [] - self.scout_distance: int = 40000 - self.allocation_data: dict[EntityID, EntityID] = {} + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + self.messages: list[CommunicationMessage] = [] + self.scout_distance: int = 40000 + self.allocation_data: dict[EntityID, EntityID] = {} - def set_allocator_result( - self, allocation_data: dict[EntityID, EntityID] - ) -> CommandPicker: - self.allocation_data = allocation_data - return self + def set_allocator_result( + self, allocation_data: dict[EntityID, EntityID] + ) -> CommandPicker: + self.allocation_data = allocation_data + return self - def calculate(self) -> CommandPicker: - self.messages.clear() - if not self.allocation_data: - return self + def calculate(self) -> CommandPicker: + self.messages.clear() + if not self.allocation_data: + return self - for ambulance_id in self.allocation_data.keys(): - agent = self._world_info.get_entity(ambulance_id) - if agent is None or not isinstance(agent, AmbulanceTeam): - continue + for ambulance_id in self.allocation_data.keys(): + agent = self._world_info.get_entity(ambulance_id) + if agent is None or not isinstance(agent, AmbulanceTeam): + continue - target = self._world_info.get_entity(self.allocation_data[ambulance_id]) - if target is None: - continue + target = self._world_info.get_entity(self.allocation_data[ambulance_id]) + if target is None: + continue - command: CommunicationMessage - if isinstance(target, Human): - command = CommandAmbulance( - True, - ambulance_id, - self._agent_info.get_entity_id(), - CommandAmbulance.ACTION_RESCUE, - StandardMessagePriority.NORMAL, - target.get_entity_id(), - ) - self.messages.append(command) + command: CommunicationMessage + if isinstance(target, Human): + command = CommandAmbulance( + True, + ambulance_id, + self._agent_info.get_entity_id(), + CommandAmbulance.ACTION_RESCUE, + StandardMessagePriority.NORMAL, + target.get_entity_id(), + ) + self.messages.append(command) - if isinstance(target, Area): - command = CommandScout( - True, - ambulance_id, - self._agent_info.get_entity_id(), - self.scout_distance, - StandardMessagePriority.NORMAL, - target.get_entity_id(), - ) - self.messages.append(command) - return self + if isinstance(target, Area): + command = CommandScout( + True, + ambulance_id, + self._agent_info.get_entity_id(), + self.scout_distance, + StandardMessagePriority.NORMAL, + target.get_entity_id(), + ) + self.messages.append(command) + return self - def get_result(self) -> list[CommunicationMessage]: - return self.messages + def get_result(self) -> list[CommunicationMessage]: + return self.messages diff --git a/src/adf_core_python/implement/centralized/default_command_picker_fire.py b/src/adf_core_python/implement/centralized/default_command_picker_fire.py index a5c8017..b7ec038 100644 --- a/src/adf_core_python/implement/centralized/default_command_picker_fire.py +++ b/src/adf_core_python/implement/centralized/default_command_picker_fire.py @@ -3,13 +3,13 @@ from rcrscore.entities import Area, EntityID, FireBrigade, Human from adf_core_python.core.agent.communication.standard.bundle.centralized.command_ambulance import ( - CommandAmbulance, + CommandAmbulance, ) from adf_core_python.core.agent.communication.standard.bundle.centralized.command_scout import ( - CommandScout, + CommandScout, ) from adf_core_python.core.agent.communication.standard.bundle.standard_message_priority import ( - StandardMessagePriority, + StandardMessagePriority, ) from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo @@ -18,69 +18,69 @@ from adf_core_python.core.agent.module.module_manager import ModuleManager from adf_core_python.core.component.centralized.command_picker import CommandPicker from adf_core_python.core.component.communication.communication_message import ( - CommunicationMessage, + CommunicationMessage, ) class DefaultCommandPickerFire(CommandPicker): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - self.messages: list[CommunicationMessage] = [] - self.scout_distance: int = 40000 - self.allocation_data: dict[EntityID, EntityID] = {} + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + self.messages: list[CommunicationMessage] = [] + self.scout_distance: int = 40000 + self.allocation_data: dict[EntityID, EntityID] = {} - def set_allocator_result( - self, allocation_data: dict[EntityID, EntityID] - ) -> CommandPicker: - self.allocation_data = allocation_data - return self + def set_allocator_result( + self, allocation_data: dict[EntityID, EntityID] + ) -> CommandPicker: + self.allocation_data = allocation_data + return self - def calculate(self) -> CommandPicker: - self.messages.clear() - if not self.allocation_data: - return self + def calculate(self) -> CommandPicker: + self.messages.clear() + if not self.allocation_data: + return self - for ambulance_id in self.allocation_data.keys(): - agent = self._world_info.get_entity(ambulance_id) - if agent is None or not isinstance(agent, FireBrigade): - continue + for ambulance_id in self.allocation_data.keys(): + agent = self._world_info.get_entity(ambulance_id) + if agent is None or not isinstance(agent, FireBrigade): + continue - target = self._world_info.get_entity(self.allocation_data[ambulance_id]) - if target is None: - continue + target = self._world_info.get_entity(self.allocation_data[ambulance_id]) + if target is None: + continue - command: CommunicationMessage - if isinstance(target, Human): - command = CommandAmbulance( - True, - ambulance_id, - self._agent_info.get_entity_id(), - CommandAmbulance.ACTION_RESCUE, - StandardMessagePriority.NORMAL, - target.get_entity_id(), - ) - self.messages.append(command) + command: CommunicationMessage + if isinstance(target, Human): + command = CommandAmbulance( + True, + ambulance_id, + self._agent_info.get_entity_id(), + CommandAmbulance.ACTION_RESCUE, + StandardMessagePriority.NORMAL, + target.get_entity_id(), + ) + self.messages.append(command) - if isinstance(target, Area): - command = CommandScout( - True, - ambulance_id, - self._agent_info.get_entity_id(), - self.scout_distance, - StandardMessagePriority.NORMAL, - target.get_entity_id(), - ) - self.messages.append(command) - return self + if isinstance(target, Area): + command = CommandScout( + True, + ambulance_id, + self._agent_info.get_entity_id(), + self.scout_distance, + StandardMessagePriority.NORMAL, + target.get_entity_id(), + ) + self.messages.append(command) + return self - def get_result(self) -> list[CommunicationMessage]: - return self.messages + def get_result(self) -> list[CommunicationMessage]: + return self.messages diff --git a/src/adf_core_python/implement/centralized/default_command_picker_police.py b/src/adf_core_python/implement/centralized/default_command_picker_police.py index 0dbde23..f6be460 100644 --- a/src/adf_core_python/implement/centralized/default_command_picker_police.py +++ b/src/adf_core_python/implement/centralized/default_command_picker_police.py @@ -3,10 +3,10 @@ from rcrscore.entities import Area, EntityID, PoliceForce from adf_core_python.core.agent.communication.standard.bundle.centralized.command_police import ( - CommandPolice, + CommandPolice, ) from adf_core_python.core.agent.communication.standard.bundle.standard_message_priority import ( - StandardMessagePriority, + StandardMessagePriority, ) from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo @@ -15,56 +15,56 @@ from adf_core_python.core.agent.module.module_manager import ModuleManager from adf_core_python.core.component.centralized.command_picker import CommandPicker from adf_core_python.core.component.communication.communication_message import ( - CommunicationMessage, + CommunicationMessage, ) class DefaultCommandPickerPolice(CommandPicker): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - self.messages: list[CommunicationMessage] = [] - self.allocation_data: dict[EntityID, EntityID] = {} + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + self.messages: list[CommunicationMessage] = [] + self.allocation_data: dict[EntityID, EntityID] = {} - def set_allocator_result( - self, allocation_data: dict[EntityID, EntityID] - ) -> CommandPicker: - self.allocation_data = allocation_data - return self + def set_allocator_result( + self, allocation_data: dict[EntityID, EntityID] + ) -> CommandPicker: + self.allocation_data = allocation_data + return self - def calculate(self) -> CommandPicker: - self.messages.clear() - if not self.allocation_data: - return self + def calculate(self) -> CommandPicker: + self.messages.clear() + if not self.allocation_data: + return self - for ambulance_id in self.allocation_data.keys(): - agent = self._world_info.get_entity(ambulance_id) - if agent is None or not isinstance(agent, PoliceForce): - continue + for ambulance_id in self.allocation_data.keys(): + agent = self._world_info.get_entity(ambulance_id) + if agent is None or not isinstance(agent, PoliceForce): + continue - target = self._world_info.get_entity(self.allocation_data[ambulance_id]) - if target is None: - continue + target = self._world_info.get_entity(self.allocation_data[ambulance_id]) + if target is None: + continue - if isinstance(target, Area): - command = CommandPolice( - True, - agent.get_entity_id(), - self._agent_info.get_entity_id(), - CommandPolice.ACTION_AUTONOMY, - StandardMessagePriority.NORMAL, - target.get_entity_id(), - ) - self.messages.append(command) - return self + if isinstance(target, Area): + command = CommandPolice( + True, + agent.get_entity_id(), + self._agent_info.get_entity_id(), + CommandPolice.ACTION_AUTONOMY, + StandardMessagePriority.NORMAL, + target.get_entity_id(), + ) + self.messages.append(command) + return self - def get_result(self) -> list[CommunicationMessage]: - return self.messages + def get_result(self) -> list[CommunicationMessage]: + return self.messages diff --git a/src/adf_core_python/implement/default_loader.py b/src/adf_core_python/implement/default_loader.py index f3af8f8..9b63888 100644 --- a/src/adf_core_python/implement/default_loader.py +++ b/src/adf_core_python/implement/default_loader.py @@ -1,57 +1,57 @@ from adf_core_python.core.component.abstract_loader import AbstractLoader from adf_core_python.core.component.tactics.tactics_ambulance_center import ( - TacticsAmbulanceCenter, + TacticsAmbulanceCenter, ) from adf_core_python.core.component.tactics.tactics_ambulance_team import ( - TacticsAmbulanceTeam, + TacticsAmbulanceTeam, ) from adf_core_python.core.component.tactics.tactics_fire_brigade import ( - TacticsFireBrigade, + TacticsFireBrigade, ) from adf_core_python.core.component.tactics.tactics_fire_station import ( - TacticsFireStation, + TacticsFireStation, ) from adf_core_python.core.component.tactics.tactics_police_force import ( - TacticsPoliceForce, + TacticsPoliceForce, ) from adf_core_python.core.component.tactics.tactics_police_office import ( - TacticsPoliceOffice, + TacticsPoliceOffice, ) from adf_core_python.implement.tactics.default_tactics_ambulance_center import ( - DefaultTacticsAmbulanceCenter, + DefaultTacticsAmbulanceCenter, ) from adf_core_python.implement.tactics.default_tactics_ambulance_team import ( - DefaultTacticsAmbulanceTeam, + DefaultTacticsAmbulanceTeam, ) from adf_core_python.implement.tactics.default_tactics_fire_brigade import ( - DefaultTacticsFireBrigade, + DefaultTacticsFireBrigade, ) from adf_core_python.implement.tactics.default_tactics_fire_station import ( - DefaultTacticsFireStation, + DefaultTacticsFireStation, ) from adf_core_python.implement.tactics.default_tactics_police_force import ( - DefaultTacticsPoliceForce, + DefaultTacticsPoliceForce, ) from adf_core_python.implement.tactics.default_tactics_police_office import ( - DefaultTacticsPoliceOffice, + DefaultTacticsPoliceOffice, ) class DefaultLoader(AbstractLoader): - def get_tactics_ambulance_team(self) -> TacticsAmbulanceTeam: - return DefaultTacticsAmbulanceTeam() + def get_tactics_ambulance_team(self) -> TacticsAmbulanceTeam: + return DefaultTacticsAmbulanceTeam() - def get_tactics_fire_brigade(self) -> TacticsFireBrigade: - return DefaultTacticsFireBrigade() + def get_tactics_fire_brigade(self) -> TacticsFireBrigade: + return DefaultTacticsFireBrigade() - def get_tactics_police_force(self) -> TacticsPoliceForce: - return DefaultTacticsPoliceForce() + def get_tactics_police_force(self) -> TacticsPoliceForce: + return DefaultTacticsPoliceForce() - def get_tactics_ambulance_center(self) -> TacticsAmbulanceCenter: - return DefaultTacticsAmbulanceCenter() + def get_tactics_ambulance_center(self) -> TacticsAmbulanceCenter: + return DefaultTacticsAmbulanceCenter() - def get_tactics_fire_station(self) -> TacticsFireStation: - return DefaultTacticsFireStation() + def get_tactics_fire_station(self) -> TacticsFireStation: + return DefaultTacticsFireStation() - def get_tactics_police_office(self) -> TacticsPoliceOffice: - return DefaultTacticsPoliceOffice() + def get_tactics_police_office(self) -> TacticsPoliceOffice: + return DefaultTacticsPoliceOffice() diff --git a/src/adf_core_python/implement/module/algorithm/a_star_path_planning.py b/src/adf_core_python/implement/module/algorithm/a_star_path_planning.py index e31cef3..8b2741a 100644 --- a/src/adf_core_python/implement/module/algorithm/a_star_path_planning.py +++ b/src/adf_core_python/implement/module/algorithm/a_star_path_planning.py @@ -8,96 +8,86 @@ 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.component.module.algorithm.path_planning import ( - PathPlanning, + PathPlanning, ) class AStarPathPlanning(PathPlanning): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + entities: list[Entity] = self._world_info.get_entities_of_types([Building, Road]) + self._graph: dict[EntityID, set[EntityID]] = {} + for entity in entities: + if isinstance(entity, Area): + self._graph[entity.get_entity_id()] = set( + neighbor for neighbor in entity.get_neighbors() if neighbor != EntityID(0) ) - entities: list[Entity] = self._world_info.get_entities_of_types( - [Building, Road] - ) - self._graph: dict[EntityID, set[EntityID]] = {} - for entity in entities: - if isinstance(entity, Area): - self._graph[entity.get_entity_id()] = set( - neighbor - for neighbor in entity.get_neighbors() - if neighbor != EntityID(0) - ) - def get_path( - self, from_entity_id: EntityID, to_entity_id: EntityID - ) -> list[EntityID]: - open_set: set[EntityID] = {from_entity_id} - came_from: dict[EntityID, EntityID] = {} - g_score: dict[EntityID, float] = {from_entity_id: 0.0} - f_score: dict[EntityID, float] = { - from_entity_id: self.heuristic(from_entity_id, to_entity_id) - } + def get_path( + self, from_entity_id: EntityID, to_entity_id: EntityID + ) -> list[EntityID]: + open_set: set[EntityID] = {from_entity_id} + came_from: dict[EntityID, EntityID] = {} + g_score: dict[EntityID, float] = {from_entity_id: 0.0} + f_score: dict[EntityID, float] = { + from_entity_id: self.heuristic(from_entity_id, to_entity_id) + } - while open_set: - current: EntityID = min( - open_set, key=lambda x: f_score.get(x, float("inf")) - ) - if current == to_entity_id: - return self.reconstruct_path(came_from, current) + while open_set: + current: EntityID = min(open_set, key=lambda x: f_score.get(x, float("inf"))) + if current == to_entity_id: + return self.reconstruct_path(came_from, current) - open_set.remove(current) - for neighbor in self._graph.get(current, []): - tentative_g_score: float = g_score[current] + self.distance( - current, neighbor - ) - if tentative_g_score < g_score.get(neighbor, float("inf")): - came_from[neighbor] = current - g_score[neighbor] = tentative_g_score - f_score[neighbor] = tentative_g_score + self.heuristic( - neighbor, to_entity_id - ) - if neighbor not in open_set: - open_set.add(neighbor) + open_set.remove(current) + for neighbor in self._graph.get(current, []): + tentative_g_score: float = g_score[current] + self.distance(current, neighbor) + if tentative_g_score < g_score.get(neighbor, float("inf")): + came_from[neighbor] = current + g_score[neighbor] = tentative_g_score + f_score[neighbor] = tentative_g_score + self.heuristic(neighbor, to_entity_id) + if neighbor not in open_set: + open_set.add(neighbor) - return [] + return [] - def get_path_to_multiple_destinations( - self, from_entity_id: EntityID, destination_entity_ids: set[EntityID] - ) -> list[EntityID]: - return [] + def get_path_to_multiple_destinations( + self, from_entity_id: EntityID, destination_entity_ids: set[EntityID] + ) -> list[EntityID]: + return [] - def heuristic(self, from_entity_id: EntityID, to_entity_id: EntityID) -> float: - # Implement a heuristic function, for example, Euclidean distance - return self._world_info.get_distance(from_entity_id, to_entity_id) + def heuristic(self, from_entity_id: EntityID, to_entity_id: EntityID) -> float: + # Implement a heuristic function, for example, Euclidean distance + return self._world_info.get_distance(from_entity_id, to_entity_id) - def distance(self, from_entity_id: EntityID, to_entity_id: EntityID) -> float: - # Implement a distance function, for example, Euclidean distance - return self._world_info.get_distance(from_entity_id, to_entity_id) + def distance(self, from_entity_id: EntityID, to_entity_id: EntityID) -> float: + # Implement a distance function, for example, Euclidean distance + return self._world_info.get_distance(from_entity_id, to_entity_id) - def reconstruct_path( - self, came_from: dict[EntityID, EntityID], current: EntityID - ) -> list[EntityID]: - total_path = [current] - while current in came_from: - current = came_from[current] - total_path.append(current) - total_path.reverse() - return total_path + def reconstruct_path( + self, came_from: dict[EntityID, EntityID], current: EntityID + ) -> list[EntityID]: + total_path = [current] + while current in came_from: + current = came_from[current] + total_path.append(current) + total_path.reverse() + return total_path - def get_distance(self, from_entity_id: EntityID, to_entity_id: EntityID) -> float: - path: list[EntityID] = self.get_path(from_entity_id, to_entity_id) - distance: float = 0.0 - for i in range(len(path) - 1): - distance += self.distance(path[i], path[i + 1]) - return distance + def get_distance(self, from_entity_id: EntityID, to_entity_id: EntityID) -> float: + path: list[EntityID] = self.get_path(from_entity_id, to_entity_id) + distance: float = 0.0 + for i in range(len(path) - 1): + distance += self.distance(path[i], path[i + 1]) + return distance - def calculate(self) -> AStarPathPlanning: - return self + def calculate(self) -> AStarPathPlanning: + return self diff --git a/src/adf_core_python/implement/module/algorithm/dijkstra_path_planning.py b/src/adf_core_python/implement/module/algorithm/dijkstra_path_planning.py index dac1549..43a0121 100644 --- a/src/adf_core_python/implement/module/algorithm/dijkstra_path_planning.py +++ b/src/adf_core_python/implement/module/algorithm/dijkstra_path_planning.py @@ -14,120 +14,118 @@ class DijkstraPathPlanning(PathPlanning): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + self.graph: dict[EntityID, list[tuple[EntityID, float]]] = {} + # グラフの構築 + for area in self._world_info.get_entities_of_types([Road, Building]): + if not isinstance(area, Area): + continue + if (neighbors := area.get_neighbors()) is None: + continue + area_id = area.get_entity_id() + self.graph[area_id] = [ + ( + neighbor, + self._world_info.get_distance(area_id, entity_id2=neighbor), ) - self.graph: dict[EntityID, list[tuple[EntityID, float]]] = {} - # グラフの構築 - for area in self._world_info.get_entities_of_types([Road, Building]): - if not isinstance(area, Area): - continue - if (neighbors := area.get_neighbors()) is None: - continue - area_id = area.get_entity_id() - self.graph[area_id] = [ - ( - neighbor, - self._world_info.get_distance(area_id, entity_id2=neighbor), - ) - for neighbor in neighbors - if neighbor.get_value() != 0 - ] - - def calculate(self) -> PathPlanning: - return self - - def get_path( - self, from_entity_id: EntityID, to_entity_id: EntityID - ) -> list[EntityID]: - # ダイクストラ法で最短経路を計算 - queue: list[tuple[float, EntityID]] = [] - heapq.heappush(queue, (0, from_entity_id)) - distance: dict[EntityID, float] = {from_entity_id: 0} - previous: dict[EntityID, Optional[EntityID]] = {from_entity_id: None} - - while queue: - current_distance, current_node = heapq.heappop(queue) - if current_node == to_entity_id: - break - - self._logger.info( - f"current_node: {current_node}, current_entity: {self._world_info.get_entity(current_node)}" - ) - - for neighbor, weight in self.graph[current_node]: - new_distance = current_distance + weight - if neighbor not in distance or new_distance < distance[neighbor]: - distance[neighbor] = new_distance - heapq.heappush(queue, (new_distance, neighbor)) - previous[neighbor] = current_node - - path: list[EntityID] = [] - current_path_node: Optional[EntityID] = to_entity_id - while current_path_node is not None: - path.append(current_path_node) - current_path_node = previous.get(current_path_node) - - return path[::-1] - - def get_path_to_multiple_destinations( - self, from_entity_id: EntityID, destination_entity_ids: set[EntityID] - ) -> list[EntityID]: - open_list = [from_entity_id] - ancestors = {from_entity_id: from_entity_id} - found = False - next_node = None - - while open_list and not found: - next_node = open_list.pop(0) - if self.is_goal(next_node, destination_entity_ids): - found = True - break - - neighbors = self.graph.get(next_node, []) - if not neighbors: - continue - - for neighbor, _ in neighbors: - if self.is_goal(neighbor, destination_entity_ids): - ancestors[neighbor] = next_node - next_node = neighbor - found = True - break - elif neighbor not in ancestors: - open_list.append(neighbor) - ancestors[neighbor] = next_node - - if not found: - return [] - - path: list[EntityID] = [] - current = next_node - while current != from_entity_id: - if current is None: - raise RuntimeError( - "Found a node with no ancestor! Something is broken." - ) - path.insert(0, current) - current = ancestors.get(current) - path.insert(0, from_entity_id) - - return path - - def is_goal(self, entity_id: EntityID, target_ids: set[EntityID]) -> bool: - return entity_id in target_ids - - def get_distance(self, from_entity_id: EntityID, to_entity_id: EntityID) -> float: - path = self.get_path(from_entity_id, to_entity_id) - distance = 0.0 - for i in range(len(path) - 1): - distance += self._world_info.get_distance(path[i], path[i + 1]) - return distance + for neighbor in neighbors + if neighbor.get_value() != 0 + ] + + def calculate(self) -> PathPlanning: + return self + + def get_path( + self, from_entity_id: EntityID, to_entity_id: EntityID + ) -> list[EntityID]: + # ダイクストラ法で最短経路を計算 + queue: list[tuple[float, EntityID]] = [] + heapq.heappush(queue, (0, from_entity_id)) + distance: dict[EntityID, float] = {from_entity_id: 0} + previous: dict[EntityID, Optional[EntityID]] = {from_entity_id: None} + + while queue: + current_distance, current_node = heapq.heappop(queue) + if current_node == to_entity_id: + break + + self._logger.info( + f"current_node: {current_node}, current_entity: {self._world_info.get_entity(current_node)}" + ) + + for neighbor, weight in self.graph[current_node]: + new_distance = current_distance + weight + if neighbor not in distance or new_distance < distance[neighbor]: + distance[neighbor] = new_distance + heapq.heappush(queue, (new_distance, neighbor)) + previous[neighbor] = current_node + + path: list[EntityID] = [] + current_path_node: Optional[EntityID] = to_entity_id + while current_path_node is not None: + path.append(current_path_node) + current_path_node = previous.get(current_path_node) + + return path[::-1] + + def get_path_to_multiple_destinations( + self, from_entity_id: EntityID, destination_entity_ids: set[EntityID] + ) -> list[EntityID]: + open_list = [from_entity_id] + ancestors = {from_entity_id: from_entity_id} + found = False + next_node = None + + while open_list and not found: + next_node = open_list.pop(0) + if self.is_goal(next_node, destination_entity_ids): + found = True + break + + neighbors = self.graph.get(next_node, []) + if not neighbors: + continue + + for neighbor, _ in neighbors: + if self.is_goal(neighbor, destination_entity_ids): + ancestors[neighbor] = next_node + next_node = neighbor + found = True + break + elif neighbor not in ancestors: + open_list.append(neighbor) + ancestors[neighbor] = next_node + + if not found: + return [] + + path: list[EntityID] = [] + current = next_node + while current != from_entity_id: + if current is None: + raise RuntimeError("Found a node with no ancestor! Something is broken.") + path.insert(0, current) + current = ancestors.get(current) + path.insert(0, from_entity_id) + + return path + + def is_goal(self, entity_id: EntityID, target_ids: set[EntityID]) -> bool: + return entity_id in target_ids + + def get_distance(self, from_entity_id: EntityID, to_entity_id: EntityID) -> float: + path = self.get_path(from_entity_id, to_entity_id) + distance = 0.0 + for i in range(len(path) - 1): + distance += self._world_info.get_distance(path[i], path[i + 1]) + return distance diff --git a/src/adf_core_python/implement/module/algorithm/k_means_clustering.py b/src/adf_core_python/implement/module/algorithm/k_means_clustering.py index a567abe..3ccdcf0 100644 --- a/src/adf_core_python/implement/module/algorithm/k_means_clustering.py +++ b/src/adf_core_python/implement/module/algorithm/k_means_clustering.py @@ -1,15 +1,15 @@ import numpy as np from rcrscore.entities import ( - AmbulanceCenter, - Building, - Entity, - EntityID, - FireStation, - GasStation, - Hydrant, - PoliceOffice, - Refuge, - Road, + AmbulanceCenter, + Building, + Entity, + EntityID, + FireStation, + GasStation, + Hydrant, + PoliceOffice, + Refuge, + Road, ) from rcrscore.urn import EntityURN from sklearn.cluster import KMeans @@ -24,140 +24,137 @@ class KMeansClustering(Clustering): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + myself = agent_info.get_myself() + if myself is None: + raise RuntimeError("Could not get agent entity") + match myself.get_urn(): + case EntityURN.AMBULANCE_TEAM: + self._cluster_number = int( + scenario_info.get_value( + "scenario.agents.at", + 1, + ) ) - myself = agent_info.get_myself() - if myself is None: - raise RuntimeError("Could not get agent entity") - match myself.get_urn(): - case EntityURN.AMBULANCE_TEAM: - self._cluster_number = int( - scenario_info.get_value( - "scenario.agents.at", - 1, - ) - ) - case EntityURN.POLICE_FORCE: - self._cluster_number = int( - scenario_info.get_value( - "scenario.agents.pf", - 1, - ) - ) - case EntityURN.FIRE_BRIGADE: - self._cluster_number = int( - scenario_info.get_value( - "scenario.agents.fb", - 1, - ) - ) - case _: - self._cluster_number = 1 - - sorted_entities = sorted( - world_info.get_entities_of_types( - [ - myself.__class__, - ] - ), - key=lambda entity: entity.get_entity_id().get_value(), + case EntityURN.POLICE_FORCE: + self._cluster_number = int( + scenario_info.get_value( + "scenario.agents.pf", + 1, + ) ) - self.entity_cluster_indices = { - entity.get_entity_id(): idx for idx, entity in enumerate(sorted_entities) - } - - self.cluster_entities: list[list[Entity]] = [] - self.entities: list[Entity] = world_info.get_entities_of_types( - [ - AmbulanceCenter, - FireStation, - GasStation, - Hydrant, - PoliceOffice, - Refuge, - Road, - Building, - ] + case EntityURN.FIRE_BRIGADE: + self._cluster_number = int( + scenario_info.get_value( + "scenario.agents.fb", + 1, + ) ) + case _: + self._cluster_number = 1 - 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_entity_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"] + sorted_entities = sorted( + world_info.get_entities_of_types( + [ + myself.__class__, ] - return self - - def get_cluster_number(self) -> int: - return self._cluster_number - - def get_cluster_index(self, entity_id: EntityID) -> int: - return self.entity_cluster_indices.get(entity_id, 0) - - def get_cluster_entities(self, cluster_index: int) -> list[Entity]: - if cluster_index >= len(self.cluster_entities): - return [] - return self.cluster_entities[cluster_index] - - def get_cluster_entity_ids(self, cluster_index: int) -> list[EntityID]: - if cluster_index >= len(self.cluster_entities): - return [] - return [ - entity.get_entity_id() for entity in self.cluster_entities[cluster_index] + ), + key=lambda entity: entity.get_entity_id().get_value(), + ) + self.entity_cluster_indices = { + entity.get_entity_id(): idx for idx, entity in enumerate(sorted_entities) + } + + self.cluster_entities: list[list[Entity]] = [] + self.entities: list[Entity] = world_info.get_entities_of_types( + [ + AmbulanceCenter, + FireStation, + GasStation, + Hydrant, + PoliceOffice, + Refuge, + Road, + Building, + ] + ) + + 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_entity_id().get_value() for entity in cluster] + for cluster in cluster_entities ] - - def prepare(self) -> Clustering: - super().prepare() - if self.get_count_prepare() > 1: - return self - self.cluster_entities = self.create_cluster(self._cluster_number, self.entities) - return self - - def create_cluster( - self, cluster_number: int, entities: list[Entity] - ) -> list[list[Entity]]: - kmeans = KMeans(n_clusters=cluster_number, random_state=0) - entity_positions: np.ndarray = np.array([]) - for entity in entities: - location1_x, location1_y = entity.get_location() - if location1_x is None or location1_y is None: - continue - entity_positions = np.append(entity_positions, [location1_x, location1_y]) - - kmeans.fit(entity_positions.reshape(-1, 2)) - - clusters: list[list[Entity]] = [[] for _ in range(cluster_number)] - for entity, label in zip(entities, kmeans.labels_): - clusters[label].append(entity) - - return clusters + }, + 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 + + def get_cluster_index(self, entity_id: EntityID) -> int: + return self.entity_cluster_indices.get(entity_id, 0) + + def get_cluster_entities(self, cluster_index: int) -> list[Entity]: + if cluster_index >= len(self.cluster_entities): + return [] + return self.cluster_entities[cluster_index] + + def get_cluster_entity_ids(self, cluster_index: int) -> list[EntityID]: + if cluster_index >= len(self.cluster_entities): + return [] + return [entity.get_entity_id() for entity in self.cluster_entities[cluster_index]] + + def prepare(self) -> Clustering: + super().prepare() + if self.get_count_prepare() > 1: + return self + self.cluster_entities = self.create_cluster(self._cluster_number, self.entities) + return self + + def create_cluster( + self, cluster_number: int, entities: list[Entity] + ) -> list[list[Entity]]: + kmeans = KMeans(n_clusters=cluster_number, random_state=0) + entity_positions: np.ndarray = np.array([]) + for entity in entities: + location1_x, location1_y = entity.get_location() + if location1_x is None or location1_y is None: + continue + entity_positions = np.append(entity_positions, [location1_x, location1_y]) + + kmeans.fit(entity_positions.reshape(-1, 2)) + + clusters: list[list[Entity]] = [[] for _ in range(cluster_number)] + for entity, label in zip(entities, kmeans.labels_): + clusters[label].append(entity) + + return clusters diff --git a/src/adf_core_python/implement/module/communication/default_channel_subscriber.py b/src/adf_core_python/implement/module/communication/default_channel_subscriber.py index 398b720..c9df4b2 100644 --- a/src/adf_core_python/implement/module/communication/default_channel_subscriber.py +++ b/src/adf_core_python/implement/module/communication/default_channel_subscriber.py @@ -6,96 +6,89 @@ from adf_core_python.core.agent.info.scenario_info import ScenarioInfoKeys from adf_core_python.core.component.communication.channel_subscriber import ( - ChannelSubscriber, + ChannelSubscriber, ) if TYPE_CHECKING: - from adf_core_python.core.agent.info.agent_info import AgentInfo - 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.info.agent_info import AgentInfo + from adf_core_python.core.agent.info.scenario_info import ScenarioInfo + from adf_core_python.core.agent.info.world_info import WorldInfo class DefaultChannelSubscriber(ChannelSubscriber): - def subscribe( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - ) -> list[int]: - agent = world_info.get_entity(agent_info.get_entity_id()) - if agent is None: - return [] - - agent_type = agent.get_urn() - - number_of_channels: int = ( - scenario_info.get_value(ScenarioInfoKeys.COMMUNICATION_CHANNELS_COUNT, 1) - - 1 - ) - - is_platoon: bool = ( - agent_type == EntityURN.FIRE_BRIGADE - or agent_type == EntityURN.POLICE_FORCE - or agent_type == EntityURN.AMBULANCE_TEAM - ) - - max_channel_count: int = ( - scenario_info.get_value( - ScenarioInfoKeys.COMMUNICATION_CHANNELS_MAX_PLATOON, 1 - ) - if is_platoon - else scenario_info.get_value( - ScenarioInfoKeys.COMMUNICATION_CHANNELS_MAX_OFFICE, 1 - ) - ) - - channels = [ - self.get_channel_number(agent_type, i, number_of_channels) - for i in range(max_channel_count) - ] - return channels - - @staticmethod - def get_channel_number( - agent_type: EntityURN, channel_index: int, number_of_channels: int - ) -> int: - agent_index = 0 - if agent_type == EntityURN.FIRE_BRIGADE or agent_type == EntityURN.FIRE_STATION: - agent_index = 1 - elif ( - agent_type == EntityURN.POLICE_FORCE - or agent_type == EntityURN.POLICE_OFFICE - ): - agent_index = 2 - elif ( - agent_type == EntityURN.AMBULANCE_TEAM - or agent_type == EntityURN.AMBULANCE_CENTER - ): - agent_index = 3 - - index = (3 * channel_index) + agent_index - if (index % number_of_channels) == 0: - index = number_of_channels - else: - index = index % number_of_channels - return index + def subscribe( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + ) -> list[int]: + agent = world_info.get_entity(agent_info.get_entity_id()) + if agent is None: + return [] + + agent_type = agent.get_urn() + + number_of_channels: int = ( + scenario_info.get_value(ScenarioInfoKeys.COMMUNICATION_CHANNELS_COUNT, 1) - 1 + ) + + is_platoon: bool = ( + agent_type == EntityURN.FIRE_BRIGADE + or agent_type == EntityURN.POLICE_FORCE + or agent_type == EntityURN.AMBULANCE_TEAM + ) + + max_channel_count: int = ( + scenario_info.get_value(ScenarioInfoKeys.COMMUNICATION_CHANNELS_MAX_PLATOON, 1) + if is_platoon + else scenario_info.get_value( + ScenarioInfoKeys.COMMUNICATION_CHANNELS_MAX_OFFICE, 1 + ) + ) + + channels = [ + self.get_channel_number(agent_type, i, number_of_channels) + for i in range(max_channel_count) + ] + return channels + + @staticmethod + def get_channel_number( + agent_type: EntityURN, channel_index: int, number_of_channels: int + ) -> int: + agent_index = 0 + if agent_type == EntityURN.FIRE_BRIGADE or agent_type == EntityURN.FIRE_STATION: + agent_index = 1 + elif agent_type == EntityURN.POLICE_FORCE or agent_type == EntityURN.POLICE_OFFICE: + agent_index = 2 + elif ( + agent_type == EntityURN.AMBULANCE_TEAM or agent_type == EntityURN.AMBULANCE_CENTER + ): + agent_index = 3 + + index = (3 * channel_index) + agent_index + if (index % number_of_channels) == 0: + index = number_of_channels + else: + index = index % number_of_channels + return index if __name__ == "__main__": - num_channels = 1 - max_channels = 2 - - for i in range(max_channels): - print( - f"FIREBRIGADE-{i}: {DefaultChannelSubscriber.get_channel_number(EntityURN.FIRE_BRIGADE, i, num_channels)}" - ) - - for i in range(max_channels): - print( - f"POLICE-{i}: {DefaultChannelSubscriber.get_channel_number(EntityURN.POLICE_OFFICE, i, num_channels)}" - ) - - for i in range(max_channels): - print( - f"AMB-{i}: {DefaultChannelSubscriber.get_channel_number(EntityURN.AMBULANCE_CENTER, i, num_channels)}" - ) + num_channels = 1 + max_channels = 2 + + for i in range(max_channels): + print( + f"FIREBRIGADE-{i}: {DefaultChannelSubscriber.get_channel_number(EntityURN.FIRE_BRIGADE, i, num_channels)}" + ) + + for i in range(max_channels): + print( + f"POLICE-{i}: {DefaultChannelSubscriber.get_channel_number(EntityURN.POLICE_OFFICE, i, num_channels)}" + ) + + for i in range(max_channels): + print( + f"AMB-{i}: {DefaultChannelSubscriber.get_channel_number(EntityURN.AMBULANCE_CENTER, i, num_channels)}" + ) diff --git a/src/adf_core_python/implement/module/communication/default_message_coordinator.py b/src/adf_core_python/implement/module/communication/default_message_coordinator.py index 28c8490..3428304 100644 --- a/src/adf_core_python/implement/module/communication/default_message_coordinator.py +++ b/src/adf_core_python/implement/module/communication/default_message_coordinator.py @@ -4,242 +4,235 @@ from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.communication.standard.bundle.centralized.command_ambulance import ( - CommandAmbulance, + CommandAmbulance, ) from adf_core_python.core.agent.communication.standard.bundle.centralized.command_fire import ( - CommandFire, + CommandFire, ) from adf_core_python.core.agent.communication.standard.bundle.centralized.command_police import ( - CommandPolice, + CommandPolice, ) from adf_core_python.core.agent.communication.standard.bundle.centralized.command_scout import ( - CommandScout, + CommandScout, ) from adf_core_python.core.agent.communication.standard.bundle.centralized.message_report import ( - MessageReport, + MessageReport, ) from adf_core_python.core.agent.communication.standard.bundle.information.message_ambulance_team import ( - MessageAmbulanceTeam, + MessageAmbulanceTeam, ) from adf_core_python.core.agent.communication.standard.bundle.information.message_building import ( - MessageBuilding, + MessageBuilding, ) from adf_core_python.core.agent.communication.standard.bundle.information.message_civilian import ( - MessageCivilian, + MessageCivilian, ) from adf_core_python.core.agent.communication.standard.bundle.information.message_fire_brigade import ( - MessageFireBrigade, + MessageFireBrigade, ) from adf_core_python.core.agent.communication.standard.bundle.information.message_police_force import ( - MessagePoliceForce, + MessagePoliceForce, ) from adf_core_python.core.agent.communication.standard.bundle.information.message_road import ( - MessageRoad, + MessageRoad, ) from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( - StandardMessage, + StandardMessage, ) from adf_core_python.core.agent.communication.standard.bundle.standard_message_priority import ( - StandardMessagePriority, + StandardMessagePriority, ) from adf_core_python.core.agent.info.agent_info import AgentInfo from adf_core_python.core.agent.info.scenario_info import ScenarioInfo, ScenarioInfoKeys from adf_core_python.core.agent.info.world_info import WorldInfo from adf_core_python.core.component.communication.communication_message import ( - CommunicationMessage, + CommunicationMessage, ) from adf_core_python.core.component.communication.message_coordinator import ( - MessageCoordinator, + MessageCoordinator, ) from adf_core_python.implement.module.communication.default_channel_subscriber import ( - DefaultChannelSubscriber, + DefaultChannelSubscriber, ) class DefaultMessageCoordinator(MessageCoordinator): - def coordinate( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - message_manager: MessageManager, - send_message_list: list[CommunicationMessage], - channel_send_message_list: list[list[CommunicationMessage]], - ) -> None: - police_messages: list[StandardMessage] = [] - ambulance_messages: list[StandardMessage] = [] - fire_brigade_messages: list[StandardMessage] = [] - voice_messages: list[StandardMessage] = [] - - agent_type = self.get_agent_type(agent_info, world_info) - - for msg in send_message_list: - if isinstance(msg, StandardMessage) and not msg.is_wireless_message(): - voice_messages.append(msg) - else: - if isinstance(msg, MessageBuilding): - fire_brigade_messages.append(msg) - elif isinstance(msg, MessageCivilian): - ambulance_messages.append(msg) - elif isinstance(msg, MessageRoad): - fire_brigade_messages.append(msg) - ambulance_messages.append(msg) - police_messages.append(msg) - elif isinstance(msg, CommandAmbulance): - ambulance_messages.append(msg) - elif isinstance(msg, CommandFire): - fire_brigade_messages.append(msg) - elif isinstance(msg, CommandPolice): - police_messages.append(msg) - elif isinstance(msg, CommandScout): - if agent_type == EntityURN.FIRE_STATION: - fire_brigade_messages.append(msg) - elif agent_type == EntityURN.POLICE_OFFICE: - police_messages.append(msg) - elif agent_type == EntityURN.AMBULANCE_CENTER: - ambulance_messages.append(msg) - elif isinstance(msg, MessageReport): - if agent_type == EntityURN.FIRE_BRIGADE: - fire_brigade_messages.append(msg) - elif agent_type == EntityURN.POLICE_FORCE: - police_messages.append(msg) - elif agent_type == EntityURN.AMBULANCE_TEAM: - ambulance_messages.append(msg) - elif isinstance(msg, MessageFireBrigade): - fire_brigade_messages.append(msg) - ambulance_messages.append(msg) - police_messages.append(msg) - elif isinstance(msg, MessagePoliceForce): - ambulance_messages.append(msg) - police_messages.append(msg) - elif isinstance(msg, MessageAmbulanceTeam): - ambulance_messages.append(msg) - police_messages.append(msg) - - if int(scenario_info.get_value("comms.channels.count", 1)) > 1: - channel_size = [0] * ( - int(scenario_info.get_value("comms.channels.count", 1)) - ) - self.set_send_messages( - scenario_info, - EntityURN.POLICE_FORCE, - agent_info, - world_info, - police_messages, - channel_send_message_list, - channel_size, - ) - self.set_send_messages( - scenario_info, - EntityURN.AMBULANCE_TEAM, - agent_info, - world_info, - ambulance_messages, - channel_send_message_list, - channel_size, - ) - self.set_send_messages( - scenario_info, - EntityURN.FIRE_BRIGADE, - agent_info, - world_info, - fire_brigade_messages, - channel_send_message_list, - channel_size, - ) - - voice_message_low_list = [] - voice_message_normal_list = [] - voice_message_high_list = [] - - for msg in voice_messages: - if isinstance(msg, StandardMessage): - if msg.get_priority() == StandardMessagePriority.LOW: - voice_message_low_list.append(msg) - elif msg.get_priority() == StandardMessagePriority.NORMAL: - voice_message_normal_list.append(msg) - elif msg.get_priority() == StandardMessagePriority.HIGH: - voice_message_high_list.append(msg) - - channel_send_message_list[0].extend(voice_message_high_list) - channel_send_message_list[0].extend(voice_message_normal_list) - channel_send_message_list[0].extend(voice_message_low_list) - - def get_channels_by_agent_type( - self, - agent_type: EntityURN, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - ) -> list[int]: - num_channels = ( - scenario_info.get_value(ScenarioInfoKeys.COMMUNICATION_CHANNELS_COUNT, 1) - - 1 - ) - max_channel_count = int( - # scenario_info.get_comms_channels_max_platoon() - scenario_info.get_value( - ScenarioInfoKeys.COMMUNICATION_CHANNELS_MAX_PLATOON, 1 - ) - if self.is_platoon_agent(agent_info, world_info) - else scenario_info.get_value( - ScenarioInfoKeys.COMMUNICATION_CHANNELS_MAX_OFFICE, 1 - ) - ) - channels = [ - DefaultChannelSubscriber.get_channel_number(agent_type, i, num_channels) - for i in range(max_channel_count) - ] - return channels - - def is_platoon_agent(self, agent_info: AgentInfo, world_info: WorldInfo) -> bool: - agent_type = self.get_agent_type(agent_info, world_info) - return agent_type in [ - EntityURN.FIRE_BRIGADE, - EntityURN.POLICE_FORCE, - EntityURN.AMBULANCE_TEAM, - ] - - def get_agent_type( - self, agent_info: AgentInfo, world_info: WorldInfo - ) -> Optional[EntityURN]: - entity = world_info.get_entity(agent_info.get_entity_id()) - if entity is None: - return None - return entity.get_urn() - - def set_send_messages( - self, - scenario_info: ScenarioInfo, - agent_type: EntityURN, - agent_info: AgentInfo, - world_info: WorldInfo, - messages: list[StandardMessage], - channel_send_message_list: list[list[CommunicationMessage]], - channel_size: list[int], - ) -> None: - channels = self.get_channels_by_agent_type( - agent_type, agent_info, world_info, scenario_info - ) - channel_capacities = [ - scenario_info.get_value("comms.channels." + str(channel) + ".bandwidth", 0) - for channel in range( - scenario_info.get_value( - ScenarioInfoKeys.COMMUNICATION_CHANNELS_COUNT, 1 - ) - ) - ] - - sorted_messages = sorted( - messages, key=lambda x: x.get_priority().value, reverse=True - ) - - for message in sorted_messages: - for channel in channels: - if message not in channel_send_message_list[channel] and ( - (channel_size[channel] + message.get_bit_size()) - <= channel_capacities[channel] - ): - channel_size[channel] += message.get_bit_size() - channel_send_message_list[channel].append(message) - break + def coordinate( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + message_manager: MessageManager, + send_message_list: list[CommunicationMessage], + channel_send_message_list: list[list[CommunicationMessage]], + ) -> None: + police_messages: list[StandardMessage] = [] + ambulance_messages: list[StandardMessage] = [] + fire_brigade_messages: list[StandardMessage] = [] + voice_messages: list[StandardMessage] = [] + + agent_type = self.get_agent_type(agent_info, world_info) + + for msg in send_message_list: + if isinstance(msg, StandardMessage) and not msg.is_wireless_message(): + voice_messages.append(msg) + else: + if isinstance(msg, MessageBuilding): + fire_brigade_messages.append(msg) + elif isinstance(msg, MessageCivilian): + ambulance_messages.append(msg) + elif isinstance(msg, MessageRoad): + fire_brigade_messages.append(msg) + ambulance_messages.append(msg) + police_messages.append(msg) + elif isinstance(msg, CommandAmbulance): + ambulance_messages.append(msg) + elif isinstance(msg, CommandFire): + fire_brigade_messages.append(msg) + elif isinstance(msg, CommandPolice): + police_messages.append(msg) + elif isinstance(msg, CommandScout): + if agent_type == EntityURN.FIRE_STATION: + fire_brigade_messages.append(msg) + elif agent_type == EntityURN.POLICE_OFFICE: + police_messages.append(msg) + elif agent_type == EntityURN.AMBULANCE_CENTER: + ambulance_messages.append(msg) + elif isinstance(msg, MessageReport): + if agent_type == EntityURN.FIRE_BRIGADE: + fire_brigade_messages.append(msg) + elif agent_type == EntityURN.POLICE_FORCE: + police_messages.append(msg) + elif agent_type == EntityURN.AMBULANCE_TEAM: + ambulance_messages.append(msg) + elif isinstance(msg, MessageFireBrigade): + fire_brigade_messages.append(msg) + ambulance_messages.append(msg) + police_messages.append(msg) + elif isinstance(msg, MessagePoliceForce): + ambulance_messages.append(msg) + police_messages.append(msg) + elif isinstance(msg, MessageAmbulanceTeam): + ambulance_messages.append(msg) + police_messages.append(msg) + + if int(scenario_info.get_value("comms.channels.count", 1)) > 1: + channel_size = [0] * (int(scenario_info.get_value("comms.channels.count", 1))) + self.set_send_messages( + scenario_info, + EntityURN.POLICE_FORCE, + agent_info, + world_info, + police_messages, + channel_send_message_list, + channel_size, + ) + self.set_send_messages( + scenario_info, + EntityURN.AMBULANCE_TEAM, + agent_info, + world_info, + ambulance_messages, + channel_send_message_list, + channel_size, + ) + self.set_send_messages( + scenario_info, + EntityURN.FIRE_BRIGADE, + agent_info, + world_info, + fire_brigade_messages, + channel_send_message_list, + channel_size, + ) + + voice_message_low_list = [] + voice_message_normal_list = [] + voice_message_high_list = [] + + for msg in voice_messages: + if isinstance(msg, StandardMessage): + if msg.get_priority() == StandardMessagePriority.LOW: + voice_message_low_list.append(msg) + elif msg.get_priority() == StandardMessagePriority.NORMAL: + voice_message_normal_list.append(msg) + elif msg.get_priority() == StandardMessagePriority.HIGH: + voice_message_high_list.append(msg) + + channel_send_message_list[0].extend(voice_message_high_list) + channel_send_message_list[0].extend(voice_message_normal_list) + channel_send_message_list[0].extend(voice_message_low_list) + + def get_channels_by_agent_type( + self, + agent_type: EntityURN, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + ) -> list[int]: + num_channels = ( + scenario_info.get_value(ScenarioInfoKeys.COMMUNICATION_CHANNELS_COUNT, 1) - 1 + ) + max_channel_count = int( + # scenario_info.get_comms_channels_max_platoon() + scenario_info.get_value(ScenarioInfoKeys.COMMUNICATION_CHANNELS_MAX_PLATOON, 1) + if self.is_platoon_agent(agent_info, world_info) + else scenario_info.get_value( + ScenarioInfoKeys.COMMUNICATION_CHANNELS_MAX_OFFICE, 1 + ) + ) + channels = [ + DefaultChannelSubscriber.get_channel_number(agent_type, i, num_channels) + for i in range(max_channel_count) + ] + return channels + + def is_platoon_agent(self, agent_info: AgentInfo, world_info: WorldInfo) -> bool: + agent_type = self.get_agent_type(agent_info, world_info) + return agent_type in [ + EntityURN.FIRE_BRIGADE, + EntityURN.POLICE_FORCE, + EntityURN.AMBULANCE_TEAM, + ] + + def get_agent_type( + self, agent_info: AgentInfo, world_info: WorldInfo + ) -> Optional[EntityURN]: + entity = world_info.get_entity(agent_info.get_entity_id()) + if entity is None: + return None + return entity.get_urn() + + def set_send_messages( + self, + scenario_info: ScenarioInfo, + agent_type: EntityURN, + agent_info: AgentInfo, + world_info: WorldInfo, + messages: list[StandardMessage], + channel_send_message_list: list[list[CommunicationMessage]], + channel_size: list[int], + ) -> None: + channels = self.get_channels_by_agent_type( + agent_type, agent_info, world_info, scenario_info + ) + channel_capacities = [ + scenario_info.get_value("comms.channels." + str(channel) + ".bandwidth", 0) + for channel in range( + scenario_info.get_value(ScenarioInfoKeys.COMMUNICATION_CHANNELS_COUNT, 1) + ) + ] + + sorted_messages = sorted( + messages, key=lambda x: x.get_priority().value, reverse=True + ) + + for message in sorted_messages: + for channel in channels: + if message not in channel_send_message_list[channel] and ( + (channel_size[channel] + message.get_bit_size()) + <= channel_capacities[channel] + ): + channel_size[channel] += message.get_bit_size() + channel_send_message_list[channel].append(message) + break diff --git a/src/adf_core_python/implement/module/complex/default_ambulance_target_allocator.py b/src/adf_core_python/implement/module/complex/default_ambulance_target_allocator.py index bdeb89a..599a75c 100644 --- a/src/adf_core_python/implement/module/complex/default_ambulance_target_allocator.py +++ b/src/adf_core_python/implement/module/complex/default_ambulance_target_allocator.py @@ -11,143 +11,143 @@ 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.complex.ambulance_target_allocator import ( - AmbulanceTargetAllocator, + AmbulanceTargetAllocator, ) class DefaultAmbulanceTargetAllocator(AmbulanceTargetAllocator): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - self._priority_humans: set[EntityID] = set() - self._target_humans: set[EntityID] = set() - self._ambulance_team_info_map: dict[ - EntityID, DefaultAmbulanceTargetAllocator.AmbulanceTeamInfo - ] = {} - - def resume(self, precompute_data: PrecomputeData) -> AmbulanceTargetAllocator: - super().resume(precompute_data) - if self.get_count_resume() >= 2: - return self - for entity_id in self._world_info.get_entity_ids_of_types([AmbulanceTeam]): - self._ambulance_team_info_map[entity_id] = self.AmbulanceTeamInfo(entity_id) - return self - - def prepare(self) -> AmbulanceTargetAllocator: - super().prepare() - if self.get_count_prepare() >= 2: - return self - for entity_id in self._world_info.get_entity_ids_of_types([AmbulanceTeam]): - self._ambulance_team_info_map[entity_id] = self.AmbulanceTeamInfo(entity_id) - return self - - def update_info(self, message_manager: MessageManager) -> AmbulanceTargetAllocator: - super().update_info(message_manager) - # TODO: implement after message_manager is implemented - return self - - def calculate(self) -> AmbulanceTargetAllocator: - agents = self._get_action_agents(self._ambulance_team_info_map) - removes = [] - current_time = self._agent_info.get_time() - - for target in self._priority_humans: - if len(agents) > 0: - target_entity = self._world_info.get_entity(target) - if target_entity is not None and isinstance(target_entity, Human): - agents = sorted( - agents, key=cmp_to_key(self._compare_by_distance(target_entity)) - ) - result = agents.pop(0) - info = self._ambulance_team_info_map[result.get_entity_id()] - if info is not None: - info._can_new_action = False - info._target = target - info.command_time = current_time - self._ambulance_team_info_map[result.get_entity_id()] = info - removes.append(target) - - for r in removes: - self._priority_humans.remove(r) - removes.clear() - - for target in self._target_humans: - if len(agents) > 0: - target_entity = self._world_info.get_entity(target) - if target_entity is not None and isinstance(target_entity, Human): - agents = sorted( - agents, key=cmp_to_key(self._compare_by_distance(target_entity)) - ) - result = agents.pop(0) - info = self._ambulance_team_info_map[result.get_entity_id()] - if info is not None: - info._can_new_action = False - info._target = target - info.command_time = current_time - self._ambulance_team_info_map[result.get_entity_id()] = info - removes.append(target) - - for r in removes: - self._target_humans.remove(r) - - return self - - def get_result(self) -> dict[EntityID, EntityID]: - return self._convert(self._ambulance_team_info_map) - - def _get_action_agents( - self, - info_map: dict[EntityID, "DefaultAmbulanceTargetAllocator.AmbulanceTeamInfo"], - ) -> list[AmbulanceTeam]: - result = [] - for entity in self._world_info.get_entities_of_types([AmbulanceTeam]): - if isinstance(entity, AmbulanceTeam): - info = info_map[entity.get_entity_id()] - if info is not None and info._can_new_action: - result.append(entity) - return result - - def _compare_by_distance( - self, target_entity: Entity - ) -> Callable[[Entity, Entity], int]: - def _cmp_func(entity_a: Entity, entity_b: Entity) -> int: - distance_a = self._world_info.get_distance( - target_entity.get_entity_id(), entity_a.get_entity_id() - ) - distance_b = self._world_info.get_distance( - target_entity.get_entity_id(), entity_b.get_entity_id() - ) - if distance_a < distance_b: - return -1 - elif distance_a > distance_b: - return 1 - else: - return 0 - - return _cmp_func - - def _convert( - self, - info_map: dict[EntityID, "DefaultAmbulanceTargetAllocator.AmbulanceTeamInfo"], - ) -> dict[EntityID, EntityID]: - result = {} - for entity_id in info_map.keys(): - info = info_map[entity_id] - if info is not None and info._target is not None: - result[entity_id] = info._target - return result - - class AmbulanceTeamInfo: - def __init__(self, entity_id: EntityID) -> None: - self._agent_id: EntityID = entity_id - self._target: Optional[EntityID] = None - self._can_new_action: bool = True - self.command_time: int = -1 + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + self._priority_humans: set[EntityID] = set() + self._target_humans: set[EntityID] = set() + self._ambulance_team_info_map: dict[ + EntityID, DefaultAmbulanceTargetAllocator.AmbulanceTeamInfo + ] = {} + + def resume(self, precompute_data: PrecomputeData) -> AmbulanceTargetAllocator: + super().resume(precompute_data) + if self.get_count_resume() >= 2: + return self + for entity_id in self._world_info.get_entity_ids_of_types([AmbulanceTeam]): + self._ambulance_team_info_map[entity_id] = self.AmbulanceTeamInfo(entity_id) + return self + + def prepare(self) -> AmbulanceTargetAllocator: + super().prepare() + if self.get_count_prepare() >= 2: + return self + for entity_id in self._world_info.get_entity_ids_of_types([AmbulanceTeam]): + self._ambulance_team_info_map[entity_id] = self.AmbulanceTeamInfo(entity_id) + return self + + def update_info(self, message_manager: MessageManager) -> AmbulanceTargetAllocator: + super().update_info(message_manager) + # TODO: implement after message_manager is implemented + return self + + def calculate(self) -> AmbulanceTargetAllocator: + agents = self._get_action_agents(self._ambulance_team_info_map) + removes = [] + current_time = self._agent_info.get_time() + + for target in self._priority_humans: + if len(agents) > 0: + target_entity = self._world_info.get_entity(target) + if target_entity is not None and isinstance(target_entity, Human): + agents = sorted( + agents, key=cmp_to_key(self._compare_by_distance(target_entity)) + ) + result = agents.pop(0) + info = self._ambulance_team_info_map[result.get_entity_id()] + if info is not None: + info._can_new_action = False + info._target = target + info.command_time = current_time + self._ambulance_team_info_map[result.get_entity_id()] = info + removes.append(target) + + for r in removes: + self._priority_humans.remove(r) + removes.clear() + + for target in self._target_humans: + if len(agents) > 0: + target_entity = self._world_info.get_entity(target) + if target_entity is not None and isinstance(target_entity, Human): + agents = sorted( + agents, key=cmp_to_key(self._compare_by_distance(target_entity)) + ) + result = agents.pop(0) + info = self._ambulance_team_info_map[result.get_entity_id()] + if info is not None: + info._can_new_action = False + info._target = target + info.command_time = current_time + self._ambulance_team_info_map[result.get_entity_id()] = info + removes.append(target) + + for r in removes: + self._target_humans.remove(r) + + return self + + def get_result(self) -> dict[EntityID, EntityID]: + return self._convert(self._ambulance_team_info_map) + + def _get_action_agents( + self, + info_map: dict[EntityID, "DefaultAmbulanceTargetAllocator.AmbulanceTeamInfo"], + ) -> list[AmbulanceTeam]: + result = [] + for entity in self._world_info.get_entities_of_types([AmbulanceTeam]): + if isinstance(entity, AmbulanceTeam): + info = info_map[entity.get_entity_id()] + if info is not None and info._can_new_action: + result.append(entity) + return result + + def _compare_by_distance( + self, target_entity: Entity + ) -> Callable[[Entity, Entity], int]: + def _cmp_func(entity_a: Entity, entity_b: Entity) -> int: + distance_a = self._world_info.get_distance( + target_entity.get_entity_id(), entity_a.get_entity_id() + ) + distance_b = self._world_info.get_distance( + target_entity.get_entity_id(), entity_b.get_entity_id() + ) + if distance_a < distance_b: + return -1 + elif distance_a > distance_b: + return 1 + else: + return 0 + + return _cmp_func + + def _convert( + self, + info_map: dict[EntityID, "DefaultAmbulanceTargetAllocator.AmbulanceTeamInfo"], + ) -> dict[EntityID, EntityID]: + result = {} + for entity_id in info_map.keys(): + info = info_map[entity_id] + if info is not None and info._target is not None: + result[entity_id] = info._target + return result + + class AmbulanceTeamInfo: + def __init__(self, entity_id: EntityID) -> None: + self._agent_id: EntityID = entity_id + self._target: Optional[EntityID] = None + self._can_new_action: bool = True + self.command_time: int = -1 diff --git a/src/adf_core_python/implement/module/complex/default_fire_target_allocator.py b/src/adf_core_python/implement/module/complex/default_fire_target_allocator.py index 4373d5d..b4b3a2e 100644 --- a/src/adf_core_python/implement/module/complex/default_fire_target_allocator.py +++ b/src/adf_core_python/implement/module/complex/default_fire_target_allocator.py @@ -11,141 +11,141 @@ 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.complex.fire_target_allocator import ( - FireTargetAllocator, + FireTargetAllocator, ) class DefaultFireTargetAllocator(FireTargetAllocator): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - self._priority_humans: set[EntityID] = set() - self._target_humans: set[EntityID] = set() - self._fire_brigade_info_map: dict[ - EntityID, DefaultFireTargetAllocator.FireBrigadeInfo - ] = {} - - def resume(self, precompute_data: PrecomputeData) -> FireTargetAllocator: - super().resume(precompute_data) - if self.get_count_resume() >= 2: - return self - for entity_id in self._world_info.get_entity_ids_of_types([FireBrigade]): - self._fire_brigade_info_map[entity_id] = self.FireBrigadeInfo(entity_id) - return self - - def prepare(self) -> FireTargetAllocator: - super().prepare() - if self.get_count_prepare() >= 2: - return self - for entity_id in self._world_info.get_entity_ids_of_types([FireBrigade]): - self._fire_brigade_info_map[entity_id] = self.FireBrigadeInfo(entity_id) - return self - - def update_info(self, message_manager: MessageManager) -> FireTargetAllocator: - super().update_info(message_manager) - # TODO: implement after message_manager is implemented - return self - - def calculate(self) -> FireTargetAllocator: - agents = self._get_action_agents(self._fire_brigade_info_map) - removes = [] - current_time = self._agent_info.get_time() - - for target in self._priority_humans: - if len(agents) > 0: - target_entity = self._world_info.get_entity(target) - if target_entity is not None and isinstance(target_entity, Human): - agents = sorted( - agents, key=cmp_to_key(self._compare_by_distance(target_entity)) - ) - result = agents.pop(0) - info = self._fire_brigade_info_map[result.get_entity_id()] - if info is not None: - info._can_new_action = False - info._target = target - info.command_time = current_time - self._fire_brigade_info_map[result.get_entity_id()] = info - removes.append(target) - - for r in removes: - self._priority_humans.remove(r) - removes.clear() - - for target in self._target_humans: - if len(agents) > 0: - target_entity = self._world_info.get_entity(target) - if target_entity is not None and isinstance(target_entity, Human): - agents = sorted( - agents, key=cmp_to_key(self._compare_by_distance(target_entity)) - ) - result = agents.pop(0) - info = self._fire_brigade_info_map[result.get_entity_id()] - if info is not None: - info._can_new_action = False - info._target = target - info.command_time = current_time - self._fire_brigade_info_map[result.get_entity_id()] = info - removes.append(target) - - for r in removes: - self._target_humans.remove(r) - - return self - - def get_result(self) -> dict[EntityID, EntityID]: - return self._convert(self._fire_brigade_info_map) - - def _get_action_agents( - self, info_map: dict[EntityID, "DefaultFireTargetAllocator.FireBrigadeInfo"] - ) -> list[FireBrigade]: - result = [] - for entity in self._world_info.get_entities_of_types([FireBrigade]): - if isinstance(entity, FireBrigade): - info = info_map[entity.get_entity_id()] - if info is not None and info._can_new_action: - result.append(entity) - return result - - def _compare_by_distance( - self, target_entity: Entity - ) -> Callable[[Entity, Entity], int]: - def _cmp_func(entity_a: Entity, entity_b: Entity) -> int: - distance_a = self._world_info.get_distance( - target_entity.get_entity_id(), entity_a.get_entity_id() - ) - distance_b = self._world_info.get_distance( - target_entity.get_entity_id(), entity_b.get_entity_id() - ) - if distance_a < distance_b: - return -1 - elif distance_a > distance_b: - return 1 - else: - return 0 - - return _cmp_func - - def _convert( - self, info_map: dict[EntityID, "DefaultFireTargetAllocator.FireBrigadeInfo"] - ) -> dict[EntityID, EntityID]: - result = {} - for entity_id in info_map.keys(): - info = info_map[entity_id] - if info is not None and info._target is not None: - result[entity_id] = info._target - return result - - class FireBrigadeInfo: - def __init__(self, entity_id: EntityID) -> None: - self._agent_id: EntityID = entity_id - self._target: Optional[EntityID] = None - self._can_new_action: bool = True - self.command_time: int = -1 + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + self._priority_humans: set[EntityID] = set() + self._target_humans: set[EntityID] = set() + self._fire_brigade_info_map: dict[ + EntityID, DefaultFireTargetAllocator.FireBrigadeInfo + ] = {} + + def resume(self, precompute_data: PrecomputeData) -> FireTargetAllocator: + super().resume(precompute_data) + if self.get_count_resume() >= 2: + return self + for entity_id in self._world_info.get_entity_ids_of_types([FireBrigade]): + self._fire_brigade_info_map[entity_id] = self.FireBrigadeInfo(entity_id) + return self + + def prepare(self) -> FireTargetAllocator: + super().prepare() + if self.get_count_prepare() >= 2: + return self + for entity_id in self._world_info.get_entity_ids_of_types([FireBrigade]): + self._fire_brigade_info_map[entity_id] = self.FireBrigadeInfo(entity_id) + return self + + def update_info(self, message_manager: MessageManager) -> FireTargetAllocator: + super().update_info(message_manager) + # TODO: implement after message_manager is implemented + return self + + def calculate(self) -> FireTargetAllocator: + agents = self._get_action_agents(self._fire_brigade_info_map) + removes = [] + current_time = self._agent_info.get_time() + + for target in self._priority_humans: + if len(agents) > 0: + target_entity = self._world_info.get_entity(target) + if target_entity is not None and isinstance(target_entity, Human): + agents = sorted( + agents, key=cmp_to_key(self._compare_by_distance(target_entity)) + ) + result = agents.pop(0) + info = self._fire_brigade_info_map[result.get_entity_id()] + if info is not None: + info._can_new_action = False + info._target = target + info.command_time = current_time + self._fire_brigade_info_map[result.get_entity_id()] = info + removes.append(target) + + for r in removes: + self._priority_humans.remove(r) + removes.clear() + + for target in self._target_humans: + if len(agents) > 0: + target_entity = self._world_info.get_entity(target) + if target_entity is not None and isinstance(target_entity, Human): + agents = sorted( + agents, key=cmp_to_key(self._compare_by_distance(target_entity)) + ) + result = agents.pop(0) + info = self._fire_brigade_info_map[result.get_entity_id()] + if info is not None: + info._can_new_action = False + info._target = target + info.command_time = current_time + self._fire_brigade_info_map[result.get_entity_id()] = info + removes.append(target) + + for r in removes: + self._target_humans.remove(r) + + return self + + def get_result(self) -> dict[EntityID, EntityID]: + return self._convert(self._fire_brigade_info_map) + + def _get_action_agents( + self, info_map: dict[EntityID, "DefaultFireTargetAllocator.FireBrigadeInfo"] + ) -> list[FireBrigade]: + result = [] + for entity in self._world_info.get_entities_of_types([FireBrigade]): + if isinstance(entity, FireBrigade): + info = info_map[entity.get_entity_id()] + if info is not None and info._can_new_action: + result.append(entity) + return result + + def _compare_by_distance( + self, target_entity: Entity + ) -> Callable[[Entity, Entity], int]: + def _cmp_func(entity_a: Entity, entity_b: Entity) -> int: + distance_a = self._world_info.get_distance( + target_entity.get_entity_id(), entity_a.get_entity_id() + ) + distance_b = self._world_info.get_distance( + target_entity.get_entity_id(), entity_b.get_entity_id() + ) + if distance_a < distance_b: + return -1 + elif distance_a > distance_b: + return 1 + else: + return 0 + + return _cmp_func + + def _convert( + self, info_map: dict[EntityID, "DefaultFireTargetAllocator.FireBrigadeInfo"] + ) -> dict[EntityID, EntityID]: + result = {} + for entity_id in info_map.keys(): + info = info_map[entity_id] + if info is not None and info._target is not None: + result[entity_id] = info._target + return result + + class FireBrigadeInfo: + def __init__(self, entity_id: EntityID) -> None: + self._agent_id: EntityID = entity_id + self._target: Optional[EntityID] = None + self._can_new_action: bool = True + self.command_time: int = -1 diff --git a/src/adf_core_python/implement/module/complex/default_human_detector.py b/src/adf_core_python/implement/module/complex/default_human_detector.py index 8f5e860..56d64a7 100644 --- a/src/adf_core_python/implement/module/complex/default_human_detector.py +++ b/src/adf_core_python/implement/module/complex/default_human_detector.py @@ -14,136 +14,135 @@ class DefaultHumanDetector(HumanDetector): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + self._clustering: Clustering = cast( + Clustering, + module_manager.get_module( + "DefaultHumanDetector.Clustering", + "adf_core_python.implement.module.algorithm.k_means_clustering.KMeansClustering", + ), + ) + self.register_sub_module(self._clustering) + + self._result: Optional[EntityID] = None + self._logger = get_agent_logger( + f"{self.__class__.__module__}.{self.__class__.__qualname__}", + self._agent_info, + ) + + def calculate(self) -> HumanDetector: + transport_human: Optional[Human] = self._agent_info.some_one_on_board() + if transport_human is not None: + self._result = transport_human.get_entity_id() + return self + + if self._result is not None: + if not self._is_valid_human(self._result): + self._result = None + + if self._result is None: + self._result = self._select_target() + + return self + + def _select_target(self) -> Optional[EntityID]: + if self._result is not None and self._is_valid_human(self._result): + return self._result + + cluster_index: int = self._clustering.get_cluster_index( + self._agent_info.get_entity_id() + ) + cluster_entities: list[Entity] = self._clustering.get_cluster_entities( + cluster_index + ) + + cluster_valid_human_entities: list[Entity] = [ + entity + for entity in cluster_entities + if self._is_valid_human(entity.get_entity_id()) and isinstance(entity, Civilian) + ] + if len(cluster_valid_human_entities) != 0: + nearest_human_entity = cluster_valid_human_entities[0] + nearest_distance = self._world_info.get_distance( + self._agent_info.get_entity_id(), + nearest_human_entity.get_entity_id(), + ) + for entity in cluster_valid_human_entities: + distance = self._world_info.get_distance( + self._agent_info.get_entity_id(), + entity.get_entity_id(), ) - self._clustering: Clustering = cast( - Clustering, - module_manager.get_module( - "DefaultHumanDetector.Clustering", - "adf_core_python.implement.module.algorithm.k_means_clustering.KMeansClustering", - ), + if distance < nearest_distance: + nearest_distance = distance + nearest_human_entity = entity + return nearest_human_entity.get_entity_id() + + world_valid_human_entities: list[Entity] = [ + entity + for entity in self._world_info.get_entities_of_types([Civilian]) + if self._is_valid_human(entity.get_entity_id()) + ] + if len(world_valid_human_entities) != 0: + nearest_human_entity = world_valid_human_entities[0] + nearest_distance = self._world_info.get_distance( + self._agent_info.get_entity_id(), + nearest_human_entity.get_entity_id(), + ) + for entity in world_valid_human_entities: + distance = self._world_info.get_distance( + self._agent_info.get_entity_id(), + entity.get_entity_id(), ) - self.register_sub_module(self._clustering) - - self._result: Optional[EntityID] = None - self._logger = get_agent_logger( - f"{self.__class__.__module__}.{self.__class__.__qualname__}", - self._agent_info, - ) - - def calculate(self) -> HumanDetector: - transport_human: Optional[Human] = self._agent_info.some_one_on_board() - if transport_human is not None: - self._result = transport_human.get_entity_id() - return self - - if self._result is not None: - if not self._is_valid_human(self._result): - self._result = None - - if self._result is None: - self._result = self._select_target() - - return self - - def _select_target(self) -> Optional[EntityID]: - if self._result is not None and self._is_valid_human(self._result): - return self._result - - cluster_index: int = self._clustering.get_cluster_index( - self._agent_info.get_entity_id() - ) - cluster_entities: list[Entity] = self._clustering.get_cluster_entities( - cluster_index - ) - - cluster_valid_human_entities: list[Entity] = [ - entity - for entity in cluster_entities - if self._is_valid_human(entity.get_entity_id()) - and isinstance(entity, Civilian) - ] - if len(cluster_valid_human_entities) != 0: - nearest_human_entity = cluster_valid_human_entities[0] - nearest_distance = self._world_info.get_distance( - self._agent_info.get_entity_id(), - nearest_human_entity.get_entity_id(), - ) - for entity in cluster_valid_human_entities: - distance = self._world_info.get_distance( - self._agent_info.get_entity_id(), - entity.get_entity_id(), - ) - if distance < nearest_distance: - nearest_distance = distance - nearest_human_entity = entity - return nearest_human_entity.get_entity_id() - - world_valid_human_entities: list[Entity] = [ - entity - for entity in self._world_info.get_entities_of_types([Civilian]) - if self._is_valid_human(entity.get_entity_id()) - ] - if len(world_valid_human_entities) != 0: - nearest_human_entity = world_valid_human_entities[0] - nearest_distance = self._world_info.get_distance( - self._agent_info.get_entity_id(), - nearest_human_entity.get_entity_id(), - ) - for entity in world_valid_human_entities: - distance = self._world_info.get_distance( - self._agent_info.get_entity_id(), - entity.get_entity_id(), - ) - if distance < nearest_distance: - nearest_distance = distance - nearest_human_entity = entity - return nearest_human_entity.get_entity_id() - - return None - - def _is_valid_human(self, target_entity_id: EntityID) -> bool: - target: Optional[Entity] = self._world_info.get_entity(target_entity_id) - if target is None: - return False - if not isinstance(target, Human): - return False - hp: Optional[int] = target.get_hp() - if hp is None or hp <= 0: - return False - buriedness: Optional[int] = target.get_buriedness() - if buriedness is None: - return False - myself = self._agent_info.get_myself() - if myself is None: - return False - if myself.get_urn() == EntityURN.FIRE_BRIGADE and buriedness == 0: - return False - if myself.get_urn() == EntityURN.AMBULANCE_TEAM and buriedness > 0: - return False - damage: Optional[int] = target.get_damage() - if damage is None or damage == 0: - return False - position_entity_id: Optional[EntityID] = target.get_position() - if position_entity_id is None: - return False - position: Optional[Entity] = self._world_info.get_entity(position_entity_id) - if position is None: - return False - urn: EntityURN = position.get_urn() - if urn == EntityURN.REFUGE or urn == EntityURN.AMBULANCE_TEAM: - return False - - return True - - def get_target_entity_id(self) -> Optional[EntityID]: - return self._result + if distance < nearest_distance: + nearest_distance = distance + nearest_human_entity = entity + return nearest_human_entity.get_entity_id() + + return None + + def _is_valid_human(self, target_entity_id: EntityID) -> bool: + target: Optional[Entity] = self._world_info.get_entity(target_entity_id) + if target is None: + return False + if not isinstance(target, Human): + return False + hp: Optional[int] = target.get_hp() + if hp is None or hp <= 0: + return False + buriedness: Optional[int] = target.get_buriedness() + if buriedness is None: + return False + myself = self._agent_info.get_myself() + if myself is None: + return False + if myself.get_urn() == EntityURN.FIRE_BRIGADE and buriedness == 0: + return False + if myself.get_urn() == EntityURN.AMBULANCE_TEAM and buriedness > 0: + return False + damage: Optional[int] = target.get_damage() + if damage is None or damage == 0: + return False + position_entity_id: Optional[EntityID] = target.get_position() + if position_entity_id is None: + return False + position: Optional[Entity] = self._world_info.get_entity(position_entity_id) + if position is None: + return False + urn: EntityURN = position.get_urn() + if urn == EntityURN.REFUGE or urn == EntityURN.AMBULANCE_TEAM: + return False + + return True + + def get_target_entity_id(self) -> Optional[EntityID]: + return self._result diff --git a/src/adf_core_python/implement/module/complex/default_police_target_allocator.py b/src/adf_core_python/implement/module/complex/default_police_target_allocator.py index 9499ebb..2244d82 100644 --- a/src/adf_core_python/implement/module/complex/default_police_target_allocator.py +++ b/src/adf_core_python/implement/module/complex/default_police_target_allocator.py @@ -2,13 +2,13 @@ from typing import Callable, Optional, cast from rcrscore.entities import ( - Building, - Entity, - EntityID, - GasStation, - PoliceForce, - Refuge, - Road, + Building, + Entity, + EntityID, + GasStation, + PoliceForce, + Refuge, + Road, ) from adf_core_python.core.agent.communication.message_manager import MessageManager @@ -19,173 +19,173 @@ 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.complex.police_target_allocator import ( - PoliceTargetAllocator, + PoliceTargetAllocator, ) class DefaultPoliceTargetAllocator(PoliceTargetAllocator): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - self._priority_areas: set[EntityID] = set() - self._target_areas: set[EntityID] = set() - self._agent_info_map: dict[ - EntityID, DefaultPoliceTargetAllocator.PoliceForceInfo - ] = {} - - def resume(self, precompute_data: PrecomputeData) -> PoliceTargetAllocator: - super().resume(precompute_data) - if self.get_count_resume() >= 2: - return self - - for entity_id in self._world_info.get_entity_ids_of_types([PoliceForce]): - self._agent_info_map[entity_id] = self.PoliceForceInfo(entity_id) - for entity in self._world_info.get_entities_of_types( - [Refuge, Building, GasStation] - ): - building: Building = cast(Building, entity) - for entity_id in building.get_neighbors(): - neighbor = self._world_info.get_entity(entity_id) - if isinstance(neighbor, Road): - self._target_areas.add(entity_id) - - for entity in self._world_info.get_entities_of_types([Refuge]): - refuge: Refuge = cast(Refuge, entity) - for entity_id in refuge.get_neighbors(): - neighbor = self._world_info.get_entity(entity_id) - if isinstance(neighbor, Road): - self._priority_areas.add(entity_id) - return self - - def prepare(self) -> PoliceTargetAllocator: - super().prepare() - if self.get_count_prepare() >= 2: - return self - - for entity_id in self._world_info.get_entity_ids_of_types([PoliceForce]): - self._agent_info_map[entity_id] = self.PoliceForceInfo(entity_id) - - for entity in self._world_info.get_entities_of_types( - [Refuge, Building, GasStation] - ): - building: Building = cast(Building, entity) - for entity_id in building.get_neighbors(): - neighbor = self._world_info.get_entity(entity_id) - if isinstance(neighbor, Road): - self._target_areas.add(entity_id) - - for entity in self._world_info.get_entities_of_types([Refuge]): - refuge: Refuge = cast(Refuge, entity) - for entity_id in refuge.get_neighbors(): - neighbor = self._world_info.get_entity(entity_id) - if isinstance(neighbor, Road): - self._priority_areas.add(entity_id) - - return self - - def update_info(self, message_manager: MessageManager) -> PoliceTargetAllocator: - super().update_info(message_manager) - # TODO: implement after message_manager is implemented - return self - - def calculate(self) -> PoliceTargetAllocator: - agents = self._get_action_agents(self._agent_info_map) - removes = [] - current_time = self._agent_info.get_time() - - for target in self._priority_areas: - if len(agents) > 0: - target_entity = self._world_info.get_entity(target) - if target_entity is not None: - agents = sorted( - agents, key=cmp_to_key(self._compare_by_distance(target_entity)) - ) - selected_agent = agents.pop(0) - info = self._agent_info_map[selected_agent.get_entity_id()] - if info is not None: - info._can_new_action = False - info._target = target - info.command_time = current_time - self._agent_info_map[selected_agent.get_entity_id()] = info - removes.append(target) - - for r in removes: - self._priority_areas.remove(r) - - areas = [] - for target in self._target_areas: - target_entity = self._world_info.get_entity(target) - if target_entity is not None: - areas.append(target_entity) - - for agent in agents: - if len(areas) > 0: - areas.sort(key=cmp_to_key(self._compare_by_distance(agent))) - target_area: Entity = areas.pop(0) - self._target_areas.remove(target_area.get_entity_id()) - info = self._agent_info_map[agent.get_entity_id()] - if info is not None: - info._can_new_action = False - info._target = target_area.get_entity_id() - info.command_time = current_time - self._agent_info_map[agent.get_entity_id()] = info - - return self - - def get_result(self) -> dict[EntityID, EntityID]: - return self._convert(self._agent_info_map) - - def _get_action_agents( - self, info_map: dict[EntityID, "DefaultPoliceTargetAllocator.PoliceForceInfo"] - ) -> list[PoliceForce]: - result = [] - for entity in self._world_info.get_entities_of_types([PoliceForce]): - if isinstance(entity, PoliceForce): - info = info_map[entity.get_entity_id()] - if info is not None and info._can_new_action: - result.append(entity) - return result - - def _compare_by_distance( - self, target_entity: Entity - ) -> Callable[[Entity, Entity], int]: - def _cmp_func(entity_a: Entity, entity_b: Entity) -> int: - distance_a = self._world_info.get_distance( - target_entity.get_entity_id(), entity_a.get_entity_id() - ) - distance_b = self._world_info.get_distance( - target_entity.get_entity_id(), entity_b.get_entity_id() - ) - if distance_a < distance_b: - return -1 - elif distance_a > distance_b: - return 1 - else: - return 0 - - return _cmp_func - - def _convert( - self, info_map: dict[EntityID, "DefaultPoliceTargetAllocator.PoliceForceInfo"] - ) -> dict[EntityID, EntityID]: - result: dict[EntityID, EntityID] = {} - for entity_id in info_map.keys(): - info = info_map[entity_id] - if info is not None and info._target is not None: - result[entity_id] = info._target - return result - - class PoliceForceInfo: - def __init__(self, entity_id: EntityID) -> None: - self._agent_id: EntityID = entity_id - self._target: Optional[EntityID] = None - self._can_new_action: bool = True - self.command_time: int = -1 + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + self._priority_areas: set[EntityID] = set() + self._target_areas: set[EntityID] = set() + self._agent_info_map: dict[ + EntityID, DefaultPoliceTargetAllocator.PoliceForceInfo + ] = {} + + def resume(self, precompute_data: PrecomputeData) -> PoliceTargetAllocator: + super().resume(precompute_data) + if self.get_count_resume() >= 2: + return self + + for entity_id in self._world_info.get_entity_ids_of_types([PoliceForce]): + self._agent_info_map[entity_id] = self.PoliceForceInfo(entity_id) + for entity in self._world_info.get_entities_of_types( + [Refuge, Building, GasStation] + ): + building: Building = cast(Building, entity) + for entity_id in building.get_neighbors(): + neighbor = self._world_info.get_entity(entity_id) + if isinstance(neighbor, Road): + self._target_areas.add(entity_id) + + for entity in self._world_info.get_entities_of_types([Refuge]): + refuge: Refuge = cast(Refuge, entity) + for entity_id in refuge.get_neighbors(): + neighbor = self._world_info.get_entity(entity_id) + if isinstance(neighbor, Road): + self._priority_areas.add(entity_id) + return self + + def prepare(self) -> PoliceTargetAllocator: + super().prepare() + if self.get_count_prepare() >= 2: + return self + + for entity_id in self._world_info.get_entity_ids_of_types([PoliceForce]): + self._agent_info_map[entity_id] = self.PoliceForceInfo(entity_id) + + for entity in self._world_info.get_entities_of_types( + [Refuge, Building, GasStation] + ): + building: Building = cast(Building, entity) + for entity_id in building.get_neighbors(): + neighbor = self._world_info.get_entity(entity_id) + if isinstance(neighbor, Road): + self._target_areas.add(entity_id) + + for entity in self._world_info.get_entities_of_types([Refuge]): + refuge: Refuge = cast(Refuge, entity) + for entity_id in refuge.get_neighbors(): + neighbor = self._world_info.get_entity(entity_id) + if isinstance(neighbor, Road): + self._priority_areas.add(entity_id) + + return self + + def update_info(self, message_manager: MessageManager) -> PoliceTargetAllocator: + super().update_info(message_manager) + # TODO: implement after message_manager is implemented + return self + + def calculate(self) -> PoliceTargetAllocator: + agents = self._get_action_agents(self._agent_info_map) + removes = [] + current_time = self._agent_info.get_time() + + for target in self._priority_areas: + if len(agents) > 0: + target_entity = self._world_info.get_entity(target) + if target_entity is not None: + agents = sorted( + agents, key=cmp_to_key(self._compare_by_distance(target_entity)) + ) + selected_agent = agents.pop(0) + info = self._agent_info_map[selected_agent.get_entity_id()] + if info is not None: + info._can_new_action = False + info._target = target + info.command_time = current_time + self._agent_info_map[selected_agent.get_entity_id()] = info + removes.append(target) + + for r in removes: + self._priority_areas.remove(r) + + areas = [] + for target in self._target_areas: + target_entity = self._world_info.get_entity(target) + if target_entity is not None: + areas.append(target_entity) + + for agent in agents: + if len(areas) > 0: + areas.sort(key=cmp_to_key(self._compare_by_distance(agent))) + target_area: Entity = areas.pop(0) + self._target_areas.remove(target_area.get_entity_id()) + info = self._agent_info_map[agent.get_entity_id()] + if info is not None: + info._can_new_action = False + info._target = target_area.get_entity_id() + info.command_time = current_time + self._agent_info_map[agent.get_entity_id()] = info + + return self + + def get_result(self) -> dict[EntityID, EntityID]: + return self._convert(self._agent_info_map) + + def _get_action_agents( + self, info_map: dict[EntityID, "DefaultPoliceTargetAllocator.PoliceForceInfo"] + ) -> list[PoliceForce]: + result = [] + for entity in self._world_info.get_entities_of_types([PoliceForce]): + if isinstance(entity, PoliceForce): + info = info_map[entity.get_entity_id()] + if info is not None and info._can_new_action: + result.append(entity) + return result + + def _compare_by_distance( + self, target_entity: Entity + ) -> Callable[[Entity, Entity], int]: + def _cmp_func(entity_a: Entity, entity_b: Entity) -> int: + distance_a = self._world_info.get_distance( + target_entity.get_entity_id(), entity_a.get_entity_id() + ) + distance_b = self._world_info.get_distance( + target_entity.get_entity_id(), entity_b.get_entity_id() + ) + if distance_a < distance_b: + return -1 + elif distance_a > distance_b: + return 1 + else: + return 0 + + return _cmp_func + + def _convert( + self, info_map: dict[EntityID, "DefaultPoliceTargetAllocator.PoliceForceInfo"] + ) -> dict[EntityID, EntityID]: + result: dict[EntityID, EntityID] = {} + for entity_id in info_map.keys(): + info = info_map[entity_id] + if info is not None and info._target is not None: + result[entity_id] = info._target + return result + + class PoliceForceInfo: + def __init__(self, entity_id: EntityID) -> None: + self._agent_id: EntityID = entity_id + self._target: Optional[EntityID] = None + self._can_new_action: bool = True + self.command_time: int = -1 diff --git a/src/adf_core_python/implement/module/complex/default_road_detector.py b/src/adf_core_python/implement/module/complex/default_road_detector.py index ed7a02d..40655c4 100644 --- a/src/adf_core_python/implement/module/complex/default_road_detector.py +++ b/src/adf_core_python/implement/module/complex/default_road_detector.py @@ -10,147 +10,143 @@ 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.path_planning import ( - PathPlanning, + PathPlanning, ) from adf_core_python.core.component.module.complex.road_detector import RoadDetector class DefaultRoadDetector(RoadDetector): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - - 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: Optional[EntityID] = None - - def precompute(self, precompute_data: PrecomputeData) -> RoadDetector: - super().precompute(precompute_data) + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + + 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: Optional[EntityID] = None + + def precompute(self, precompute_data: PrecomputeData) -> RoadDetector: + super().precompute(precompute_data) + return self + + def resume(self, precompute_data: PrecomputeData) -> RoadDetector: + super().resume(precompute_data) + if self.get_count_resume() >= 2: + return self + + self._target_areas: set[EntityID] = set() + entities = self._world_info.get_entities_of_types([Refuge, Building, GasStation]) + for entity in entities: + if not isinstance(entity, Building): + continue + for entity_id in entity.get_neighbors(): + neighbor = self._world_info.get_entity(entity_id) + if isinstance(neighbor, Road): + self._target_areas.add(entity_id) + + self._priority_roads = set() + for entity in self._world_info.get_entities_of_types([Refuge]): + if not isinstance(entity, Building): + continue + for entity_id in entity.get_neighbors(): + neighbor = self._world_info.get_entity(entity_id) + if isinstance(neighbor, Road): + self._priority_roads.add(entity_id) + + return self + + def prepare(self) -> RoadDetector: + super().prepare() + if self.get_count_prepare() >= 2: + return self + + self._target_areas = set() + entities = self._world_info.get_entities_of_types([Refuge, Building, GasStation]) + for entity in entities: + building: Building = cast(Building, entity) + for entity_id in building.get_neighbors(): + neighbor = self._world_info.get_entity(entity_id) + if isinstance(neighbor, Road): + self._target_areas.add(entity_id) + + self._priority_roads = set() + for entity in self._world_info.get_entities_of_types([Refuge]): + refuge: Refuge = cast(Refuge, entity) + for entity_id in refuge.get_neighbors(): + neighbor = self._world_info.get_entity(entity_id) + if isinstance(neighbor, Road): + self._priority_roads.add(entity_id) + + return self + + def update_info(self, message_manager: MessageManager) -> RoadDetector: + super().update_info(message_manager) + if self.get_count_update_info() >= 2: + return self + + if self._result is not None: + if self._agent_info.get_position_entity_id == self._result: + entity = self._world_info.get_entity(self._result) + if isinstance(entity, Building): + self._result = None + elif isinstance(entity, Road): + road = entity + if road.get_blockades() == []: + self._target_areas.remove(self._result) + self._result = None + + return self + + def calculate(self) -> RoadDetector: + if self._result is None: + position_entity_id = self._agent_info.get_position_entity_id() + if position_entity_id is None: return self - - def resume(self, precompute_data: PrecomputeData) -> RoadDetector: - super().resume(precompute_data) - if self.get_count_resume() >= 2: - return self - - self._target_areas: set[EntityID] = set() - entities = self._world_info.get_entities_of_types( - [Refuge, Building, GasStation] - ) - for entity in entities: - if not isinstance(entity, Building): - continue - for entity_id in entity.get_neighbors(): - neighbor = self._world_info.get_entity(entity_id) - if isinstance(neighbor, Road): - self._target_areas.add(entity_id) - - self._priority_roads = set() - for entity in self._world_info.get_entities_of_types([Refuge]): - if not isinstance(entity, Building): - continue - for entity_id in entity.get_neighbors(): - neighbor = self._world_info.get_entity(entity_id) - if isinstance(neighbor, Road): - self._priority_roads.add(entity_id) - + if position_entity_id in self._target_areas: + self._result = position_entity_id return self - - def prepare(self) -> RoadDetector: - super().prepare() - if self.get_count_prepare() >= 2: - return self - - self._target_areas = set() - entities = self._world_info.get_entities_of_types( - [Refuge, Building, GasStation] + remove_list = [] + for entity_id in self._priority_roads: + if entity_id not in self._target_areas: + remove_list.append(entity_id) + + self._priority_roads = self._priority_roads - set(remove_list) + if len(self._priority_roads) > 0: + agent_position = self._agent_info.get_position_entity_id() + if agent_position is None: + return self + _nearest_target_area = agent_position + _nearest_distance = float("inf") + for target_area in self._target_areas: + if ( + self._world_info.get_distance(agent_position, target_area) + < _nearest_distance + ): + _nearest_target_area = target_area + _nearest_distance = self._world_info.get_distance( + agent_position, target_area + ) + path: list[EntityID] = self._path_planning.get_path( + agent_position, _nearest_target_area ) - for entity in entities: - building: Building = cast(Building, entity) - for entity_id in building.get_neighbors(): - neighbor = self._world_info.get_entity(entity_id) - if isinstance(neighbor, Road): - self._target_areas.add(entity_id) - - self._priority_roads = set() - for entity in self._world_info.get_entities_of_types([Refuge]): - refuge: Refuge = cast(Refuge, entity) - for entity_id in refuge.get_neighbors(): - neighbor = self._world_info.get_entity(entity_id) - if isinstance(neighbor, Road): - self._priority_roads.add(entity_id) - - return self - - def update_info(self, message_manager: MessageManager) -> RoadDetector: - super().update_info(message_manager) - if self.get_count_update_info() >= 2: - return self - - if self._result is not None: - if self._agent_info.get_position_entity_id == self._result: - entity = self._world_info.get_entity(self._result) - if isinstance(entity, Building): - self._result = None - elif isinstance(entity, Road): - road = entity - if road.get_blockades() == []: - self._target_areas.remove(self._result) - self._result = None + if path is not None and len(path) > 0: + self._result = path[-1] - return self - - def calculate(self) -> RoadDetector: - if self._result is None: - position_entity_id = self._agent_info.get_position_entity_id() - if position_entity_id is None: - return self - if position_entity_id in self._target_areas: - self._result = position_entity_id - return self - remove_list = [] - for entity_id in self._priority_roads: - if entity_id not in self._target_areas: - remove_list.append(entity_id) - - self._priority_roads = self._priority_roads - set(remove_list) - if len(self._priority_roads) > 0: - agent_position = self._agent_info.get_position_entity_id() - if agent_position is None: - return self - _nearest_target_area = agent_position - _nearest_distance = float("inf") - for target_area in self._target_areas: - if ( - self._world_info.get_distance(agent_position, target_area) - < _nearest_distance - ): - _nearest_target_area = target_area - _nearest_distance = self._world_info.get_distance( - agent_position, target_area - ) - path: list[EntityID] = self._path_planning.get_path( - agent_position, _nearest_target_area - ) - if path is not None and len(path) > 0: - self._result = path[-1] - - return self + return self - def get_target_entity_id(self) -> Optional[EntityID]: - return self._result + def get_target_entity_id(self) -> Optional[EntityID]: + return self._result diff --git a/src/adf_core_python/implement/module/complex/default_search.py b/src/adf_core_python/implement/module/complex/default_search.py index 1050029..9d303ed 100644 --- a/src/adf_core_python/implement/module/complex/default_search.py +++ b/src/adf_core_python/implement/module/complex/default_search.py @@ -15,90 +15,90 @@ class DefaultSearch(Search): - def __init__( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - develop_data: DevelopData, - ) -> None: - super().__init__( - agent_info, world_info, scenario_info, module_manager, develop_data - ) - - self._unreached_building_ids: set[EntityID] = set() - self._result: Optional[EntityID] = None - - self._clustering: Clustering = cast( - Clustering, - module_manager.get_module( - "DefaultSearch.Clustering", - "adf_core_python.implement.module.algorithm.k_means_clustering.KMeansClustering", - ), - ) - - self._path_planning: PathPlanning = cast( - PathPlanning, - module_manager.get_module( - "DefaultSearch.PathPlanning", - "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", - ), - ) - - self._logger = get_agent_logger( - f"{self.__class__.__module__}.{self.__class__.__qualname__}", - self._agent_info, - ) - - self.register_sub_module(self._clustering) - self.register_sub_module(self._path_planning) - - def update_info(self, message_manager: MessageManager) -> Search: - super().update_info(message_manager) - if self.get_count_update_info() > 1: - return self - - self._logger.debug( - f"unreached_building_ids: {[str(id) for id in self._unreached_building_ids]}" - ) - - searched_building_id = self._agent_info.get_position_entity_id() - if searched_building_id is not None: - self._unreached_building_ids.discard(searched_building_id) - - if len(self._unreached_building_ids) == 0: - self._unreached_building_ids = self._get_search_targets() - - return self - - def calculate(self) -> Search: - nearest_building_id: Optional[EntityID] = None - nearest_distance: Optional[float] = None - for building_id in self._unreached_building_ids: - distance = self._world_info.get_distance( - self._agent_info.get_entity_id(), building_id - ) - if nearest_distance is None or distance < nearest_distance: - nearest_building_id = building_id - nearest_distance = distance - self._result = nearest_building_id - return self - - def get_target_entity_id(self) -> Optional[EntityID]: - return self._result - - def _get_search_targets(self) -> set[EntityID]: - cluster_index: int = self._clustering.get_cluster_index( - self._agent_info.get_entity_id() - ) - cluster_entities: list[Entity] = self._clustering.get_cluster_entities( - cluster_index - ) - building_entity_ids: list[EntityID] = [ - entity.get_entity_id() - for entity in cluster_entities - if isinstance(entity, Building) and not isinstance(entity, Refuge) - ] - - return set(building_entity_ids) + def __init__( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + develop_data: DevelopData, + ) -> None: + super().__init__( + agent_info, world_info, scenario_info, module_manager, develop_data + ) + + self._unreached_building_ids: set[EntityID] = set() + self._result: Optional[EntityID] = None + + self._clustering: Clustering = cast( + Clustering, + module_manager.get_module( + "DefaultSearch.Clustering", + "adf_core_python.implement.module.algorithm.k_means_clustering.KMeansClustering", + ), + ) + + self._path_planning: PathPlanning = cast( + PathPlanning, + module_manager.get_module( + "DefaultSearch.PathPlanning", + "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", + ), + ) + + self._logger = get_agent_logger( + f"{self.__class__.__module__}.{self.__class__.__qualname__}", + self._agent_info, + ) + + self.register_sub_module(self._clustering) + self.register_sub_module(self._path_planning) + + def update_info(self, message_manager: MessageManager) -> Search: + super().update_info(message_manager) + if self.get_count_update_info() > 1: + return self + + self._logger.debug( + f"unreached_building_ids: {[str(id) for id in self._unreached_building_ids]}" + ) + + searched_building_id = self._agent_info.get_position_entity_id() + if searched_building_id is not None: + self._unreached_building_ids.discard(searched_building_id) + + if len(self._unreached_building_ids) == 0: + self._unreached_building_ids = self._get_search_targets() + + return self + + def calculate(self) -> Search: + nearest_building_id: Optional[EntityID] = None + nearest_distance: Optional[float] = None + for building_id in self._unreached_building_ids: + distance = self._world_info.get_distance( + self._agent_info.get_entity_id(), building_id + ) + if nearest_distance is None or distance < nearest_distance: + nearest_building_id = building_id + nearest_distance = distance + self._result = nearest_building_id + return self + + def get_target_entity_id(self) -> Optional[EntityID]: + return self._result + + def _get_search_targets(self) -> set[EntityID]: + cluster_index: int = self._clustering.get_cluster_index( + self._agent_info.get_entity_id() + ) + cluster_entities: list[Entity] = self._clustering.get_cluster_entities( + cluster_index + ) + building_entity_ids: list[EntityID] = [ + entity.get_entity_id() + for entity in cluster_entities + if isinstance(entity, Building) and not isinstance(entity, Refuge) + ] + + return set(building_entity_ids) diff --git a/src/adf_core_python/implement/tactics/default_tactics_ambulance_center.py b/src/adf_core_python/implement/tactics/default_tactics_ambulance_center.py index 68c9ff8..f7108a5 100644 --- a/src/adf_core_python/implement/tactics/default_tactics_ambulance_center.py +++ b/src/adf_core_python/implement/tactics/default_tactics_ambulance_center.py @@ -11,91 +11,89 @@ from adf_core_python.core.agent.precompute.precompute_data import PrecomputeData from adf_core_python.core.component.centralized.command_picker import CommandPicker from adf_core_python.core.component.module.complex.target_allocator import ( - TargetAllocator, + TargetAllocator, ) from adf_core_python.core.component.tactics.tactics_ambulance_center import ( - TacticsAmbulanceCenter, + TacticsAmbulanceCenter, ) class DefaultTacticsAmbulanceCenter(TacticsAmbulanceCenter): - def initialize( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - precompute_data: PrecomputeData, - message_manager: MessageManager, - develop_data: DevelopData, - ) -> None: - self._allocator: TargetAllocator = cast( - TargetAllocator, - module_manager.get_module( - "DefaultTacticsAmbulanceCenter.TargetAllocator", - "adf_core_python.implement.module.complex.default_ambulance_target_allocator.DefaultAmbulanceTargetAllocator", - ), - ) - self._picker: CommandPicker = module_manager.get_command_picker( - "DefaultTacticsAmbulanceCenter.CommandPicker", - "adf_core_python.implement.centralized.default_command_picker_ambulance.DefaultCommandPickerAmbulance", - ) - self.register_module(self._allocator) - self.register_command_picker(self._picker) + def initialize( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + message_manager: MessageManager, + develop_data: DevelopData, + ) -> None: + self._allocator: TargetAllocator = cast( + TargetAllocator, + module_manager.get_module( + "DefaultTacticsAmbulanceCenter.TargetAllocator", + "adf_core_python.implement.module.complex.default_ambulance_target_allocator.DefaultAmbulanceTargetAllocator", + ), + ) + self._picker: CommandPicker = module_manager.get_command_picker( + "DefaultTacticsAmbulanceCenter.CommandPicker", + "adf_core_python.implement.centralized.default_command_picker_ambulance.DefaultCommandPickerAmbulance", + ) + self.register_module(self._allocator) + self.register_command_picker(self._picker) - 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 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, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - precompute_data: PrecomputeData, - message_manager: MessageManager, - develop_data: DevelopData, - ) -> None: - self.module_resume(precompute_data) + def resume( + 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_resume(precompute_data) - def prepare( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - precompute_data: PrecomputeData, - develop_data: DevelopData, - ) -> None: - self.module_prepare() + def prepare( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + develop_data: DevelopData, + ) -> None: + self.module_prepare() - def think( - 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_update_info(message_manager) + def think( + 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_update_info(message_manager) - allocation_result: dict[EntityID, EntityID] = ( - self._allocator.calculate().get_result() - ) - for message in ( - self._picker.set_allocator_result(allocation_result) - .calculate() - .get_result() - ): - message_manager.add_message(message) + allocation_result: dict[EntityID, EntityID] = ( + self._allocator.calculate().get_result() + ) + for message in ( + self._picker.set_allocator_result(allocation_result).calculate().get_result() + ): + message_manager.add_message(message) diff --git a/src/adf_core_python/implement/tactics/default_tactics_ambulance_team.py b/src/adf_core_python/implement/tactics/default_tactics_ambulance_team.py index 688c845..2ab674b 100644 --- a/src/adf_core_python/implement/tactics/default_tactics_ambulance_team.py +++ b/src/adf_core_python/implement/tactics/default_tactics_ambulance_team.py @@ -6,13 +6,13 @@ from adf_core_python.core.agent.action.common.action_rest import ActionRest from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.communication.standard.bundle.centralized.command_ambulance import ( - CommandAmbulance, + CommandAmbulance, ) from adf_core_python.core.agent.communication.standard.bundle.centralized.command_scout import ( - CommandScout, + CommandScout, ) from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( - StandardMessage, + StandardMessage, ) from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo @@ -23,182 +23,176 @@ from adf_core_python.core.component.module.complex.human_detector import HumanDetector from adf_core_python.core.component.module.complex.search import Search from adf_core_python.core.component.tactics.tactics_ambulance_team import ( - TacticsAmbulanceTeam, + TacticsAmbulanceTeam, ) class DefaultTacticsAmbulanceTeam(TacticsAmbulanceTeam): - def initialize( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - precompute_data: PrecomputeData, - message_manager: MessageManager, - develop_data: DevelopData, - ) -> None: - # world_info.index_class() - super().initialize( - agent_info, - world_info, - scenario_info, - module_manager, - precompute_data, - message_manager, - develop_data, - ) - - self._search: Search = cast( - Search, - module_manager.get_module( - "DefaultTacticsAmbulanceTeam.Search", - "adf_core_python.implement.module.complex.default_search.DefaultSearch", - ), - ) - self._human_detector: HumanDetector = cast( - HumanDetector, - module_manager.get_module( - "DefaultTacticsAmbulanceTeam.HumanDetector", - "adf_core_python.implement.module.complex.default_human_detector.DefaultHumanDetector", - ), - ) - 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._command_executor_ambulance = module_manager.get_command_executor( - "DefaultTacticsAmbulanceTeam.CommandExecutorAmbulance", - "adf_core_python.implement.centralized.default_command_executor_ambulance.DefaultCommandExecutorAmbulance", - ) - self._command_executor_scout = module_manager.get_command_executor( - "DefaultTacticsAmbulanceTeam.CommandExecutorScout", - "adf_core_python.implement.centralized.default_command_executor_scout.DefaultCommandExecutorScout", - ) - - self.register_module(self._search) - self.register_module(self._human_detector) - self.register_action(self._action_transport) - self.register_action(self._action_ext_move) - self.register_command_executor(self._command_executor_ambulance) - self.register_command_executor(self._command_executor_scout) - - self._recent_command: Optional[StandardMessage] = None - - 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, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - precompute_data: PrecomputeData, - message_manager: MessageManager, - develop_data: DevelopData, - ) -> None: - self.module_resume(precompute_data) - - def prepare( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - precompute_data: PrecomputeData, - develop_data: DevelopData, - ) -> None: - self.module_prepare() - - def think( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - precompute_data: PrecomputeData, - message_manager: MessageManager, - develop_data: DevelopData, - ) -> Action: - self.reset_count() - self.module_update_info(message_manager) - - agent: AmbulanceTeam = cast(AmbulanceTeam, agent_info.get_myself()) # noqa: F841 - entity_id = agent_info.get_entity_id() # noqa: F841 - - self._logger.debug( - f"received messages: {[str(message) for message in message_manager.get_received_message_list()]}, help: {message_manager.get_heard_agent_help_message_count()}" - ) - - for message in message_manager.get_received_message_list(): - if isinstance(message, CommandScout): - if ( - message.get_command_executor_agent_entity_id() - == agent_info.get_entity_id() - ): - self._recent_command = message - self._command_executor_scout.set_command(message) - if isinstance(message, CommandAmbulance): - if ( - message.get_command_executor_agent_entity_id() - == agent_info.get_entity_id() - ): - self._recent_command = message - self._command_executor_ambulance.set_command(message) - - if self._recent_command is not None: - action: Optional[Action] = None - if isinstance(self._recent_command, CommandScout): - action = self._command_executor_scout.calculate().get_action() - elif isinstance(self._recent_command, CommandAmbulance): - action = self._command_executor_ambulance.calculate().get_action() - if action is not None: - self._logger.debug( - f"action decided by command: {action}", time=agent_info.get_time() - ) - return action - - target_entity_id = self._human_detector.calculate().get_target_entity_id() - self._logger.debug( - f"human detector target_entity_id: {target_entity_id}", - time=agent_info.get_time(), - ) - if target_entity_id is not None: - action = ( - self._action_transport.set_target_entity_id(target_entity_id) - .calculate() - .get_action() - ) - if action is not None: - self._logger.debug(f"action: {action}", time=agent_info.get_time()) - return action - - target_entity_id = self._search.calculate().get_target_entity_id() + def initialize( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + message_manager: MessageManager, + develop_data: DevelopData, + ) -> None: + # world_info.index_class() + super().initialize( + agent_info, + world_info, + scenario_info, + module_manager, + precompute_data, + message_manager, + develop_data, + ) + + self._search: Search = cast( + Search, + module_manager.get_module( + "DefaultTacticsAmbulanceTeam.Search", + "adf_core_python.implement.module.complex.default_search.DefaultSearch", + ), + ) + self._human_detector: HumanDetector = cast( + HumanDetector, + module_manager.get_module( + "DefaultTacticsAmbulanceTeam.HumanDetector", + "adf_core_python.implement.module.complex.default_human_detector.DefaultHumanDetector", + ), + ) + 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._command_executor_ambulance = module_manager.get_command_executor( + "DefaultTacticsAmbulanceTeam.CommandExecutorAmbulance", + "adf_core_python.implement.centralized.default_command_executor_ambulance.DefaultCommandExecutorAmbulance", + ) + self._command_executor_scout = module_manager.get_command_executor( + "DefaultTacticsAmbulanceTeam.CommandExecutorScout", + "adf_core_python.implement.centralized.default_command_executor_scout.DefaultCommandExecutorScout", + ) + + self.register_module(self._search) + self.register_module(self._human_detector) + self.register_action(self._action_transport) + self.register_action(self._action_ext_move) + self.register_command_executor(self._command_executor_ambulance) + self.register_command_executor(self._command_executor_scout) + + self._recent_command: Optional[StandardMessage] = None + + 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, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + message_manager: MessageManager, + develop_data: DevelopData, + ) -> None: + self.module_resume(precompute_data) + + def prepare( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + develop_data: DevelopData, + ) -> None: + self.module_prepare() + + def think( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + message_manager: MessageManager, + develop_data: DevelopData, + ) -> Action: + self.reset_count() + self.module_update_info(message_manager) + + agent: AmbulanceTeam = cast(AmbulanceTeam, agent_info.get_myself()) # noqa: F841 + entity_id = agent_info.get_entity_id() # noqa: F841 + + self._logger.debug( + f"received messages: {[str(message) for message in message_manager.get_received_message_list()]}, help: {message_manager.get_heard_agent_help_message_count()}" + ) + + for message in message_manager.get_received_message_list(): + if isinstance(message, CommandScout): + if message.get_command_executor_agent_entity_id() == agent_info.get_entity_id(): + self._recent_command = message + self._command_executor_scout.set_command(message) + if isinstance(message, CommandAmbulance): + if message.get_command_executor_agent_entity_id() == agent_info.get_entity_id(): + self._recent_command = message + self._command_executor_ambulance.set_command(message) + + if self._recent_command is not None: + action: Optional[Action] = None + if isinstance(self._recent_command, CommandScout): + action = self._command_executor_scout.calculate().get_action() + elif isinstance(self._recent_command, CommandAmbulance): + action = self._command_executor_ambulance.calculate().get_action() + if action is not None: self._logger.debug( - f"search target_entity_id: {target_entity_id}", time=agent_info.get_time() + f"action decided by command: {action}", time=agent_info.get_time() ) - if target_entity_id is not None: - action = ( - self._action_ext_move.set_target_entity_id(target_entity_id) - .calculate() - .get_action() - ) - if action is not None: - self._logger.debug(f"action: {action}", time=agent_info.get_time()) - return action - - return ActionRest() + return action + + target_entity_id = self._human_detector.calculate().get_target_entity_id() + self._logger.debug( + f"human detector target_entity_id: {target_entity_id}", + time=agent_info.get_time(), + ) + if target_entity_id is not None: + action = ( + self._action_transport.set_target_entity_id(target_entity_id) + .calculate() + .get_action() + ) + if action is not None: + self._logger.debug(f"action: {action}", time=agent_info.get_time()) + return action + + target_entity_id = self._search.calculate().get_target_entity_id() + self._logger.debug( + f"search target_entity_id: {target_entity_id}", time=agent_info.get_time() + ) + if target_entity_id is not None: + action = ( + self._action_ext_move.set_target_entity_id(target_entity_id) + .calculate() + .get_action() + ) + if action is not None: + self._logger.debug(f"action: {action}", time=agent_info.get_time()) + return action + + return ActionRest() diff --git a/src/adf_core_python/implement/tactics/default_tactics_fire_brigade.py b/src/adf_core_python/implement/tactics/default_tactics_fire_brigade.py index de4f706..5b9b8db 100644 --- a/src/adf_core_python/implement/tactics/default_tactics_fire_brigade.py +++ b/src/adf_core_python/implement/tactics/default_tactics_fire_brigade.py @@ -6,13 +6,13 @@ from adf_core_python.core.agent.action.common.action_rest import ActionRest from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.communication.standard.bundle.centralized.command_fire import ( - CommandFire, + CommandFire, ) from adf_core_python.core.agent.communication.standard.bundle.centralized.command_scout import ( - CommandScout, + CommandScout, ) from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( - StandardMessage, + StandardMessage, ) from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo @@ -23,178 +23,172 @@ from adf_core_python.core.component.module.complex.human_detector import HumanDetector from adf_core_python.core.component.module.complex.search import Search from adf_core_python.core.component.tactics.tactics_fire_brigade import ( - TacticsFireBrigade, + TacticsFireBrigade, ) class DefaultTacticsFireBrigade(TacticsFireBrigade): - def initialize( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - precompute_data: PrecomputeData, - message_manager: MessageManager, - develop_data: DevelopData, - ) -> None: - # world_info.index_class() - super().initialize( - agent_info, - world_info, - scenario_info, - module_manager, - precompute_data, - message_manager, - develop_data, - ) - - self._search: Search = cast( - Search, - module_manager.get_module( - "DefaultTacticsFireBrigade.Search", - "adf_core_python.implement.module.complex.default_search.DefaultSearch", - ), - ) - self._human_detector: HumanDetector = cast( - HumanDetector, - module_manager.get_module( - "DefaultTacticsFireBrigade.HumanDetector", - "adf_core_python.implement.module.complex.default_human_detector.DefaultHumanDetector", - ), - ) - 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._command_executor_fire = module_manager.get_command_executor( - "DefaultTacticsFireBrigade.CommandExecutorFire", - "adf_core_python.implement.centralized.default_command_executor_fire.DefaultCommandExecutorFire", - ) - self._command_executor_scout = module_manager.get_command_executor( - "DefaultTacticsAmbulanceTeam.CommandExecutorScout", - "adf_core_python.implement.centralized.default_command_executor_scout.DefaultCommandExecutorScout", - ) - - self.register_module(self._search) - self.register_module(self._human_detector) - self.register_action(self._action_rescue) - self.register_action(self._action_ext_move) - self.register_command_executor(self._command_executor_fire) - self.register_command_executor(self._command_executor_scout) - - self._recent_command: Optional[StandardMessage] = None - - 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, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - precompute_data: PrecomputeData, - message_manager: MessageManager, - develop_data: DevelopData, - ) -> None: - self.module_resume(precompute_data) - - def prepare( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - precompute_data: PrecomputeData, - develop_data: DevelopData, - ) -> None: - self.module_prepare() - - def think( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - precompute_data: PrecomputeData, - message_manager: MessageManager, - develop_data: DevelopData, - ) -> Action: - self.reset_count() - self.module_update_info(message_manager) - - agent: FireBrigade = cast(FireBrigade, agent_info.get_myself()) # noqa: F841 - entity_id = agent_info.get_entity_id() # noqa: F841 - - for message in message_manager.get_received_message_list(): - if isinstance(message, CommandScout): - if ( - message.get_command_executor_agent_entity_id() - == agent_info.get_entity_id() - ): - self._recent_command = message - self._command_executor_scout.set_command(command=message) - if isinstance(message, CommandFire): - if ( - message.get_command_executor_agent_entity_id() - == agent_info.get_entity_id() - ): - self._recent_command = message - self._command_executor_fire.set_command(message) - - if self._recent_command is not None: - action: Optional[Action] = None - if isinstance(self._recent_command, CommandScout): - action = self._command_executor_scout.calculate().get_action() - elif isinstance(self._recent_command, CommandFire): - action = self._command_executor_fire.calculate().get_action() - if action is not None: - self._logger.debug( - f"action decided by command: {action}", time=agent_info.get_time() - ) - return action - - target_entity_id = self._human_detector.calculate().get_target_entity_id() - self._logger.debug( - f"human detector target_entity_id: {target_entity_id}", - time=agent_info.get_time(), - ) - if target_entity_id is not None: - action = ( - self._action_rescue.set_target_entity_id(target_entity_id) - .calculate() - .get_action() - ) - if action is not None: - self._logger.debug(f"action: {action}", time=agent_info.get_time()) - return action - - target_entity_id = self._search.calculate().get_target_entity_id() + def initialize( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + message_manager: MessageManager, + develop_data: DevelopData, + ) -> None: + # world_info.index_class() + super().initialize( + agent_info, + world_info, + scenario_info, + module_manager, + precompute_data, + message_manager, + develop_data, + ) + + self._search: Search = cast( + Search, + module_manager.get_module( + "DefaultTacticsFireBrigade.Search", + "adf_core_python.implement.module.complex.default_search.DefaultSearch", + ), + ) + self._human_detector: HumanDetector = cast( + HumanDetector, + module_manager.get_module( + "DefaultTacticsFireBrigade.HumanDetector", + "adf_core_python.implement.module.complex.default_human_detector.DefaultHumanDetector", + ), + ) + 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._command_executor_fire = module_manager.get_command_executor( + "DefaultTacticsFireBrigade.CommandExecutorFire", + "adf_core_python.implement.centralized.default_command_executor_fire.DefaultCommandExecutorFire", + ) + self._command_executor_scout = module_manager.get_command_executor( + "DefaultTacticsAmbulanceTeam.CommandExecutorScout", + "adf_core_python.implement.centralized.default_command_executor_scout.DefaultCommandExecutorScout", + ) + + self.register_module(self._search) + self.register_module(self._human_detector) + self.register_action(self._action_rescue) + self.register_action(self._action_ext_move) + self.register_command_executor(self._command_executor_fire) + self.register_command_executor(self._command_executor_scout) + + self._recent_command: Optional[StandardMessage] = None + + 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, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + message_manager: MessageManager, + develop_data: DevelopData, + ) -> None: + self.module_resume(precompute_data) + + def prepare( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + develop_data: DevelopData, + ) -> None: + self.module_prepare() + + def think( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + message_manager: MessageManager, + develop_data: DevelopData, + ) -> Action: + self.reset_count() + self.module_update_info(message_manager) + + agent: FireBrigade = cast(FireBrigade, agent_info.get_myself()) # noqa: F841 + entity_id = agent_info.get_entity_id() # noqa: F841 + + for message in message_manager.get_received_message_list(): + if isinstance(message, CommandScout): + if message.get_command_executor_agent_entity_id() == agent_info.get_entity_id(): + self._recent_command = message + self._command_executor_scout.set_command(command=message) + if isinstance(message, CommandFire): + if message.get_command_executor_agent_entity_id() == agent_info.get_entity_id(): + self._recent_command = message + self._command_executor_fire.set_command(message) + + if self._recent_command is not None: + action: Optional[Action] = None + if isinstance(self._recent_command, CommandScout): + action = self._command_executor_scout.calculate().get_action() + elif isinstance(self._recent_command, CommandFire): + action = self._command_executor_fire.calculate().get_action() + if action is not None: self._logger.debug( - f"search target_entity_id: {target_entity_id}", time=agent_info.get_time() + f"action decided by command: {action}", time=agent_info.get_time() ) - if target_entity_id is not None: - action = ( - self._action_ext_move.set_target_entity_id(target_entity_id) - .calculate() - .get_action() - ) - if action is not None: - self._logger.debug(f"action: {action}", time=agent_info.get_time()) - return action - - return ActionRest() + return action + + target_entity_id = self._human_detector.calculate().get_target_entity_id() + self._logger.debug( + f"human detector target_entity_id: {target_entity_id}", + time=agent_info.get_time(), + ) + if target_entity_id is not None: + action = ( + self._action_rescue.set_target_entity_id(target_entity_id) + .calculate() + .get_action() + ) + if action is not None: + self._logger.debug(f"action: {action}", time=agent_info.get_time()) + return action + + target_entity_id = self._search.calculate().get_target_entity_id() + self._logger.debug( + f"search target_entity_id: {target_entity_id}", time=agent_info.get_time() + ) + if target_entity_id is not None: + action = ( + self._action_ext_move.set_target_entity_id(target_entity_id) + .calculate() + .get_action() + ) + if action is not None: + self._logger.debug(f"action: {action}", time=agent_info.get_time()) + return action + + return ActionRest() diff --git a/src/adf_core_python/implement/tactics/default_tactics_fire_station.py b/src/adf_core_python/implement/tactics/default_tactics_fire_station.py index ef6425d..099d2b1 100644 --- a/src/adf_core_python/implement/tactics/default_tactics_fire_station.py +++ b/src/adf_core_python/implement/tactics/default_tactics_fire_station.py @@ -11,91 +11,89 @@ from adf_core_python.core.agent.precompute.precompute_data import PrecomputeData from adf_core_python.core.component.centralized.command_picker import CommandPicker from adf_core_python.core.component.module.complex.target_allocator import ( - TargetAllocator, + TargetAllocator, ) from adf_core_python.core.component.tactics.tactics_fire_station import ( - TacticsFireStation, + TacticsFireStation, ) class DefaultTacticsFireStation(TacticsFireStation): - def initialize( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - precompute_data: PrecomputeData, - message_manager: MessageManager, - develop_data: DevelopData, - ) -> None: - self._allocator: TargetAllocator = cast( - TargetAllocator, - module_manager.get_module( - "DefaultTacticsFireStation.TargetAllocator", - "adf_core_python.implement.module.complex.default_fire_target_allocator.DefaultFireTargetAllocator", - ), - ) - self._picker: CommandPicker = module_manager.get_command_picker( - "DefaultTacticsFireStation.CommandPicker", - "adf_core_python.implement.centralized.default_command_picker_fire.DefaultCommandPickerFire", - ) - self.register_module(self._allocator) - self.register_command_picker(self._picker) + def initialize( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + message_manager: MessageManager, + develop_data: DevelopData, + ) -> None: + self._allocator: TargetAllocator = cast( + TargetAllocator, + module_manager.get_module( + "DefaultTacticsFireStation.TargetAllocator", + "adf_core_python.implement.module.complex.default_fire_target_allocator.DefaultFireTargetAllocator", + ), + ) + self._picker: CommandPicker = module_manager.get_command_picker( + "DefaultTacticsFireStation.CommandPicker", + "adf_core_python.implement.centralized.default_command_picker_fire.DefaultCommandPickerFire", + ) + self.register_module(self._allocator) + self.register_command_picker(self._picker) - def resume( - 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_resume(precompute_data) + def resume( + 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_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 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, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - precompute_data: PrecomputeData, - develop_data: DevelopData, - ) -> None: - self.module_prepare() + def prepare( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + develop_data: DevelopData, + ) -> None: + self.module_prepare() - def think( - 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_update_info(message_manager) + def think( + 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_update_info(message_manager) - allocation_result: dict[EntityID, EntityID] = ( - self._allocator.calculate().get_result() - ) - for message in ( - self._picker.set_allocator_result(allocation_result) - .calculate() - .get_result() - ): - message_manager.add_message(message) + allocation_result: dict[EntityID, EntityID] = ( + self._allocator.calculate().get_result() + ) + for message in ( + self._picker.set_allocator_result(allocation_result).calculate().get_result() + ): + message_manager.add_message(message) diff --git a/src/adf_core_python/implement/tactics/default_tactics_police_force.py b/src/adf_core_python/implement/tactics/default_tactics_police_force.py index 8b75a07..3e26216 100644 --- a/src/adf_core_python/implement/tactics/default_tactics_police_force.py +++ b/src/adf_core_python/implement/tactics/default_tactics_police_force.py @@ -6,16 +6,16 @@ from adf_core_python.core.agent.action.common.action_rest import ActionRest from adf_core_python.core.agent.communication.message_manager import MessageManager from adf_core_python.core.agent.communication.standard.bundle.centralized.command_fire import ( - CommandFire, + CommandFire, ) from adf_core_python.core.agent.communication.standard.bundle.centralized.command_police import ( - CommandPolice, + CommandPolice, ) from adf_core_python.core.agent.communication.standard.bundle.centralized.command_scout import ( - CommandScout, + CommandScout, ) from adf_core_python.core.agent.communication.standard.bundle.standard_message import ( - StandardMessage, + StandardMessage, ) from adf_core_python.core.agent.develop.develop_data import DevelopData from adf_core_python.core.agent.info.agent_info import AgentInfo @@ -26,181 +26,175 @@ from adf_core_python.core.component.module.complex.road_detector import RoadDetector from adf_core_python.core.component.module.complex.search import Search from adf_core_python.core.component.tactics.tactics_police_force import ( - TacticsPoliceForce, + TacticsPoliceForce, ) class DefaultTacticsPoliceForce(TacticsPoliceForce): - def initialize( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - precompute_data: PrecomputeData, - message_manager: MessageManager, - develop_data: DevelopData, - ) -> None: - # world_info.index_class() - super().initialize( - agent_info, - world_info, - scenario_info, - module_manager, - precompute_data, - message_manager, - develop_data, - ) - # self._clear_distance = int( - # scenario_info.get_value("clear.repair.distance", "null") - # ) - - self._search: Search = cast( - Search, - module_manager.get_module( - "DefaultTacticsPoliceForce.Search", - "adf_core_python.implement.module.complex.default_search.DefaultSearch", - ), - ) - 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._command_executor_police = module_manager.get_command_executor( - "DefaultTacticsPoliceForce.CommandExecutorPolice", - "adf_core_python.implement.centralized.default_command_executor_police.DefaultCommandExecutorPolice", - ) - self._command_executor_scout = module_manager.get_command_executor( - "DefaultTacticsPoliceForce.CommandExecutorScout", - "adf_core_python.implement.centralized.default_command_executor_scout_police.DefaultCommandExecutorScoutPolice", - ) - - self.register_module(self._search) - self.register_module(self._road_detector) - self.register_action(self._action_ext_clear) - self.register_action(self._action_ext_move) - self.register_command_executor(self._command_executor_police) - self.register_command_executor(self._command_executor_scout) - - self._recent_command: Optional[StandardMessage] = None - - 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, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - precompute_data: PrecomputeData, - message_manager: MessageManager, - develop_data: DevelopData, - ) -> None: - self.module_resume(precompute_data) - - def prepare( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - precompute_data: PrecomputeData, - develop_data: DevelopData, - ) -> None: - self.module_prepare() - - def think( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - precompute_data: PrecomputeData, - message_manager: MessageManager, - develop_data: DevelopData, - ) -> Action: - self.reset_count() - self.module_update_info(message_manager) - - agent: PoliceForce = cast(PoliceForce, agent_info.get_myself()) # noqa: F841 - entity_id = agent_info.get_entity_id() # noqa: F841 - - for message in message_manager.get_received_message_list(): - if isinstance(message, CommandScout): - if ( - message.get_command_executor_agent_entity_id() - == agent_info.get_entity_id() - ): - self._recent_command = message - self._command_executor_scout.set_command(command=message) - if isinstance(message, CommandPolice): - if ( - message.get_command_executor_agent_entity_id() - == agent_info.get_entity_id() - ): - self._recent_command = message - self._command_executor_police.set_command(message) - - if self._recent_command is not None: - action: Optional[Action] = None - if isinstance(self._recent_command, CommandScout): - action = self._command_executor_scout.calculate().get_action() - elif isinstance(self._recent_command, CommandFire): - action = self._command_executor_police.calculate().get_action() - if action is not None: - self._logger.debug( - f"action decided by command: {action}", time=agent_info.get_time() - ) - return action - - target_entity_id = self._road_detector.calculate().get_target_entity_id() - self._logger.debug( - f"road detector target_entity_id: {target_entity_id}", - time=agent_info.get_time(), - ) - if target_entity_id is not None: - action = ( - self._action_ext_clear.set_target_entity_id(target_entity_id) - .calculate() - .get_action() - ) - if action is not None: - self._logger.debug(f"action: {action}", time=agent_info.get_time()) - return action - - target_entity_id = self._search.calculate().get_target_entity_id() + def initialize( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + message_manager: MessageManager, + develop_data: DevelopData, + ) -> None: + # world_info.index_class() + super().initialize( + agent_info, + world_info, + scenario_info, + module_manager, + precompute_data, + message_manager, + develop_data, + ) + # self._clear_distance = int( + # scenario_info.get_value("clear.repair.distance", "null") + # ) + + self._search: Search = cast( + Search, + module_manager.get_module( + "DefaultTacticsPoliceForce.Search", + "adf_core_python.implement.module.complex.default_search.DefaultSearch", + ), + ) + 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._command_executor_police = module_manager.get_command_executor( + "DefaultTacticsPoliceForce.CommandExecutorPolice", + "adf_core_python.implement.centralized.default_command_executor_police.DefaultCommandExecutorPolice", + ) + self._command_executor_scout = module_manager.get_command_executor( + "DefaultTacticsPoliceForce.CommandExecutorScout", + "adf_core_python.implement.centralized.default_command_executor_scout_police.DefaultCommandExecutorScoutPolice", + ) + + self.register_module(self._search) + self.register_module(self._road_detector) + self.register_action(self._action_ext_clear) + self.register_action(self._action_ext_move) + self.register_command_executor(self._command_executor_police) + self.register_command_executor(self._command_executor_scout) + + self._recent_command: Optional[StandardMessage] = None + + 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, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + message_manager: MessageManager, + develop_data: DevelopData, + ) -> None: + self.module_resume(precompute_data) + + def prepare( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + develop_data: DevelopData, + ) -> None: + self.module_prepare() + + def think( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + message_manager: MessageManager, + develop_data: DevelopData, + ) -> Action: + self.reset_count() + self.module_update_info(message_manager) + + agent: PoliceForce = cast(PoliceForce, agent_info.get_myself()) # noqa: F841 + entity_id = agent_info.get_entity_id() # noqa: F841 + + for message in message_manager.get_received_message_list(): + if isinstance(message, CommandScout): + if message.get_command_executor_agent_entity_id() == agent_info.get_entity_id(): + self._recent_command = message + self._command_executor_scout.set_command(command=message) + if isinstance(message, CommandPolice): + if message.get_command_executor_agent_entity_id() == agent_info.get_entity_id(): + self._recent_command = message + self._command_executor_police.set_command(message) + + if self._recent_command is not None: + action: Optional[Action] = None + if isinstance(self._recent_command, CommandScout): + action = self._command_executor_scout.calculate().get_action() + elif isinstance(self._recent_command, CommandFire): + action = self._command_executor_police.calculate().get_action() + if action is not None: self._logger.debug( - f"search target_entity_id: {target_entity_id}", time=agent_info.get_time() + f"action decided by command: {action}", time=agent_info.get_time() ) - if target_entity_id is not None: - action = ( - self._action_ext_move.set_target_entity_id(target_entity_id) - .calculate() - .get_action() - ) - if action is not None: - self._logger.debug(f"action: {action}", time=agent_info.get_time()) - return action - - return ActionRest() + return action + + target_entity_id = self._road_detector.calculate().get_target_entity_id() + self._logger.debug( + f"road detector target_entity_id: {target_entity_id}", + time=agent_info.get_time(), + ) + if target_entity_id is not None: + action = ( + self._action_ext_clear.set_target_entity_id(target_entity_id) + .calculate() + .get_action() + ) + if action is not None: + self._logger.debug(f"action: {action}", time=agent_info.get_time()) + return action + + target_entity_id = self._search.calculate().get_target_entity_id() + self._logger.debug( + f"search target_entity_id: {target_entity_id}", time=agent_info.get_time() + ) + if target_entity_id is not None: + action = ( + self._action_ext_move.set_target_entity_id(target_entity_id) + .calculate() + .get_action() + ) + if action is not None: + self._logger.debug(f"action: {action}", time=agent_info.get_time()) + return action + + return ActionRest() diff --git a/src/adf_core_python/implement/tactics/default_tactics_police_office.py b/src/adf_core_python/implement/tactics/default_tactics_police_office.py index d605244..d830de2 100644 --- a/src/adf_core_python/implement/tactics/default_tactics_police_office.py +++ b/src/adf_core_python/implement/tactics/default_tactics_police_office.py @@ -11,91 +11,89 @@ from adf_core_python.core.agent.precompute.precompute_data import PrecomputeData from adf_core_python.core.component.centralized.command_picker import CommandPicker from adf_core_python.core.component.module.complex.target_allocator import ( - TargetAllocator, + TargetAllocator, ) from adf_core_python.core.component.tactics.tactics_police_office import ( - TacticsPoliceOffice, + TacticsPoliceOffice, ) class DefaultTacticsPoliceOffice(TacticsPoliceOffice): - def initialize( - self, - agent_info: AgentInfo, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - precompute_data: PrecomputeData, - message_manager: MessageManager, - develop_data: DevelopData, - ) -> None: - self._allocator: TargetAllocator = cast( - TargetAllocator, - module_manager.get_module( - "DefaultTacticsPoliceOffice.TargetAllocator", - "adf_core_python.implement.module.complex.default_police_target_allocator.DefaultPoliceTargetAllocator", - ), - ) - self._picker: CommandPicker = module_manager.get_command_picker( - "DefaultTacticsPoliceOffice.CommandPicker", - "adf_core_python.implement.centralized.default_command_picker_police.DefaultCommandPickerPolice", - ) - self.register_module(self._allocator) - self.register_command_picker(self._picker) + def initialize( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + message_manager: MessageManager, + develop_data: DevelopData, + ) -> None: + self._allocator: TargetAllocator = cast( + TargetAllocator, + module_manager.get_module( + "DefaultTacticsPoliceOffice.TargetAllocator", + "adf_core_python.implement.module.complex.default_police_target_allocator.DefaultPoliceTargetAllocator", + ), + ) + self._picker: CommandPicker = module_manager.get_command_picker( + "DefaultTacticsPoliceOffice.CommandPicker", + "adf_core_python.implement.centralized.default_command_picker_police.DefaultCommandPickerPolice", + ) + self.register_module(self._allocator) + self.register_command_picker(self._picker) - def resume( - 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_resume(precompute_data) + def resume( + 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_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 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, - world_info: WorldInfo, - scenario_info: ScenarioInfo, - module_manager: ModuleManager, - precompute_data: PrecomputeData, - develop_data: DevelopData, - ) -> None: - self.module_prepare() + def prepare( + self, + agent_info: AgentInfo, + world_info: WorldInfo, + scenario_info: ScenarioInfo, + module_manager: ModuleManager, + precompute_data: PrecomputeData, + develop_data: DevelopData, + ) -> None: + self.module_prepare() - def think( - 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_update_info(message_manager) + def think( + 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_update_info(message_manager) - allocation_result: dict[EntityID, EntityID] = ( - self._allocator.calculate().get_result() - ) - for message in ( - self._picker.set_allocator_result(allocation_result) - .calculate() - .get_result() - ): - message_manager.add_message(message) + allocation_result: dict[EntityID, EntityID] = ( + self._allocator.calculate().get_result() + ) + for message in ( + self._picker.set_allocator_result(allocation_result).calculate().get_result() + ): + message_manager.add_message(message) diff --git a/src/adf_core_python/launcher.py b/src/adf_core_python/launcher.py index 0982f70..e69b17a 100644 --- a/src/adf_core_python/launcher.py +++ b/src/adf_core_python/launcher.py @@ -8,138 +8,138 @@ class Launcher: - def __init__( - self, - launcher_config_file: str, - ) -> None: - try: - resource.setrlimit(resource.RLIMIT_NOFILE, (8192, 1048576)) - except Exception as e: - print( - f"Failed to set resource limit: {e}. " - "This may cause issues with the number of open files." - ) + def __init__( + self, + launcher_config_file: str, + ) -> None: + try: + resource.setrlimit(resource.RLIMIT_NOFILE, (8192, 1048576)) + except Exception as e: + print( + f"Failed to set resource limit: {e}. " + "This may cause issues with the number of open files." + ) - self.launcher_config = Config(launcher_config_file) + self.launcher_config = Config(launcher_config_file) - parser = argparse.ArgumentParser(description="Agent Launcher") + parser = argparse.ArgumentParser(description="Agent Launcher") - parser.add_argument( - "--host", - type=str, - help="host name(Default: localhost)", - metavar="", - ) - parser.add_argument( - "--port", - type=int, - help="port number(Default: 27931)", - metavar="", - ) - parser.add_argument( - "-a", - "--ambulanceteam", - type=int, - help="number of ambulance agents(Default: all ambulance)", - metavar="", - ) - parser.add_argument( - "-f", - "--firebrigade", - type=int, - help="number of firebrigade agents(Default: all firebrigade)", - metavar="", - ) - parser.add_argument( - "-p", - "--policeforce", - type=int, - help="number of policeforce agents(Default: all policeforce)", - metavar="", - ) - parser.add_argument( - "-ac", - "--ambulancecenter", - type=int, - help="number of ambulance center agents(Default: all ambulance center)", - metavar="", - ) - parser.add_argument( - "-fs", - "--firestation", - type=int, - help="number of fire station agents(Default: all fire station)", - metavar="", - ) - parser.add_argument( - "-po", - "--policeoffice", - type=int, - help="number of police office agents(Default: all police office)", - metavar="", - ) - parser.add_argument( - "--precompute", - action="store_true", - help="precompute flag", - ) - parser.add_argument( - "--timeout", - type=int, - help="timeout in seconds", - metavar="", - ) - parser.add_argument("--debug", action="store_true", help="debug flag") - parser.add_argument( - "--java", - action="store_true", - help="using java module flag", - ) - args = parser.parse_args() + parser.add_argument( + "--host", + type=str, + help="host name(Default: localhost)", + metavar="", + ) + parser.add_argument( + "--port", + type=int, + help="port number(Default: 27931)", + metavar="", + ) + parser.add_argument( + "-a", + "--ambulanceteam", + type=int, + help="number of ambulance agents(Default: all ambulance)", + metavar="", + ) + parser.add_argument( + "-f", + "--firebrigade", + type=int, + help="number of firebrigade agents(Default: all firebrigade)", + metavar="", + ) + parser.add_argument( + "-p", + "--policeforce", + type=int, + help="number of policeforce agents(Default: all policeforce)", + metavar="", + ) + parser.add_argument( + "-ac", + "--ambulancecenter", + type=int, + help="number of ambulance center agents(Default: all ambulance center)", + metavar="", + ) + parser.add_argument( + "-fs", + "--firestation", + type=int, + help="number of fire station agents(Default: all fire station)", + metavar="", + ) + parser.add_argument( + "-po", + "--policeoffice", + type=int, + help="number of police office agents(Default: all police office)", + metavar="", + ) + parser.add_argument( + "--precompute", + action="store_true", + help="precompute flag", + ) + parser.add_argument( + "--timeout", + type=int, + help="timeout in seconds", + metavar="", + ) + parser.add_argument("--debug", action="store_true", help="debug flag") + parser.add_argument( + "--java", + action="store_true", + help="using java module flag", + ) + args = parser.parse_args() - config_map = { - ConfigKey.KEY_KERNEL_HOST: args.host, - ConfigKey.KEY_KERNEL_PORT: args.port, - ConfigKey.KEY_AMBULANCE_TEAM_COUNT: args.ambulanceteam, - ConfigKey.KEY_FIRE_BRIGADE_COUNT: args.firebrigade, - ConfigKey.KEY_POLICE_FORCE_COUNT: args.policeforce, - ConfigKey.KEY_AMBULANCE_CENTRE_COUNT: args.ambulancecenter, - ConfigKey.KEY_FIRE_STATION_COUNT: args.firestation, - ConfigKey.KEY_POLICE_OFFICE_COUNT: args.policeoffice, - ConfigKey.KEY_PRECOMPUTE: args.precompute, - ConfigKey.KEY_KERNEL_TIMEOUT: args.timeout, - ConfigKey.KEY_DEBUG_FLAG: args.debug, - ConfigKey.KEY_GATEWAY_FLAG: args.java, - } + config_map = { + ConfigKey.KEY_KERNEL_HOST: args.host, + ConfigKey.KEY_KERNEL_PORT: args.port, + ConfigKey.KEY_AMBULANCE_TEAM_COUNT: args.ambulanceteam, + ConfigKey.KEY_FIRE_BRIGADE_COUNT: args.firebrigade, + ConfigKey.KEY_POLICE_FORCE_COUNT: args.policeforce, + ConfigKey.KEY_AMBULANCE_CENTRE_COUNT: args.ambulancecenter, + ConfigKey.KEY_FIRE_STATION_COUNT: args.firestation, + ConfigKey.KEY_POLICE_OFFICE_COUNT: args.policeoffice, + ConfigKey.KEY_PRECOMPUTE: args.precompute, + ConfigKey.KEY_KERNEL_TIMEOUT: args.timeout, + ConfigKey.KEY_DEBUG_FLAG: args.debug, + ConfigKey.KEY_GATEWAY_FLAG: args.java, + } - for key, value in config_map.items(): - if value is not None: - self.launcher_config.set_value(key, value) + for key, value in config_map.items(): + if value is not None: + self.launcher_config.set_value(key, value) - configure_logger() - self.logger = get_logger(__name__) + configure_logger() + self.logger = get_logger(__name__) - self.logger.debug(f"launcher_config: {self.launcher_config}") + self.logger.debug(f"launcher_config: {self.launcher_config}") - def launch(self) -> None: - agent_launcher: AgentLauncher = AgentLauncher( - self.launcher_config, - ) - agent_launcher.init_connector() + def launch(self) -> None: + agent_launcher: AgentLauncher = AgentLauncher( + self.launcher_config, + ) + agent_launcher.init_connector() - try: - agent_launcher.launch() - except KeyboardInterrupt: - self.logger.info("Agent launcher interrupted") - except Exception as e: - self.logger.exception("Agent launcher failed", exc_info=e) - raise e - self.logger.info("Agent launcher finished") + try: + agent_launcher.launch() + except KeyboardInterrupt: + self.logger.info("Agent launcher interrupted") + except Exception as e: + self.logger.exception("Agent launcher failed", exc_info=e) + raise e + self.logger.info("Agent launcher finished") if __name__ == "__main__": - launcher = Launcher( - "config/launcher.yaml", - ) + launcher = Launcher( + "config/launcher.yaml", + ) - launcher.launch() + launcher.launch() diff --git a/tests/core/agent/config/test_module_config.py b/tests/core/agent/config/test_module_config.py index af0aa95..ffb8ca5 100644 --- a/tests/core/agent/config/test_module_config.py +++ b/tests/core/agent/config/test_module_config.py @@ -6,43 +6,43 @@ class TestModuleConfig: - def test_can_read_from_yaml(self) -> None: - script_dir = os.path.dirname(os.path.abspath(__file__)) - config_file_path = os.path.join(script_dir, "module.yaml") - config = ModuleConfig(config_file_path) - assert ( - config.get_value("DefaultTacticsPoliceOffice.TargetAllocator") - == "sample_team.module.complex.SamplePoliceTargetAllocator" - ) - assert ( - config.get_value("DefaultTacticsPoliceOffice.CommandPicker") - == "adf_core_python.implement.centralized.DefaultCommandPickerPolice" - ) - assert ( - config.get_value("SampleSearch.PathPlanning.Ambulance") - == "adf_core_python.implement.module.algorithm.DijkstraPathPlanning" - ) - assert ( - config.get_value("SampleSearch.PathPlanning.Fire") - == "adf_core_python.implement.module.algorithm.DijkstraPathPlanning" - ) - assert ( - config.get_value("SampleSearch.PathPlanning.Police") - == "adf_core_python.implement.module.algorithm.DijkstraPathPlanning" - ) - assert ( - config.get_value("SampleSearch.Clustering.Ambulance") - == "adf_core_python.implement.module.algorithm.KMeansClustering" - ) - assert ( - config.get_value("SampleSearch.Clustering.Fire") - == "adf_core_python.implement.module.algorithm.KMeansClustering" - ) - assert ( - config.get_value("SampleSearch.Clustering.Police") - == "adf_core_python.implement.module.algorithm.KMeansClustering" - ) + def test_can_read_from_yaml(self) -> None: + script_dir = os.path.dirname(os.path.abspath(__file__)) + config_file_path = os.path.join(script_dir, "module.yaml") + config = ModuleConfig(config_file_path) + assert ( + config.get_value("DefaultTacticsPoliceOffice.TargetAllocator") + == "sample_team.module.complex.SamplePoliceTargetAllocator" + ) + assert ( + config.get_value("DefaultTacticsPoliceOffice.CommandPicker") + == "adf_core_python.implement.centralized.DefaultCommandPickerPolice" + ) + assert ( + config.get_value("SampleSearch.PathPlanning.Ambulance") + == "adf_core_python.implement.module.algorithm.DijkstraPathPlanning" + ) + assert ( + config.get_value("SampleSearch.PathPlanning.Fire") + == "adf_core_python.implement.module.algorithm.DijkstraPathPlanning" + ) + assert ( + config.get_value("SampleSearch.PathPlanning.Police") + == "adf_core_python.implement.module.algorithm.DijkstraPathPlanning" + ) + assert ( + config.get_value("SampleSearch.Clustering.Ambulance") + == "adf_core_python.implement.module.algorithm.KMeansClustering" + ) + assert ( + config.get_value("SampleSearch.Clustering.Fire") + == "adf_core_python.implement.module.algorithm.KMeansClustering" + ) + assert ( + config.get_value("SampleSearch.Clustering.Police") + == "adf_core_python.implement.module.algorithm.KMeansClustering" + ) - def test_if_file_not_found(self) -> None: - with pytest.raises(FileNotFoundError): - ModuleConfig("not_found.yaml") + def test_if_file_not_found(self) -> None: + with pytest.raises(FileNotFoundError): + ModuleConfig("not_found.yaml") diff --git a/tests/core/agent/develop/test_develop.py b/tests/core/agent/develop/test_develop.py index 877e50a..9501be4 100644 --- a/tests/core/agent/develop/test_develop.py +++ b/tests/core/agent/develop/test_develop.py @@ -6,17 +6,17 @@ class TestDevelopData: - def test_can_read_from_yaml(self) -> None: - script_dir = os.path.dirname(os.path.abspath(__file__)) - develop_file_path = os.path.join(script_dir, "develop.json") - develop_data = DevelopData(True, develop_file_path) + def test_can_read_from_yaml(self) -> None: + script_dir = os.path.dirname(os.path.abspath(__file__)) + develop_file_path = os.path.join(script_dir, "develop.json") + develop_data = DevelopData(True, develop_file_path) - assert develop_data.get_value("string") == "test" - assert develop_data.get_value("number") == 1 - assert develop_data.get_value("boolean") is True - assert develop_data.get_value("dict") == {"test": "test"} - assert develop_data.get_value("array") == ["test", "test"] + assert develop_data.get_value("string") == "test" + assert develop_data.get_value("number") == 1 + assert develop_data.get_value("boolean") is True + assert develop_data.get_value("dict") == {"test": "test"} + assert develop_data.get_value("array") == ["test", "test"] - def test_if_file_not_found(self) -> None: - with pytest.raises(FileNotFoundError): - DevelopData(True, "not_found.json") + def test_if_file_not_found(self) -> None: + with pytest.raises(FileNotFoundError): + DevelopData(True, "not_found.json") diff --git a/tests/core/agent/module/test_module_manager.py b/tests/core/agent/module/test_module_manager.py index 470061e..d6ec498 100644 --- a/tests/core/agent/module/test_module_manager.py +++ b/tests/core/agent/module/test_module_manager.py @@ -8,25 +8,25 @@ class TestModuleManager: - @pytest.mark.skip(reason="一時的に無効化") - def test_can_get_module(self) -> None: - script_dir = os.path.dirname(os.path.abspath(__file__)) - config_file_path = os.path.join(script_dir, "module.yaml") - config = ModuleConfig(config_file_path) - config.set_value( - "test_module", - "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", - ) - module_manager = self.create_module_manager(config) - module = module_manager.get_module("test_module", "test_module") - assert isinstance(module, AbstractModule) - assert module.__class__.__name__ == "AStarPathPlanning" + @pytest.mark.skip(reason="一時的に無効化") + def test_can_get_module(self) -> None: + script_dir = os.path.dirname(os.path.abspath(__file__)) + config_file_path = os.path.join(script_dir, "module.yaml") + config = ModuleConfig(config_file_path) + config.set_value( + "test_module", + "adf_core_python.implement.module.algorithm.a_star_path_planning.AStarPathPlanning", + ) + module_manager = self.create_module_manager(config) + module = module_manager.get_module("test_module", "test_module") + assert isinstance(module, AbstractModule) + assert module.__class__.__name__ == "AStarPathPlanning" - def create_module_manager(self, config: ModuleConfig) -> ModuleManager: - return ModuleManager( - None, # type: ignore - None, # type: ignore - None, # type: ignore - config, - None, # type: ignore - ) + def create_module_manager(self, config: ModuleConfig) -> ModuleManager: + return ModuleManager( + None, # type: ignore + None, # type: ignore + None, # type: ignore + config, + None, # type: ignore + ) From 810dfc7f17bd30a83aa3a0d725b7eab825919677 Mon Sep 17 00:00:00 2001 From: shima004 Date: Mon, 4 Aug 2025 15:26:44 +0900 Subject: [PATCH 06/13] =?UTF-8?q?feat:=20docs=E3=83=87=E3=82=A3=E3=83=AC?= =?UTF-8?q?=E3=82=AF=E3=83=88=E3=83=AA=E3=82=92mypy=E3=81=AE=E9=99=A4?= =?UTF-8?q?=E5=A4=96=E3=83=AA=E3=82=B9=E3=83=88=E3=81=AB=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 0e429bd..40a3160 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -133,6 +133,7 @@ disallow_untyped_defs = true no_implicit_optional = true check_untyped_defs = true warn_redundant_casts = true +exclude = ["docs"] [tool.uv.sources] rcrscore = { git = "https://github.com/adf-python/rcrs-core-python" , tag = "v0.2.0" } From 365e3e08ed3f2ee46c09830d190d9ae81c97f8ea Mon Sep 17 00:00:00 2001 From: shima004 Date: Mon, 4 Aug 2025 15:26:52 +0900 Subject: [PATCH 07/13] =?UTF-8?q?feat:=20=E5=9E=8B=E3=83=92=E3=83=B3?= =?UTF-8?q?=E3=83=88=E3=82=92=E8=BF=BD=E5=8A=A0=E3=81=97=E3=81=A6=E9=96=A2?= =?UTF-8?q?=E6=95=B0=E3=81=AE=E6=98=8E=E7=A2=BA=E3=81=95=E3=82=92=E5=90=91?= =?UTF-8?q?=E4=B8=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/launcher/connect/connection.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/adf_core_python/core/launcher/connect/connection.py b/src/adf_core_python/core/launcher/connect/connection.py index 660d987..3923471 100644 --- a/src/adf_core_python/core/launcher/connect/connection.py +++ b/src/adf_core_python/core/launcher/connect/connection.py @@ -59,7 +59,7 @@ def send_msg(self, msg: Any) -> None: Connection._write_msg(msg, self.socket) @staticmethod - def _write_int32(value, sock): + def _write_int32(value: int, sock: socket.socket) -> None: b = [ ((value >> 24) & 0xFF), ((value >> 16) & 0xFF), @@ -70,7 +70,7 @@ def _write_int32(value, sock): sock.sendall(bytes(b)) @staticmethod - def _readnbytes(sock, n): + def _readnbytes(sock: socket.socket, n: int) -> bytes: buff = b"" while n > 0: b = sock.recv(n) @@ -81,7 +81,7 @@ def _readnbytes(sock, n): return buff @staticmethod - def _read_int32(sock): + def _read_int32(sock: socket.socket) -> int: byte_array = Connection._readnbytes(sock, 4) value = int( ((byte_array[0]) << 24) @@ -92,15 +92,14 @@ def _read_int32(sock): return value @staticmethod - def _write_msg(msg, sock): + def _write_msg(msg: Any, sock: socket.socket) -> None: out = msg.SerializeToString() Connection._write_int32(len(out), sock) sock.sendall(out) @staticmethod - def _read_msg(sock): - # await reader.read(1) + def _read_msg(sock: socket.socket) -> RCRSProto_pb2.MessageProto: size = Connection._read_int32(sock) content = Connection._readnbytes(sock, size) message = RCRSProto_pb2.MessageProto() From 1cc2fa6a31eb9470e066aa21d1c8efc7c0239c28 Mon Sep 17 00:00:00 2001 From: shima004 Date: Mon, 4 Aug 2025 15:27:15 +0900 Subject: [PATCH 08/13] =?UTF-8?q?feat:=20README=E3=81=ABPoetry=E3=81=8B?= =?UTF-8?q?=E3=82=89uv=E3=81=B8=E3=81=AE=E7=A7=BB=E8=A1=8C=E3=81=A8Python?= =?UTF-8?q?=E3=83=90=E3=83=BC=E3=82=B8=E3=83=A7=E3=83=B3=E3=81=AE=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E3=81=AE=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index da12692..d0f490a 100644 --- a/README.md +++ b/README.md @@ -8,32 +8,34 @@ ### Prerequisites -- Python (3.12 or higher) -- Poetry (1.8.3 or higher) +- Python (3.13 or higher) +- uv (0.8.2 or higher) ### Installation ```bash -poetry install +uv sync ``` ### Run Agent ```bash -poetry run python ./adf_core_python/launcher.py +uv run python ./adf_core_python/launcher.py # get help -poetry run python ./adf_core_python/launcher.py -h +uv run python ./adf_core_python/launcher.py -h ``` ### Build ```bash -poetry build +uv build ``` ### Pre Commit ```bash -poetry run task precommit +uv run ruff format . +uv run ruff check . +uv run mypy . ``` From 1c6c26d176c3bffe866c436e00176994c563f663 Mon Sep 17 00:00:00 2001 From: shima004 Date: Mon, 4 Aug 2025 15:47:12 +0900 Subject: [PATCH 09/13] =?UTF-8?q?feat:=20CI=E3=81=A7ruff=E3=81=A8mypy?= =?UTF-8?q?=E3=81=AE=E5=AE=9F=E8=A1=8C=E3=81=ABuv=E3=82=92=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E3=81=99=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E5=A4=89?= =?UTF-8?q?=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 24ebbf5..95a231d 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -55,10 +55,10 @@ jobs: run: echo ${{ github.workspace }}/.venv/bin >> $GITHUB_PATH - name: Check ruff version - run: ruff --version + run: uv run ruff --version - name: Run ruff format check - run: ruff format --check . + run: uv run ruff format --check . ruff-lint: needs: setup @@ -77,10 +77,10 @@ jobs: run: echo ${{ github.workspace }}/.venv/bin >> $GITHUB_PATH - name: Check ruff version - run: ruff --version + run: uv run ruff --version - name: Run ruff lint - run: ruff check --output-format=github . + run: uv run ruff check --output-format=github . mypy-type-check: needs: setup @@ -99,10 +99,10 @@ jobs: run: echo ${{ github.workspace }}/.venv/bin >> $GITHUB_PATH - name: Check mypy version - run: mypy --version + run: uv run mypy --version - name: Run mypy type check - run: mypy . + run: uv run mypy . pytest: needs: setup From d3be3dd961d6e8164ba9c9ca1f40c9aa44170e1a Mon Sep 17 00:00:00 2001 From: shima004 Date: Mon, 4 Aug 2025 15:52:41 +0900 Subject: [PATCH 10/13] =?UTF-8?q?feat:=20CI=E3=81=AE=E8=A8=AD=E5=AE=9A?= =?UTF-8?q?=E3=82=92uv=E3=82=92=E4=BD=BF=E7=94=A8=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=E6=9B=B4=E6=96=B0=E3=81=97=E3=80=81?= =?UTF-8?q?=E3=82=AD=E3=83=A3=E3=83=83=E3=82=B7=E3=83=A5=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E3=82=92=E6=9C=80=E9=81=A9=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yaml | 93 ++++++++++++++------------------------- 1 file changed, 33 insertions(+), 60 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 95a231d..06c53ee 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -12,116 +12,89 @@ on: jobs: setup: + name: Setup ✅ runs-on: ubuntu-latest + outputs: + cache-hit: ${{ steps.setup_uv.outputs.cache-hit }} steps: - name: Checkout code uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v5 + - name: Install uv (+ enable cache) + id: setup_uv + uses: astral-sh/setup-uv@v6 with: - python-version: 3.12 + enable-cache: true - - name: Cache virtual environment - id: cached-virtualenv - uses: actions/cache@v4 - with: - path: .venv - key: ${{ runner.os }}-venv-${{ hashFiles('**/uv.lock') }} - - - name: Install dependencies - if: steps.cached-virtualenv.outputs.cache-hit != 'true' - run: | - python -m venv .venv - source .venv/bin/activate - pip install --upgrade pip - pip install uv - uv sync + - name: Sync dependencies + run: uv sync --locked --dev + + - name: Prune uv cache (optimized for CI) + run: uv cache prune --ci ruff-format: + name: Ruff format check needs: setup runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - - name: Restore virtual environment cache - uses: actions/cache@v4 + - name: Install uv + restore cache + uses: astral-sh/setup-uv@v6 with: - path: .venv - key: ${{ runner.os }}-venv-${{ hashFiles('**/uv.lock') }} - - - name: Set path - run: echo ${{ github.workspace }}/.venv/bin >> $GITHUB_PATH + enable-cache: true - - name: Check ruff version - run: uv run ruff --version - - - name: Run ruff format check + - name: Check ruff formatting run: uv run ruff format --check . ruff-lint: + name: Ruff lint check needs: setup runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - - name: Restore virtual environment cache - uses: actions/cache@v4 + - name: Install uv + restore cache + uses: astral-sh/setup-uv@v6 with: - path: .venv - key: ${{ runner.os }}-venv-${{ hashFiles('**/poetry.lock') }} - - - name: Set path - run: echo ${{ github.workspace }}/.venv/bin >> $GITHUB_PATH - - - name: Check ruff version - run: uv run ruff --version + enable-cache: true - name: Run ruff lint run: uv run ruff check --output-format=github . mypy-type-check: + name: MyPy type check needs: setup runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - - name: Restore virtual environment cache - uses: actions/cache@v4 + - name: Install uv + restore cache + uses: astral-sh/setup-uv@v6 with: - path: .venv - key: ${{ runner.os }}-venv-${{ hashFiles('**/poetry.lock') }} - - - name: Set path - run: echo ${{ github.workspace }}/.venv/bin >> $GITHUB_PATH + enable-cache: true - - name: Check mypy version - run: uv run mypy --version - - - name: Run mypy type check - run: uv run mypy . + - name: Run mypy + run: uv run --frozen mypy . pytest: + name: PyTest needs: setup runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - - name: Restore virtual environment cache - uses: actions/cache@v4 + - name: Install uv + restore cache + uses: astral-sh/setup-uv@v6 with: - path: .venv - key: ${{ runner.os }}-venv-${{ hashFiles('**/poetry.lock') }} - - - name: Set path - run: echo ${{ github.workspace }}/.venv/bin >> $GITHUB_PATH + enable-cache: true - - name: Run pytest - run: pytest tests/ + - name: Run tests + run: uv run --frozen pytest tests/ publish: runs-on: ubuntu-latest From d72d84c8c0ddfbe54728aa189c2e85dc2b44aa1b Mon Sep 17 00:00:00 2001 From: shima004 Date: Mon, 4 Aug 2025 15:54:58 +0900 Subject: [PATCH 11/13] =?UTF-8?q?feat:=20CI=E3=81=AE=E3=82=BB=E3=83=83?= =?UTF-8?q?=E3=83=88=E3=82=A2=E3=83=83=E3=83=97=E5=90=8D=E3=81=8B=E3=82=89?= =?UTF-8?q?=E7=B5=B5=E6=96=87=E5=AD=97=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 06c53ee..787cd22 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -12,7 +12,7 @@ on: jobs: setup: - name: Setup ✅ + name: Setup runs-on: ubuntu-latest outputs: cache-hit: ${{ steps.setup_uv.outputs.cache-hit }} From 75a142bd390809da78523719c32290c992df5534 Mon Sep 17 00:00:00 2001 From: shima004 Date: Mon, 4 Aug 2025 16:00:49 +0900 Subject: [PATCH 12/13] =?UTF-8?q?feat:=20CI=E3=82=B8=E3=83=A7=E3=83=96?= =?UTF-8?q?=E5=90=8D=E3=82=92=E5=B0=8F=E6=96=87=E5=AD=97=E3=81=AB=E7=B5=B1?= =?UTF-8?q?=E4=B8=80=E3=81=97=E3=80=81pytest=E3=81=AE=E8=A8=AD=E5=AE=9A?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yaml | 8 ++++---- pyproject.toml | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 787cd22..9a39d65 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -33,7 +33,7 @@ jobs: run: uv cache prune --ci ruff-format: - name: Ruff format check + name: ruff-format needs: setup runs-on: ubuntu-latest steps: @@ -49,7 +49,7 @@ jobs: run: uv run ruff format --check . ruff-lint: - name: Ruff lint check + name: ruff-lint needs: setup runs-on: ubuntu-latest steps: @@ -65,7 +65,7 @@ jobs: run: uv run ruff check --output-format=github . mypy-type-check: - name: MyPy type check + name: mypy-type-check needs: setup runs-on: ubuntu-latest steps: @@ -81,7 +81,7 @@ jobs: run: uv run --frozen mypy . pytest: - name: PyTest + name: pytest needs: setup runs-on: ubuntu-latest steps: diff --git a/pyproject.toml b/pyproject.toml index 40a3160..0754df2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -135,5 +135,9 @@ check_untyped_defs = true warn_redundant_casts = true exclude = ["docs"] +[tool.pytest.ini_options] +pythonpath = ["src"] +testpaths = ["tests"] + [tool.uv.sources] rcrscore = { git = "https://github.com/adf-python/rcrs-core-python" , tag = "v0.2.0" } From 61f25e3879452c5b51e46aaebdb51f3148b1e218 Mon Sep 17 00:00:00 2001 From: shima004 Date: Mon, 4 Aug 2025 16:11:09 +0900 Subject: [PATCH 13/13] =?UTF-8?q?feat:=20pytest=E3=82=B8=E3=83=A7=E3=83=96?= =?UTF-8?q?=E3=82=92CI=E3=81=8B=E3=82=89=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yaml | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9a39d65..958de34 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -80,22 +80,6 @@ jobs: - name: Run mypy run: uv run --frozen mypy . - pytest: - name: pytest - needs: setup - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Install uv + restore cache - uses: astral-sh/setup-uv@v6 - with: - enable-cache: true - - - name: Run tests - run: uv run --frozen pytest tests/ - publish: runs-on: ubuntu-latest permissions: