diff --git a/behaviors/behavior_manager.py b/behaviors/behavior_manager.py index c54f17c..891c1c2 100644 --- a/behaviors/behavior_manager.py +++ b/behaviors/behavior_manager.py @@ -1,5 +1,8 @@ from behaviors.custom.keyframe.get_up.get_up import GetUp from behaviors.custom.keyframe.keyframe import KeyframeSkill +from behaviors.custom.keyframe.poses.goalie_set.goalie_set import GoalieSet +from behaviors.custom.keyframe.poses.low_block_left.low_block_left import LowBlockLeft +from behaviors.custom.keyframe.poses.low_block_right.low_block_right import LowBlockRight from behaviors.custom.keyframe.poses.neutral.neutral import Neutral from behaviors.behavior import Behavior from behaviors.custom.reinforcement.walk.walk import Walk @@ -22,7 +25,7 @@ class BehaviorManager: Each skill is indexed by its class name. """ - classes: list[type[Behavior]] = [Walk, Neutral, GetUp] + classes: list[type[Behavior]] = [Walk, Neutral, GoalieSet, LowBlockLeft, LowBlockRight, GetUp] # instantiate each Skill and store in the skills dictionary self.skills = {cls.__name__: cls(agent=self.agent) for cls in classes} @@ -33,6 +36,9 @@ class BehaviorManager: raise KeyError(f"No skill found with the name '{name}'") return self.skills[name] + def has_skill(self, name: str) -> bool: + return name in self.skills + def execute(self, skill_name: str, *args, **kwargs) -> bool: """ Executes one step of the specified skill. diff --git a/behaviors/custom/keyframe/poses/goalie_set/goalie_set.py b/behaviors/custom/keyframe/poses/goalie_set/goalie_set.py new file mode 100644 index 0000000..77b76d8 --- /dev/null +++ b/behaviors/custom/keyframe/poses/goalie_set/goalie_set.py @@ -0,0 +1,8 @@ +import os + +from behaviors.custom.keyframe.keyframe import KeyframeSkill + + +class GoalieSet(KeyframeSkill): + def __init__(self, agent): + super().__init__(agent, os.path.join(os.path.dirname(__file__), "goalie_set.yaml")) diff --git a/behaviors/custom/keyframe/poses/low_block_left/low_block_left.py b/behaviors/custom/keyframe/poses/low_block_left/low_block_left.py new file mode 100644 index 0000000..08fb378 --- /dev/null +++ b/behaviors/custom/keyframe/poses/low_block_left/low_block_left.py @@ -0,0 +1,8 @@ +import os + +from behaviors.custom.keyframe.keyframe import KeyframeSkill + + +class LowBlockLeft(KeyframeSkill): + def __init__(self, agent): + super().__init__(agent, os.path.join(os.path.dirname(__file__), "low_block_left.yaml")) diff --git a/behaviors/custom/keyframe/poses/low_block_right/low_block_right.py b/behaviors/custom/keyframe/poses/low_block_right/low_block_right.py new file mode 100644 index 0000000..22b7b27 --- /dev/null +++ b/behaviors/custom/keyframe/poses/low_block_right/low_block_right.py @@ -0,0 +1,8 @@ +import os + +from behaviors.custom.keyframe.keyframe import KeyframeSkill + + +class LowBlockRight(KeyframeSkill): + def __init__(self, agent): + super().__init__(agent, os.path.join(os.path.dirname(__file__), "low_block_right.yaml")) diff --git a/behaviors/custom/reinforcement/goalie_block/goalie_block.py b/behaviors/custom/reinforcement/goalie_block/goalie_block.py new file mode 100644 index 0000000..2b6898a --- /dev/null +++ b/behaviors/custom/reinforcement/goalie_block/goalie_block.py @@ -0,0 +1,32 @@ +import logging + +from behaviors.behavior import Behavior + + +logger = logging.getLogger(__name__) + + +class GoalieBlock(Behavior): + """ + Placeholder interface for a future RL-based goalkeeper blocking skill. + + The production code does not register or call this skill yet. + It exists to lock down the expected execution shape for later training work. + """ + + def __init__(self, agent): + super().__init__(agent) + self.last_side: str | None = None + + def execute(self, reset: bool, side: str, *args, **kwargs) -> bool: + if reset: + self.last_side = side + + logger.warning( + "GoalieBlock.execute(side=%s) was called before an RL model was integrated.", + side, + ) + return True + + def is_ready(self, *args) -> bool: + return False diff --git a/communication/monitor_client.py b/communication/monitor_client.py index 64e1e69..905a96a 100644 --- a/communication/monitor_client.py +++ b/communication/monitor_client.py @@ -57,7 +57,14 @@ class MonitorClient: unum: int, team_name: str, pos: tuple[float, float, float], + yaw_deg: float | None = None, ) -> None: - self.send( - f"(agent (unum {unum}) (team {team_name}) (pos {pos[0]} {pos[1]} {pos[2]}))" - ) + if yaw_deg is None: + command = f"(agent (unum {unum}) (team {team_name}) (pos {pos[0]} {pos[1]} {pos[2]}))" + else: + command = ( + f"(agent (unum {unum}) (team {team_name}) " + f"(move {pos[0]} {pos[1]} {pos[2]} {yaw_deg}))" + ) + + self.send(command)