|
5 | 5 |
|
6 | 6 | from Debug.debug_command_factory import DebugCommandFactory
|
7 | 7 | from ai.Algorithm.evaluation_module import player_with_ball, player_pointing_toward_point, \
|
8 |
| - player_pointing_toward_segment |
| 8 | + player_pointing_toward_segment, closest_players_to_point |
9 | 9 |
|
10 | 10 | __author__ = 'RoboCupULaval'
|
11 | 11 |
|
12 | 12 | from typing import List
|
13 | 13 |
|
14 | 14 | from Util import Pose, Position
|
15 | 15 | from Util.ai_command import MoveTo, Idle
|
16 |
| -from Util.constant import ROBOT_RADIUS, KEEPOUT_DISTANCE_FROM_GOAL |
| 16 | +from Util.constant import ROBOT_RADIUS, KEEPOUT_DISTANCE_FROM_GOAL, ROBOT_DIAMETER |
17 | 17 | from Util.geometry import intersection_line_and_circle, intersection_between_lines, \
|
18 | 18 | closest_point_on_segment, find_bisector_of_triangle, Area
|
19 | 19 | from ai.GameDomainObjects import Player
|
@@ -54,7 +54,7 @@ def defense_dumb(self):
|
54 | 54 |
|
55 | 55 | def defense(self):
|
56 | 56 | # Prepare to block the ball
|
57 |
| - if self.game_state.field.is_ball_in_our_goal_area() and self.game_state.ball.is_immobile(): |
| 57 | + if self._is_ball_safe_to_kick() and self.game_state.ball.is_immobile(): |
58 | 58 | self.next_state = self.clear
|
59 | 59 |
|
60 | 60 | if self._ball_going_toward_goal():
|
@@ -104,28 +104,38 @@ def intercept(self):
|
104 | 104 | end_speed=0,
|
105 | 105 | ball_collision=False)
|
106 | 106 |
|
107 |
| - def _ball_going_toward_goal(self): |
108 |
| - upper_angle = (self.game_state.ball.position - self.GOAL_LINE.p2).angle + 5 * np.pi / 180.0 |
109 |
| - lower_angle = (self.game_state.ball.position - self.GOAL_LINE.p1).angle - 5 * np.pi / 180.0 |
110 |
| - ball_speed = self.game_state.ball.velocity.norm |
111 |
| - return (ball_speed > self.DANGER_BALL_VELOCITY and self.game_state.ball.velocity.x > 0) or \ |
112 |
| - (ball_speed > self.MOVING_BALL_VELOCITY and upper_angle <= self.game_state.ball.velocity.angle <= lower_angle) |
113 |
| - |
114 | 107 | def clear(self):
|
115 | 108 | # Move the ball to outside of the penality zone
|
116 | 109 | if self.go_kick_tactic is None:
|
117 | 110 | self.go_kick_tactic = GoKick(self.game_state,
|
118 | 111 | self.player,
|
119 | 112 | auto_update_target=True,
|
120 | 113 | go_behind_distance=1.2*GRAB_BALL_SPACING,
|
121 |
| - forbidden_areas=self.forbidden_areas) # make it easier |
122 |
| - if not self.game_state.field.is_ball_in_our_goal_area(): |
| 114 | + forbidden_areas=self.forbidden_areas) # make it easier |
| 115 | + if not self._is_ball_safe_to_kick(): |
123 | 116 | self.next_state = self.defense
|
124 | 117 | self.go_kick_tactic = None
|
125 | 118 | return Idle
|
126 | 119 | else:
|
127 | 120 | return self.go_kick_tactic.exec()
|
128 | 121 |
|
| 122 | + def _ball_going_toward_goal(self): |
| 123 | + upper_angle = (self.game_state.ball.position - self.GOAL_LINE.p2).angle + 5 * np.pi / 180.0 |
| 124 | + lower_angle = (self.game_state.ball.position - self.GOAL_LINE.p1).angle - 5 * np.pi / 180.0 |
| 125 | + ball_speed = self.game_state.ball.velocity.norm |
| 126 | + return (ball_speed > self.DANGER_BALL_VELOCITY and self.game_state.ball.velocity.x > 0) or \ |
| 127 | + (ball_speed > self.MOVING_BALL_VELOCITY and upper_angle <= self.game_state.ball.velocity.angle <= lower_angle) |
| 128 | + |
| 129 | + def _is_ball_safe_to_kick(self): |
| 130 | + # Since defender can not kick the ball while inside the goal there are position where the ball is unreachable |
| 131 | + # The goalee must leave the goal area and kick the ball |
| 132 | + goal_area = self.game_state.field.our_goal_area |
| 133 | + width = KEEPOUT_DISTANCE_FROM_GOAL + ROBOT_DIAMETER |
| 134 | + area_in_front_of_goal = Area.from_limits(goal_area.top, goal_area.bottom, |
| 135 | + goal_area.left, goal_area.left - width) |
| 136 | + return self.game_state.field.is_ball_in_our_goal_area() or \ |
| 137 | + area_in_front_of_goal.point_inside(self.game_state.ball.position) and self._no_enemy_around_ball() |
| 138 | + |
129 | 139 | def _best_target_into_goal(self):
|
130 | 140 |
|
131 | 141 | enemy_player_with_ball = player_with_ball(min_dist_from_ball=200, our_team=False)
|
@@ -159,3 +169,10 @@ def debug_cmd(self):
|
159 | 169 | else:
|
160 | 170 | return []
|
161 | 171 |
|
| 172 | + def _no_enemy_around_ball(self): |
| 173 | + closest = closest_players_to_point(self.game_state.ball_position, our_team=False) |
| 174 | + if len(closest) == 0: |
| 175 | + return True |
| 176 | + DANGEROUS_ENEMY_MIN_DISTANCE = 500 |
| 177 | + return closest[0].distance > DANGEROUS_ENEMY_MIN_DISTANCE |
| 178 | + |
0 commit comments