def intercept(self): # Find the point where the ball will go if not self._ball_going_toward_goal( ) and not self.game_state.field.is_ball_in_our_goal_area(): self.next_state = self.defense elif self.game_state.field.is_ball_in_our_goal_area( ) and self.game_state.ball.is_immobile(): self.next_state = self.clear ball = self.game_state.ball where_ball_enter_goal = intersection_between_lines( self.GOAL_LINE.p1, self.GOAL_LINE.p2, ball.position, ball.position + ball.velocity) # This is where the ball is going to enter the goal where_ball_enter_goal = closest_point_on_segment( where_ball_enter_goal, self.GOAL_LINE.p1, self.GOAL_LINE.p2) enter_goal_to_ball = Line(where_ball_enter_goal, ball.position) # The goalkeeper can not enter goal since there a line blocking vision end_segment = enter_goal_to_ball.direction * ROBOT_RADIUS + where_ball_enter_goal intersect_pts = closest_point_on_segment(self.player.position, ball.position, end_segment) self.last_intersection = intersect_pts return MoveTo( Pose(intersect_pts, self.player.pose.orientation ), # It's a bit faster, to keep our orientation cruise_speed=3, end_speed=0, ball_collision=False)
def intercept(self): # Find the point where the ball will go if not self._ball_going_toward_goal() and not self.game_state.field.is_ball_in_our_goal_area(): self.next_state = self.defense elif self.game_state.field.is_ball_in_our_goal_area() and self.game_state.ball.is_immobile(): self.next_state = self.clear ball = self.game_state.ball where_ball_enter_goal = intersection_between_lines(self.GOAL_LINE.p1, self.GOAL_LINE.p2, ball.position, ball.position + ball.velocity) # This is where the ball is going to enter the goal where_ball_enter_goal = closest_point_on_segment(where_ball_enter_goal, self.GOAL_LINE.p1, self.GOAL_LINE.p2) enter_goal_to_ball = Line(where_ball_enter_goal, ball.position) # The goalkeeper can not enter goal since there a line blocking vision end_segment = enter_goal_to_ball.direction * ROBOT_RADIUS + where_ball_enter_goal intersect_pts = closest_point_on_segment(self.player.position, ball.position, end_segment) self.last_intersection = intersect_pts return MoveTo(Pose(intersect_pts, self.player.pose.orientation), # It's a bit faster, to keep our orientation cruise_speed=3, end_speed=0, ball_collision=False)
def ProtectGoal(game_state: GameState, player: Player, is_right_goal: bool=True, minimum_distance: float=150 / 2, maximum_distance: float=None): """ Calcul la pose que doit prendre le gardien en fonction de la position de la balle. :return: Un tuple (Pose, kick) où Pose est la destination du gardien et kick est nul (on ne botte pas) """ goalkeeper_position = player.pose.position ball_position = game_state.ball_position goal_x = game_state.field.our_goal_x goal_position = Position(goal_x, 0) # Calcul des deux positions extremums entre la balle et le centre du but inner_circle_position = stay_inside_circle(ball_position, goal_position, minimum_distance) outer_circle_position = stay_inside_circle(ball_position, goal_position, maximum_distance) destination_position = closest_point_on_segment(goalkeeper_position, inner_circle_position, outer_circle_position) # Vérification que destination_position respecte la distance maximale if maximum_distance is None: destination_position = game_state.game.field.stay_inside_goal_area(destination_position, our_goal=True) else: destination_position = stay_inside_circle(destination_position, goal_position, maximum_distance) # Calcul de l'orientation de la pose de destination destination_orientation = (ball_position - destination_position).angle destination_pose = Pose(destination_position, destination_orientation) return MoveTo(destination_pose)
def GoBetween(position1: Position, position2: Position, target: Position, minimum_distance: float=0): delta = minimum_distance * normalize(position2 - position1) position1 = position1 + delta position2 = position2 - delta destination = closest_point_on_segment(target, position1, position2) dest_to_target = target - destination return CmdBuilder().addMoveTo(Pose(destination, dest_to_target.angle)).build()
def GoBetween(position1: Position, position2: Position, target: Position, minimum_distance: float = 0): delta = minimum_distance * normalize(position2 - position1) position1 = position1 + delta position2 = position2 - delta destination = closest_point_on_segment(target, position1, position2) dest_to_target = target - destination return CmdBuilder().addMoveTo(Pose(destination, dest_to_target.angle)).build()
def _best_target_into_goal(self): if 0 < len(self.game_state.enemy_team.available_players): enemy_player_with_ball = player_with_ball(min_dist_from_ball=200, our_team=False) if enemy_player_with_ball is not None: if player_pointing_toward_segment(enemy_player_with_ball, self.GOAL_LINE): ball = self.game_state.ball where_ball_enter_goal = intersection_between_lines(self.GOAL_LINE.p1, self.GOAL_LINE.p2, ball.position, ball.position + Position(1000 * np.cos(enemy_player_with_ball.pose.orientation), 1000 * np.sin(enemy_player_with_ball.pose.orientation))) where_ball_enter_goal = closest_point_on_segment(where_ball_enter_goal, self.GOAL_LINE.p1, self.GOAL_LINE.p2) return where_ball_enter_goal return find_bisector_of_triangle(self.game_state.ball.position, self.GOAL_LINE.p2, self.GOAL_LINE.p1)
def _best_target_into_goal(self): if 0 < len(self.game_state.enemy_team.available_players): enemy_player_with_ball = player_with_ball(min_dist_from_ball=200, our_team=False) if enemy_player_with_ball is not None: if player_pointing_toward_segment(enemy_player_with_ball, self.GOAL_LINE): ball = self.game_state.ball where_ball_enter_goal = intersection_between_lines( self.GOAL_LINE.p1, self.GOAL_LINE.p2, ball.position, ball.position + Position( 1000 * np.cos(enemy_player_with_ball.pose.orientation), 1000 * np.sin(enemy_player_with_ball.pose.orientation))) where_ball_enter_goal = closest_point_on_segment( where_ball_enter_goal, self.GOAL_LINE.p1, self.GOAL_LINE.p2) return where_ball_enter_goal return find_bisector_of_triangle(self.game_state.ball.position, self.GOAL_LINE.p2, self.GOAL_LINE.p1)
def ProtectGoal(game_state: GameState, player: Player, is_right_goal: bool = True, minimum_distance: float = 150 / 2, maximum_distance: float = None): """ Calcul la pose que doit prendre le gardien en fonction de la position de la balle. :return: Un tuple (Pose, kick) où Pose est la destination du gardien et kick est nul (on ne botte pas) """ goalkeeper_position = player.pose.position ball_position = game_state.ball_position goal_x = game_state.field.our_goal_x goal_position = Position(goal_x, 0) # Calcul des deux positions extremums entre la balle et le centre du but inner_circle_position = stay_inside_circle(ball_position, goal_position, minimum_distance) outer_circle_position = stay_inside_circle(ball_position, goal_position, maximum_distance) destination_position = closest_point_on_segment(goalkeeper_position, inner_circle_position, outer_circle_position) # Vérification que destination_position respecte la distance maximale if maximum_distance is None: destination_position = game_state.game.field.stay_inside_goal_area( destination_position, our_goal=True) else: destination_position = stay_inside_circle(destination_position, goal_position, maximum_distance) # Calcul de l'orientation de la pose de destination destination_orientation = (ball_position - destination_position).angle destination_pose = Pose(destination_position, destination_orientation) return MoveTo(destination_pose)
def test_closest_point_on_segment(): reference = Position(50, 50) start = Position(10, 0) end = Position(100, 0) assert closest_point_on_segment(reference, start=start, end=end) == Position(50, 0)
def test_closest_point_on_segment_outside_diagonal2_reverse(): reference = Position(9, 10) end = Position(10, 10) start = Position(100, 100) assert closest_point_on_segment(reference, start=start, end=end) == Position(10, 10)
def test_closest_point_on_segment_outside_negative(): reference = Position(-10, 0) start = Position(10, 0) end = Position(100, 0) assert closest_point_on_segment(reference, start=start, end=end) == Position(10, 0)
def test_closest_point_on_segment_outside_positive(): reference = Position(110, 0) start = Position(10, 0) end = Position(100, 0) assert closest_point_on_segment(reference, start=start, end=end) == Position(100, 0)
def test_closest_point_on_segment_under(): reference = Position(0, 100) start = Position(10, 10) end = Position(100, 100) assert closest_point_on_segment(reference, start=start, end=end) == Position(50, 50)
def test_closest_point_on_segment_outside_diagonal2_reverse(): reference = Position(9, 10) end = Position(10, 10) start = Position(100, 100) assert closest_point_on_segment(reference, start=start, end=end) == Position(10, 10)