From 7bad73c525a8e1ab3f5bd44af503837ecbaf8def Mon Sep 17 00:00:00 2001 From: ShotaAk Date: Fri, 16 May 2025 12:20:27 +0000 Subject: [PATCH 1/7] Add name field to tactic_base --- consai_game/consai_game/core/tactic/tactic_base.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/consai_game/consai_game/core/tactic/tactic_base.py b/consai_game/consai_game/core/tactic/tactic_base.py index eadc6e1c..9751e8f9 100644 --- a/consai_game/consai_game/core/tactic/tactic_base.py +++ b/consai_game/consai_game/core/tactic/tactic_base.py @@ -41,6 +41,7 @@ def __init__(self): """TacticBaseの初期化を行う関数.""" self._robot_id = -1 self._state = TacticState.BEFORE_INIT + self._name = self.__class__.__name__ @abstractmethod def run(self, world_model: WorldModel) -> MotionCommand: @@ -75,3 +76,8 @@ def state(self) -> TacticState: def state(self, value: TacticState) -> None: """戦術の状態を設定する関数.""" self._state = value + + @property + def name(self) -> str: + """戦術の名前を取得する関数.""" + return self._name From b3f2f844a39f92a8e2361d9bd32bee2890e22d2e Mon Sep 17 00:00:00 2001 From: ShotaAk Date: Fri, 16 May 2025 12:21:03 +0000 Subject: [PATCH 2/7] Implement get_robot_tactic_status to agent_scheduler_node --- consai_game/consai_game/core/tactic/agent.py | 19 +++++++++++++++ .../core/tactic/agent_scheduler_node.py | 11 +++++++++ .../core/tactic/robot_tactic_status.py | 24 +++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 consai_game/consai_game/core/tactic/robot_tactic_status.py diff --git a/consai_game/consai_game/core/tactic/agent.py b/consai_game/consai_game/core/tactic/agent.py index 4824e08d..dc2cb975 100644 --- a/consai_game/consai_game/core/tactic/agent.py +++ b/consai_game/consai_game/core/tactic/agent.py @@ -27,6 +27,7 @@ from consai_game.core.tactic.role import Role, RoleConst from consai_game.core.tactic.tactic_base import TacticState +from consai_game.core.tactic.robot_tactic_status import RobotTacticStatus from consai_game.world_model.world_model import WorldModel @@ -88,3 +89,21 @@ def reset_tactic(self) -> None: self.present_tactic = self.role.tactics[self.present_tactic_index] self.present_tactic.reset(self.role.robot_id) + + def get_robot_tactic_status(self) -> Optional[RobotTacticStatus]: + """ロボットが実行しているTacticの状態を取得する関数. + + TacticかロボットIDが無効な場合はNoneを返す. + """ + + if self.present_tactic is None: + return None + + if self.role.robot_id == RoleConst.INVALID_ROLE_ID: + return None + + return RobotTacticStatus( + robot_id=self.role.robot_id, + tactic_name=self.present_tactic.name, + tactic_state="none", # TODO: tacticが状態遷移器を持っていたら、状態をセットする + ) diff --git a/consai_game/consai_game/core/tactic/agent_scheduler_node.py b/consai_game/consai_game/core/tactic/agent_scheduler_node.py index c668b5ef..cf11ff93 100644 --- a/consai_game/consai_game/core/tactic/agent_scheduler_node.py +++ b/consai_game/consai_game/core/tactic/agent_scheduler_node.py @@ -27,6 +27,7 @@ from consai_game.core.tactic.agent import Agent from consai_game.core.tactic.role import Role +from consai_game.core.tactic.robot_tactic_status import RobotTacticStatus from consai_game.utils.process_info import process_info from consai_game.world_model.world_model import WorldModel @@ -78,3 +79,13 @@ def set_roles(self, roles: list[Role]): with self.lock: for role, agent in zip(roles, self.agents): agent.set_role(role) + + def get_robot_tactic_status(self) -> list[RobotTacticStatus]: + """各エージェントのロボットID, 戦術名, 戦術状態を取得する関数.""" + status_list = [] + + for agent in self.agents: + if status := agent.get_robot_tactic_status(): + status_list.append(status) + + return status_list diff --git a/consai_game/consai_game/core/tactic/robot_tactic_status.py b/consai_game/consai_game/core/tactic/robot_tactic_status.py new file mode 100644 index 00000000..904781d0 --- /dev/null +++ b/consai_game/consai_game/core/tactic/robot_tactic_status.py @@ -0,0 +1,24 @@ +# Copyright 2025 Roots +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from dataclasses import dataclass + + +@dataclass +class RobotTacticStatus: + """ロボットが実行しているTacticと状態をまとめたクラス""" + + robot_id: int + tactic_name: str + tactic_state: str From 37856cfc2b21712ac20ec59d79ff30f1ca7859c8 Mon Sep 17 00:00:00 2001 From: ShotaAk Date: Fri, 16 May 2025 12:23:59 +0000 Subject: [PATCH 3/7] Move visualize_msg_pub_node to visualization directory --- consai_game/consai_game/main.py | 2 +- .../visualize_msg_publisher_node.py | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename consai_game/consai_game/{world_model => visualization}/visualize_msg_publisher_node.py (100%) diff --git a/consai_game/consai_game/main.py b/consai_game/consai_game/main.py index d247ffb3..d643a76a 100755 --- a/consai_game/consai_game/main.py +++ b/consai_game/consai_game/main.py @@ -30,7 +30,7 @@ from consai_game.core.play.play_node import PlayNode from consai_game.core.tactic.agent_scheduler_node import AgentSchedulerNode -from consai_game.world_model.visualize_msg_publisher_node import VisualizeMsgPublisherNode +from consai_game.visualization.visualize_msg_publisher_node import VisualizeMsgPublisherNode from consai_game.world_model.world_model_provider_node import WorldModelProviderNode diff --git a/consai_game/consai_game/world_model/visualize_msg_publisher_node.py b/consai_game/consai_game/visualization/visualize_msg_publisher_node.py similarity index 100% rename from consai_game/consai_game/world_model/visualize_msg_publisher_node.py rename to consai_game/consai_game/visualization/visualize_msg_publisher_node.py From 23c9456201b7d88432dda234bcac4d5600da30eb Mon Sep 17 00:00:00 2001 From: ShotaAk Date: Fri, 16 May 2025 13:06:07 +0000 Subject: [PATCH 4/7] Visualize tactic name --- .../core/tactic/agent_scheduler_node.py | 2 +- consai_game/consai_game/main.py | 2 + .../visualize_msg_publisher_node.py | 39 ++++++++++++++++++- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/consai_game/consai_game/core/tactic/agent_scheduler_node.py b/consai_game/consai_game/core/tactic/agent_scheduler_node.py index cf11ff93..f8aa418c 100644 --- a/consai_game/consai_game/core/tactic/agent_scheduler_node.py +++ b/consai_game/consai_game/core/tactic/agent_scheduler_node.py @@ -80,7 +80,7 @@ def set_roles(self, roles: list[Role]): for role, agent in zip(roles, self.agents): agent.set_role(role) - def get_robot_tactic_status(self) -> list[RobotTacticStatus]: + def get_robot_tactic_status_list(self) -> list[RobotTacticStatus]: """各エージェントのロボットID, 戦術名, 戦術状態を取得する関数.""" status_list = [] diff --git a/consai_game/consai_game/main.py b/consai_game/consai_game/main.py index d643a76a..cfda420c 100755 --- a/consai_game/consai_game/main.py +++ b/consai_game/consai_game/main.py @@ -40,6 +40,8 @@ def main(): world_model = world_model_provider_node.world_model play_node.set_world_model(world_model) agent_scheduler_node.set_world_model(world_model) + + vis_msg_publisher_node.set_robot_tactic_status_list(agent_scheduler_node.get_robot_tactic_status_list()) vis_msg_publisher_node.publish(world_model) time.sleep(1 / UPDATE_HZ) diff --git a/consai_game/consai_game/visualization/visualize_msg_publisher_node.py b/consai_game/consai_game/visualization/visualize_msg_publisher_node.py index ca892641..834ca4b4 100644 --- a/consai_game/consai_game/visualization/visualize_msg_publisher_node.py +++ b/consai_game/consai_game/visualization/visualize_msg_publisher_node.py @@ -13,7 +13,7 @@ # limitations under the License. """ -WorldModelの情報を可視化トピックとしてpublishするノードの定義. +consai_gameの情報を可視化トピックとしてpublishするノードの定義. キックターゲットやボールの状態をObjectsメッセージとしてGUIに送信する. """ @@ -23,6 +23,7 @@ from consai_visualizer_msgs.msg import Objects, ShapeCircle, ShapeLine, ShapeText +from consai_game.core.tactic.robot_tactic_status import RobotTacticStatus from consai_game.world_model.ball_model import BallModel from consai_game.world_model.ball_activity_model import BallActivityModel, BallState from consai_game.world_model.robot_activity_model import RobotActivityModel @@ -32,12 +33,13 @@ class VisualizeMsgPublisherNode(Node): - """WorldModelをGUIに描画するためのトピックをpublishするノード.""" + """consai_gameの情報をGUIに描画するためのトピックをpublishするノード.""" def __init__(self): """ノードの初期化関数.""" super().__init__("vis_msg_publisher_node") self.pub_visualizer_objects = self.create_publisher(Objects, "visualizer_objects", qos.qos_profile_sensor_data) + self.robot_tactic_status_list: list[RobotTacticStatus] = None def publish(self, world_model: WorldModel): """WorldModelをGUIに描画するためのトピックをpublishする.""" @@ -55,6 +57,11 @@ def publish(self, world_model: WorldModel): self.pub_visualizer_objects.publish( self.robot_activity_to_vis_msg(robot_activity=world_model.robot_activity, robots=world_model.robots) ) + self.pub_visualizer_objects.publish(self.robot_tactic_status_to_vis_msg(robots=world_model.robots)) + + def set_robot_tactic_status_list(self, robot_tactic_status_list: list[RobotTacticStatus]): + """ロボットの戦術状態をセットすする関数""" + self.robot_tactic_status_list = robot_tactic_status_list def kick_target_to_vis_msg(self, kick_target: KickTargetModel, ball: BallModel) -> Objects: """kick_targetをObjectsメッセージに変換する.""" @@ -215,3 +222,31 @@ def robot_activity_to_vis_msg(self, robot_activity: RobotActivityModel, robots: vis_obj.circles.append(circle) return vis_obj + + def robot_tactic_status_to_vis_msg(self, robots: RobotsModel) -> Objects: + """ロボットの戦術状態をObjectsメッセージに変換する.""" + vis_obj = Objects() + vis_obj.layer = "game" + vis_obj.sub_layer = "tactic" + vis_obj.z_order = 4 + + if self.robot_tactic_status_list is None: + return vis_obj + + for status in self.robot_tactic_status_list: + + if status.robot_id not in robots.our_visible_robots: + continue + + robot_pos = robots.our_visible_robots[status.robot_id].pos + + text = ShapeText() + text.text = status.tactic_name + text.x = robot_pos.x + text.x = robot_pos.x + text.y = robot_pos.y + 0.2 + text.size = 10 + text.color.name = "violet" + vis_obj.texts.append(text) + + return vis_obj From 11fddd124f86a73cba3f224b6ad53cdeae7e9b5f Mon Sep 17 00:00:00 2001 From: ShotaAk Date: Sat, 17 May 2025 06:09:38 +0000 Subject: [PATCH 5/7] Add tacitc_state file --- consai_game/consai_game/core/tactic/agent.py | 2 +- .../consai_game/core/tactic/tactic_base.py | 10 +------- .../consai_game/core/tactic/tactic_state.py | 24 +++++++++++++++++++ .../consai_game/tactic/back_dribble.py | 4 +--- consai_game/consai_game/tactic/dribble.py | 4 +--- consai_game/consai_game/tactic/kick/kick.py | 5 ++-- consai_game/consai_game/tactic/kick/shoot.py | 5 ++-- consai_game/consai_game/tactic/man_mark.py | 6 +---- consai_game/consai_game/tactic/receive.py | 6 ----- consai_game/consai_game/tactic/stop.py | 7 +----- consai_game/consai_game/tactic/swab.py | 5 ++-- 11 files changed, 36 insertions(+), 42 deletions(-) create mode 100644 consai_game/consai_game/core/tactic/tactic_state.py diff --git a/consai_game/consai_game/core/tactic/agent.py b/consai_game/consai_game/core/tactic/agent.py index dc2cb975..97fe74eb 100644 --- a/consai_game/consai_game/core/tactic/agent.py +++ b/consai_game/consai_game/core/tactic/agent.py @@ -26,7 +26,7 @@ from consai_msgs.msg import MotionCommand from consai_game.core.tactic.role import Role, RoleConst -from consai_game.core.tactic.tactic_base import TacticState +from consai_game.core.tactic.tactic_state import TacticState from consai_game.core.tactic.robot_tactic_status import RobotTacticStatus from consai_game.world_model.world_model import WorldModel diff --git a/consai_game/consai_game/core/tactic/tactic_base.py b/consai_game/consai_game/core/tactic/tactic_base.py index 9751e8f9..36d6ab8d 100644 --- a/consai_game/consai_game/core/tactic/tactic_base.py +++ b/consai_game/consai_game/core/tactic/tactic_base.py @@ -19,21 +19,13 @@ """ from abc import ABC, abstractmethod -from enum import Enum, auto +from consai_game.core.tactic.tactic_state import TacticState from consai_game.world_model.world_model import WorldModel from consai_msgs.msg import MotionCommand -class TacticState(Enum): - """戦術の状態を表す列挙型.""" - - BEFORE_INIT = 0 - RUNNING = auto() - FINISHED = auto() - - class TacticBase(ABC): """戦術の基本クラス.""" diff --git a/consai_game/consai_game/core/tactic/tactic_state.py b/consai_game/consai_game/core/tactic/tactic_state.py new file mode 100644 index 00000000..2f9203c6 --- /dev/null +++ b/consai_game/consai_game/core/tactic/tactic_state.py @@ -0,0 +1,24 @@ +# Copyright 2025 Roots +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +from enum import Enum, auto + + +class TacticState(Enum): + """戦術の状態を表す列挙型.""" + + BEFORE_INIT = 0 + RUNNING = auto() + FINISHED = auto() diff --git a/consai_game/consai_game/tactic/back_dribble.py b/consai_game/consai_game/tactic/back_dribble.py index c9bbdd7e..5aaa85e4 100644 --- a/consai_game/consai_game/tactic/back_dribble.py +++ b/consai_game/consai_game/tactic/back_dribble.py @@ -19,7 +19,6 @@ """ from consai_game.core.tactic.tactic_base import TacticBase -from consai_game.core.tactic.tactic_base import TacticState from consai_game.world_model.world_model import WorldModel from consai_game.utils.generate_dummy_ball_position import generate_dummy_ball_position @@ -132,8 +131,7 @@ def __init__(self, x=0.0, y=0.0): def reset(self, robot_id: int) -> None: """Reset the tactic state for the specified robot.""" - self.robot_id = robot_id - self.state = TacticState.RUNNING + super().reset(robot_id) self.machine.reset() def run(self, world_model: WorldModel) -> MotionCommand: diff --git a/consai_game/consai_game/tactic/dribble.py b/consai_game/consai_game/tactic/dribble.py index a96f6373..162abedc 100644 --- a/consai_game/consai_game/tactic/dribble.py +++ b/consai_game/consai_game/tactic/dribble.py @@ -19,7 +19,6 @@ """ from consai_game.core.tactic.tactic_base import TacticBase -from consai_game.core.tactic.tactic_base import TacticState from consai_game.world_model.world_model import WorldModel from consai_game.utils.generate_dummy_ball_position import generate_dummy_ball_position @@ -126,8 +125,7 @@ def __init__(self, x=0.0, y=0.0): def reset(self, robot_id: int) -> None: """Reset the tactic state for the specified robot.""" - self.robot_id = robot_id - self.state = TacticState.RUNNING + super().reset(robot_id) self.machine.reset() def run(self, world_model: WorldModel) -> MotionCommand: diff --git a/consai_game/consai_game/tactic/kick/kick.py b/consai_game/consai_game/tactic/kick/kick.py index b189905c..fbd192d6 100644 --- a/consai_game/consai_game/tactic/kick/kick.py +++ b/consai_game/consai_game/tactic/kick/kick.py @@ -21,7 +21,7 @@ from consai_tools.geometry import geometry_tools as tool from consai_game.world_model.world_model import WorldModel -from consai_game.core.tactic.tactic_base import TacticBase, TacticState +from consai_game.core.tactic.tactic_base import TacticBase from consai_game.utils.generate_dummy_ball_position import generate_dummy_ball_position from transitions.extensions import GraphMachine @@ -113,8 +113,7 @@ def __init__(self, x=0.0, y=0.0, is_pass=False, is_tapping=False, is_setplay=Fal def reset(self, robot_id: int) -> None: """ロボットIDを設定し, Tacticの状態をRUNNINGにリセットする関数.""" - self.robot_id = robot_id - self.state = TacticState.RUNNING + super().reset(robot_id) self.machine.reset() def run(self, world_model: WorldModel) -> MotionCommand: diff --git a/consai_game/consai_game/tactic/kick/shoot.py b/consai_game/consai_game/tactic/kick/shoot.py index caf7bb71..2eb9406e 100644 --- a/consai_game/consai_game/tactic/kick/shoot.py +++ b/consai_game/consai_game/tactic/kick/shoot.py @@ -15,7 +15,7 @@ """シュート動作に関するTacticを定義するモジュール.""" from consai_game.world_model.world_model import WorldModel -from consai_game.core.tactic.tactic_base import TacticBase, TacticState +from consai_game.core.tactic.tactic_base import TacticBase from consai_game.tactic.kick.kick import Kick from consai_msgs.msg import MotionCommand, State2D @@ -31,8 +31,7 @@ def __init__(self): def reset(self, robot_id: int) -> None: """ロボットIDを設定し, Tacticの状態をRUNNINGにリセットする関数.""" - self.robot_id = robot_id - self.state = TacticState.RUNNING + super().reset(robot_id) self.kick_tactic.reset(robot_id) def run(self, world_model: WorldModel, x=6.0, y=0.0) -> MotionCommand: diff --git a/consai_game/consai_game/tactic/man_mark.py b/consai_game/consai_game/tactic/man_mark.py index d694cdd0..c2e720e2 100644 --- a/consai_game/consai_game/tactic/man_mark.py +++ b/consai_game/consai_game/tactic/man_mark.py @@ -1,4 +1,4 @@ -from consai_game.core.tactic.tactic_base import TacticBase, TacticState +from consai_game.core.tactic.tactic_base import TacticBase from consai_msgs.msg import MotionCommand from consai_msgs.msg import State2D from consai_game.world_model.world_model import WorldModel @@ -21,10 +21,6 @@ def __init__(self, target_robot_id: int, mark_distance: float = 0.5): # ペナルティエリア際に移動するためのマージン self.area_margin = 0.15 - def reset(self, robot_id: int): - self.robot_id = robot_id - self.state = TacticState.RUNNING - def run(self, world_model: WorldModel) -> MotionCommand: command = MotionCommand() command.robot_id = self.robot_id diff --git a/consai_game/consai_game/tactic/receive.py b/consai_game/consai_game/tactic/receive.py index fd617b25..52b10e66 100644 --- a/consai_game/consai_game/tactic/receive.py +++ b/consai_game/consai_game/tactic/receive.py @@ -19,7 +19,6 @@ """ from consai_game.core.tactic.tactic_base import TacticBase -from consai_game.core.tactic.tactic_base import TacticState from consai_game.world_model.world_model import WorldModel from consai_msgs.msg import MotionCommand @@ -43,11 +42,6 @@ def __init__(self): super().__init__() self.receive_pos = State2D() - def reset(self, robot_id: int) -> None: - """Reset the tactic state for the specified robot.""" - self.robot_id = robot_id - self.state = TacticState.RUNNING - def run(self, world_model: WorldModel, diff_angle_threshold: int = 20) -> MotionCommand: """Run the tactic and return a MotionCommand based on the ball's position and movement.""" command = MotionCommand() diff --git a/consai_game/consai_game/tactic/stop.py b/consai_game/consai_game/tactic/stop.py index 0142999a..7035ed44 100644 --- a/consai_game/consai_game/tactic/stop.py +++ b/consai_game/consai_game/tactic/stop.py @@ -17,7 +17,7 @@ from consai_msgs.msg import MotionCommand from consai_game.world_model.world_model import WorldModel -from consai_game.core.tactic.tactic_base import TacticBase, TacticState +from consai_game.core.tactic.tactic_base import TacticBase class Stop(TacticBase): @@ -27,11 +27,6 @@ def __init__(self): """StopTacticのインスタンスを初期化する関数.""" super().__init__() - def reset(self, robot_id: int) -> None: - """ロボットIDを設定し, Tacticの状態をRUNNINGにリセットする関数.""" - self.robot_id = robot_id - self.state = TacticState.RUNNING - def run(self, world_model: WorldModel) -> MotionCommand: """ロボットを停止させるためのMotionCommandを生成する関数.""" command = MotionCommand() diff --git a/consai_game/consai_game/tactic/swab.py b/consai_game/consai_game/tactic/swab.py index a9071ec2..0599be20 100644 --- a/consai_game/consai_game/tactic/swab.py +++ b/consai_game/consai_game/tactic/swab.py @@ -18,7 +18,7 @@ from consai_msgs.msg import State2D from consai_game.world_model.world_model import WorldModel -from consai_game.core.tactic.tactic_base import TacticBase, TacticState +from consai_game.core.tactic.tactic_base import TacticBase from transitions.extensions import GraphMachine @@ -73,8 +73,7 @@ def __init__(self): def reset(self, robot_id: int) -> None: """ロボットIDを設定し、Tacticの状態をRUNNINGにリセットする関数.""" - self.robot_id = robot_id - self.state = TacticState.RUNNING + super().reset(robot_id) self.machine.reset() def run(self, world_model: WorldModel) -> MotionCommand: From f9c61678409978b0b32841590261b50236241a8e Mon Sep 17 00:00:00 2001 From: ShotaAk Date: Sat, 17 May 2025 06:28:49 +0000 Subject: [PATCH 6/7] Refactor wrapper tactic --- .../core/tactic/wrapper_tactic_base.py | 37 +++++++++++++++++++ .../wrapper/allow_move_in_defense_area.py | 19 +--------- .../forbid_moving_in_placement_area.py | 19 +--------- .../tactic/wrapper/move_to_receive_pass.py | 19 +--------- .../consai_game/tactic/wrapper/slow_safe.py | 19 +--------- .../tactic/wrapper/with_avoid_ball_zone.py | 19 +--------- .../tactic/wrapper/wrapper_look_ball.py | 19 +--------- 7 files changed, 49 insertions(+), 102 deletions(-) create mode 100644 consai_game/consai_game/core/tactic/wrapper_tactic_base.py diff --git a/consai_game/consai_game/core/tactic/wrapper_tactic_base.py b/consai_game/consai_game/core/tactic/wrapper_tactic_base.py new file mode 100644 index 00000000..da455e8f --- /dev/null +++ b/consai_game/consai_game/core/tactic/wrapper_tactic_base.py @@ -0,0 +1,37 @@ +# Copyright 2025 Roots +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from consai_game.core.tactic.tactic_base import TacticBase + + +class WrapperTacticBase(TacticBase): + """WrapperTacticの基底クラス. + + WrapperTacticは、他のTacticをラップして、特定の機能を追加する + """ + + def __init__(self, tactic=TacticBase): + """内部tacticを初期化する関数.""" + super().__init__() + self.inner_tactic = tactic + + def reset(self, robot_id: int) -> None: + """inner_tacticをリセットする関数.""" + super().reset(robot_id) + self.inner_tactic.reset(robot_id) + + def exit(self): + """inner_tacticをexitする関数.""" + super().exit() + self.inner_tactic.exit() diff --git a/consai_game/consai_game/tactic/wrapper/allow_move_in_defense_area.py b/consai_game/consai_game/tactic/wrapper/allow_move_in_defense_area.py index 2fc7e5e0..c36541ea 100644 --- a/consai_game/consai_game/tactic/wrapper/allow_move_in_defense_area.py +++ b/consai_game/consai_game/tactic/wrapper/allow_move_in_defense_area.py @@ -14,31 +14,16 @@ from consai_msgs.msg import MotionCommand +from consai_game.core.tactic.wrapper_tactic_base import WrapperTacticBase from consai_game.world_model.world_model import WorldModel -from consai_game.core.tactic.tactic_base import TacticBase -class AllowMoveInDefenseArea(TacticBase): +class AllowMoveInDefenseArea(WrapperTacticBase): """ディフェンスエリア内での移動を許可するWrapperTactic." AllowMoveInDefenseArea(tactic=Position()) のように使用する """ - def __init__(self, tactic=TacticBase): - """inner_tacticを初期化する関数.""" - super().__init__() - self.inner_tactic = tactic - - def reset(self, robot_id: int) -> None: - """inner_tacticをリセットする関数.""" - super().reset(robot_id) - self.inner_tactic.reset(robot_id) - - def exit(self): - """inner_tacticをexitする関数.""" - super().exit() - self.inner_tactic.exit() - def run(self, world_model: WorldModel) -> MotionCommand: """ディフェンスエリア内での移動と、ボールとの接触を許可する.""" command = self.inner_tactic.run(world_model) diff --git a/consai_game/consai_game/tactic/wrapper/forbid_moving_in_placement_area.py b/consai_game/consai_game/tactic/wrapper/forbid_moving_in_placement_area.py index 110fad28..d3732024 100644 --- a/consai_game/consai_game/tactic/wrapper/forbid_moving_in_placement_area.py +++ b/consai_game/consai_game/tactic/wrapper/forbid_moving_in_placement_area.py @@ -14,31 +14,16 @@ from consai_msgs.msg import MotionCommand +from consai_game.core.tactic.wrapper_tactic_base import WrapperTacticBase from consai_game.world_model.world_model import WorldModel -from consai_game.core.tactic.tactic_base import TacticBase -class ForbidMovingInPlacementArea(TacticBase): +class ForbidMovingInPlacementArea(WrapperTacticBase): """プレースメントエリア内での移動を禁止するWrapperTactic." ForbidMovingInPlacementArea(tactic=Position()) のように使用する """ - def __init__(self, tactic=TacticBase): - """inner_tacticを初期化する関数.""" - super().__init__() - self.inner_tactic = tactic - - def reset(self, robot_id: int) -> None: - """inner_tacticをリセットする関数.""" - super().reset(robot_id) - self.inner_tactic.reset(robot_id) - - def exit(self): - """inner_tacticをexitする関数.""" - super().exit() - self.inner_tactic.exit() - def run(self, world_model: WorldModel) -> MotionCommand: """プレースメントエリア内での移動を禁止する関数.""" command = self.inner_tactic.run(world_model) diff --git a/consai_game/consai_game/tactic/wrapper/move_to_receive_pass.py b/consai_game/consai_game/tactic/wrapper/move_to_receive_pass.py index aff8e88a..901b2358 100644 --- a/consai_game/consai_game/tactic/wrapper/move_to_receive_pass.py +++ b/consai_game/consai_game/tactic/wrapper/move_to_receive_pass.py @@ -14,13 +14,13 @@ from consai_msgs.msg import MotionCommand +from consai_game.core.tactic.wrapper_tactic_base import WrapperTacticBase from consai_game.world_model.world_model import WorldModel -from consai_game.core.tactic.tactic_base import TacticBase from consai_tools.geometry import geometry_tools as tool -class MoveToReceivePass(TacticBase): +class MoveToReceivePass(WrapperTacticBase): """パスラインが相手ロボットとかぶっていたらパスをもらえる位置に移動するWrapperTactic. MoveToReceivePass(tactic=Position()) のように使用する @@ -28,21 +28,6 @@ class MoveToReceivePass(TacticBase): THRESHOULD_RADIUS = 0.5 # パスラインに対して相手ロボットが干渉するとみなす半径[m] - def __init__(self, tactic=TacticBase): - """inner_tacticを初期化する関数.""" - super().__init__() - self.inner_tactic = tactic - - def reset(self, robot_id: int) -> None: - """inner_tacticをリセットする関数.""" - super().reset(robot_id) - self.inner_tactic.reset(robot_id) - - def exit(self): - """inner_tacticをexitする関数.""" - super().exit() - self.inner_tactic.exit() - def run(self, world_model: WorldModel) -> MotionCommand: """パスラインを開くようにdesired_poseを上書きする.""" command = self.inner_tactic.run(world_model) diff --git a/consai_game/consai_game/tactic/wrapper/slow_safe.py b/consai_game/consai_game/tactic/wrapper/slow_safe.py index d152d4b8..cbf23015 100644 --- a/consai_game/consai_game/tactic/wrapper/slow_safe.py +++ b/consai_game/consai_game/tactic/wrapper/slow_safe.py @@ -14,11 +14,11 @@ from consai_msgs.msg import MotionCommand +from consai_game.core.tactic.wrapper_tactic_base import WrapperTacticBase from consai_game.world_model.world_model import WorldModel -from consai_game.core.tactic.tactic_base import TacticBase -class SlowSafe(TacticBase): +class SlowSafe(WrapperTacticBase): """ボールを避けながら低速で移動するWrapperTactic." SlowSafe(tactic=Position()) のように使用する @@ -27,21 +27,6 @@ class SlowSafe(TacticBase): MAX_VELOCITY = 1.0 # 最大速度の制限値 [m/s] AVOID_RADIUS = 0.6 # ボールを避ける半径 [m] - def __init__(self, tactic=TacticBase): - """inner_tacticを初期化する関数.""" - super().__init__() - self.inner_tactic = tactic - - def reset(self, robot_id: int) -> None: - """inner_tacticをリセットする関数.""" - super().reset(robot_id) - self.inner_tactic.reset(robot_id) - - def exit(self): - """inner_tacticをexitする関数.""" - super().exit() - self.inner_tactic.exit() - def run(self, world_model: WorldModel) -> MotionCommand: """ディフェンスエリア内での移動と、ボールとの接触を許可する.""" command = self.inner_tactic.run(world_model) diff --git a/consai_game/consai_game/tactic/wrapper/with_avoid_ball_zone.py b/consai_game/consai_game/tactic/wrapper/with_avoid_ball_zone.py index 181c55ec..1f65763b 100644 --- a/consai_game/consai_game/tactic/wrapper/with_avoid_ball_zone.py +++ b/consai_game/consai_game/tactic/wrapper/with_avoid_ball_zone.py @@ -14,11 +14,11 @@ from consai_msgs.msg import MotionCommand +from consai_game.core.tactic.wrapper_tactic_base import WrapperTacticBase from consai_game.world_model.world_model import WorldModel -from consai_game.core.tactic.tactic_base import TacticBase -class WithAvoidBallZone(TacticBase): +class WithAvoidBallZone(WrapperTacticBase): """ボールの周囲を避けるWrapperTactic." WithAvoidBallZone(tactic=Position()) のように使用する @@ -26,21 +26,6 @@ class WithAvoidBallZone(TacticBase): AVOID_RADIUS = 0.7 # ボールを避ける半径 [m] - def __init__(self, tactic=TacticBase): - """inner_tacticを初期化する関数.""" - super().__init__() - self.inner_tactic = tactic - - def reset(self, robot_id: int) -> None: - """inner_tacticをリセットする関数.""" - super().reset(robot_id) - self.inner_tactic.reset(robot_id) - - def exit(self): - """inner_tacticをexitする関数.""" - super().exit() - self.inner_tactic.exit() - def run(self, world_model: WorldModel) -> MotionCommand: """ボールの周囲を避ける.""" command = self.inner_tactic.run(world_model) diff --git a/consai_game/consai_game/tactic/wrapper/wrapper_look_ball.py b/consai_game/consai_game/tactic/wrapper/wrapper_look_ball.py index 54b18479..9f8a9f91 100644 --- a/consai_game/consai_game/tactic/wrapper/wrapper_look_ball.py +++ b/consai_game/consai_game/tactic/wrapper/wrapper_look_ball.py @@ -14,32 +14,17 @@ from consai_msgs.msg import MotionCommand +from consai_game.core.tactic.wrapper_tactic_base import WrapperTacticBase from consai_game.world_model.world_model import WorldModel -from consai_game.core.tactic.tactic_base import TacticBase from consai_tools.geometry import geometry_tools as tool -class WrapperLookBall(TacticBase): +class WrapperLookBall(WrapperTacticBase): """ボールを見るようにthetaを上書きするWrapperTactic. WrapperLookBall(tactic=Position()) のように使用する """ - def __init__(self, tactic=TacticBase): - """内部tacticを初期化する関数.""" - super().__init__() - self.inner_tactic = tactic - - def reset(self, robot_id: int) -> None: - """inner_tacticをリセットする関数.""" - super().reset(robot_id) - self.inner_tactic.reset(robot_id) - - def exit(self): - """inner_tacticをexitする関数.""" - super().exit() - self.inner_tactic.exit() - def run(self, world_model: WorldModel) -> MotionCommand: """ボールを見るようにdesired_poseを上書きする.`""" command = self.inner_tactic.run(world_model) From 5b745357c8cc079bf46e7c261489efa36588dd6b Mon Sep 17 00:00:00 2001 From: ShotaAk Date: Sat, 17 May 2025 06:33:13 +0000 Subject: [PATCH 7/7] Set name to wrapper tactic --- consai_game/consai_game/core/tactic/tactic_base.py | 5 +++++ consai_game/consai_game/core/tactic/wrapper_tactic_base.py | 1 + 2 files changed, 6 insertions(+) diff --git a/consai_game/consai_game/core/tactic/tactic_base.py b/consai_game/consai_game/core/tactic/tactic_base.py index 36d6ab8d..c430375b 100644 --- a/consai_game/consai_game/core/tactic/tactic_base.py +++ b/consai_game/consai_game/core/tactic/tactic_base.py @@ -73,3 +73,8 @@ def state(self, value: TacticState) -> None: def name(self) -> str: """戦術の名前を取得する関数.""" return self._name + + @name.setter + def name(self, value: str) -> None: + """戦術の名前を設定する関数.""" + self._name = value diff --git a/consai_game/consai_game/core/tactic/wrapper_tactic_base.py b/consai_game/consai_game/core/tactic/wrapper_tactic_base.py index da455e8f..44477c70 100644 --- a/consai_game/consai_game/core/tactic/wrapper_tactic_base.py +++ b/consai_game/consai_game/core/tactic/wrapper_tactic_base.py @@ -25,6 +25,7 @@ def __init__(self, tactic=TacticBase): """内部tacticを初期化する関数.""" super().__init__() self.inner_tactic = tactic + self.name += f"({self.inner_tactic.name})" def reset(self, robot_id: int) -> None: """inner_tacticをリセットする関数."""