add kick behavior with keyframe, but still need to be improved
This commit is contained in:
91
behaviors/custom/keyframe/kick/kick.py
Normal file
91
behaviors/custom/keyframe/kick/kick.py
Normal file
@@ -0,0 +1,91 @@
|
||||
import os
|
||||
from numbers import Real
|
||||
|
||||
from behaviors.behavior import Behavior
|
||||
from behaviors.custom.keyframe.keyframe import KeyframeSkill
|
||||
|
||||
|
||||
class Kick(Behavior):
|
||||
SHORT_MAX_DISTANCE: float = 1.8
|
||||
MID_MAX_DISTANCE: float = 4.5
|
||||
TEN_METER_MIN_DISTANCE: float = 8.0
|
||||
DEFAULT_DISTANCE: float = 3.0
|
||||
|
||||
def __init__(self, agent):
|
||||
super().__init__(agent)
|
||||
|
||||
base_dir = os.path.dirname(__file__)
|
||||
self.short_kick = KeyframeSkill(
|
||||
agent=agent,
|
||||
file=os.path.join(base_dir, "kick_short.yaml"),
|
||||
)
|
||||
self.mid_kick = KeyframeSkill(
|
||||
agent=agent,
|
||||
file=os.path.join(base_dir, "kick_mid.yaml"),
|
||||
)
|
||||
self.long_kick = KeyframeSkill(
|
||||
agent=agent,
|
||||
file=os.path.join(base_dir, "kick_long.yaml"),
|
||||
)
|
||||
self.ten_meter_kick = KeyframeSkill(
|
||||
agent=agent,
|
||||
file=os.path.join(base_dir, "kick_10m.yaml"),
|
||||
)
|
||||
|
||||
self.current_kick: KeyframeSkill | None = None
|
||||
self.should_reset_kick: bool = True
|
||||
self.should_execute_neutral: bool = True
|
||||
|
||||
def execute(self, reset: bool, *args, **kwargs) -> bool:
|
||||
if reset:
|
||||
kick_distance = self._extract_kick_distance(*args, **kwargs)
|
||||
self.current_kick = self._choose_kick_from_distance(kick_distance)
|
||||
self.should_reset_kick = True
|
||||
self.should_execute_neutral = True
|
||||
|
||||
if self.current_kick is None:
|
||||
self.current_kick = self.mid_kick
|
||||
|
||||
if self.should_execute_neutral:
|
||||
neutral_finished = self.agent.skills_manager.execute(
|
||||
"Neutral",
|
||||
)
|
||||
self.should_reset_kick = False
|
||||
if not neutral_finished:
|
||||
return False
|
||||
self.should_execute_neutral = False
|
||||
self.should_reset_kick = True
|
||||
|
||||
has_finished = self.current_kick.execute(reset=self.should_reset_kick)
|
||||
self.should_reset_kick = False
|
||||
return has_finished
|
||||
|
||||
def _extract_kick_distance(self, *args, **kwargs) -> float:
|
||||
distance_candidates = (
|
||||
kwargs.get("distance"),
|
||||
kwargs.get("kick_distance"),
|
||||
kwargs.get("target_distance"),
|
||||
kwargs.get("ball_to_target_distance"),
|
||||
args[0] if args else None,
|
||||
)
|
||||
|
||||
for candidate in distance_candidates:
|
||||
if isinstance(candidate, Real):
|
||||
return float(max(0.0, candidate))
|
||||
|
||||
return self.DEFAULT_DISTANCE
|
||||
|
||||
def _choose_kick_from_distance(self, distance: float) -> KeyframeSkill:
|
||||
if distance <= self.SHORT_MAX_DISTANCE:
|
||||
return self.short_kick
|
||||
|
||||
if distance <= self.MID_MAX_DISTANCE:
|
||||
return self.mid_kick
|
||||
|
||||
if distance >= self.TEN_METER_MIN_DISTANCE:
|
||||
return self.ten_meter_kick
|
||||
|
||||
return self.long_kick
|
||||
|
||||
def is_ready(self, *args) -> bool:
|
||||
return True
|
||||
Reference in New Issue
Block a user