예제 #1
0
 def _find_best_next_target(self, area: Area, old_target_position, player_position: Position, target_to_position: Line):
     intersections = area.intersect(target_to_position)
     if intersections:
         return intersections[0]
     elif old_target_position == player_position:
         return area.closest_border_point(old_target_position)
     else:  # The player is already in the forbidden area, so it must go in the opposite direction than the target
         intersections = area.intersect_with_line(target_to_position)
         if (intersections[0] - self.player.position).norm < (intersections[1] - self.player.position).norm:
             return intersections[0]
         else:
             return intersections[1]
예제 #2
0
 def _find_best_next_target(self, area: Area, old_target_position,
                            player_position: Position,
                            target_to_position: Line):
     intersections = area.intersect(target_to_position)
     if intersections:
         return intersections[0]
     elif old_target_position == player_position:
         return area.closest_border_point(old_target_position)
     else:  # The player is already in the forbidden area, so it must go in the opposite direction than the target
         intersections = area.intersect_with_line(target_to_position)
         if (intersections[0] - self.player.position).norm < (
                 intersections[1] - self.player.position).norm:
             return intersections[0]
         else:
             return intersections[1]
예제 #3
0
    def __init__(self, game_state: GameState, player: Player, target: Optional[Pose]=None,
                 args: Optional[List[Any]]=None, forbidden_areas: Optional[List[Area]]=None):
        self.logger = logging.getLogger(self.__class__.__name__)

        assert isinstance(player, Player), "Le player doit être un Player, non un '{}'".format(player)
        assert target is None or isinstance(target, Pose), "La target devrait être une Pose"
        self.game_state = game_state
        self.player = player
        self.player_id = player.id
        if args is None:
            self.args = []
        else:
            self.args = args

        self.current_state = self.halt
        self.next_state = self.halt
        self.status_flag = Flags.INIT
        self.target = target

        if forbidden_areas is None:
            field = self.game_state.field

            # Those limits are for ulaval local only
            areas = field.border_limits
            areas += [
                self.field.behind_our_goal_line,
                self.field.behind_their_goal_line]
            #areas = []
            self.forbidden_areas = [Area.pad(area, KEEPOUT_DISTANCE_FROM_GOAL) for area in areas]
            self.forbidden_areas += [self.game_state.field.their_goal_forbidden_area,
                                     self.game_state.field.our_goal_forbidden_area]
        else:
            self.forbidden_areas = forbidden_areas
예제 #4
0
    def __init__(
            self,
            game_state: GameState,
            player: Player,
            target: Pose = Pose(),
            penalty_kick=False,
            args: List[str] = None,
    ):
        forbidden_area = [
            Area.pad(game_state.field.their_goal_area,
                     KEEPOUT_DISTANCE_FROM_GOAL)
        ]
        super().__init__(game_state,
                         player,
                         target,
                         args,
                         forbidden_areas=forbidden_area)

        self.current_state = self.defense
        self.next_state = self.defense

        self.target = Pose(
            self.game_state.field.our_goal,
            np.pi)  # Ignore target argument, always go for our goal

        self.go_kick_tactic = None  # Used by clear
        self.last_intersection = None  # For debug

        self.OFFSET_FROM_GOAL_LINE = Position(ROBOT_RADIUS + 10, 0)
        self.GOAL_LINE = self.game_state.field.our_goal_line
예제 #5
0
    def _update_field_const(self):
        self.our_goal = Position(self.our_goal_x, 0)
        self.our_goal_pose = Pose(self.our_goal, 0)
        self.their_goal = Position(self.their_goal_x, 0)
        self.their_goal_pose = Pose(self.their_goal, 0)

        p1 = self.field_lines["RightPenaltyStretch"].p1
        p2 = self.field_lines["RightPenaltyStretch"].p2
        p3 = self.field_lines["RightFieldLeftPenaltyStretch"].p1
        p4 = self.field_lines["RightFieldLeftPenaltyStretch"].p2
        self.our_goal_area = Area.from_4_point(p1, p2, p3, p4)

        self.their_goal_area = Area.flip_x(self.our_goal_area)

        self.goal_line = Line(p1=Position(self.our_goal_x, +self.goal_width / 2),
                                  p2=Position(self.our_goal_x, -self.goal_width / 2))

        self.our_goal_line = Line(p1=Position(self.our_goal_x, +self.goal_width / 2),
                                  p2=Position(self.our_goal_x, -self.goal_width / 2))
        self.their_goal_line = Line(p1=Position(self.their_goal_x, +self.goal_width / 2),
                                    p2=Position(self.their_goal_x, -self.goal_width / 2))
        self.behind_our_goal_line = Area.from_limits(self.our_goal_area.top,
                                                     self.our_goal_area.bottom,
                                                     self.our_goal_area.right + 50 * self.goal_depth,
                                                     self.our_goal_area.left)
        self.behind_their_goal_line = Area.flip_x(self.behind_our_goal_line)

        self.free_kick_avoid_area = Area.pad(self.their_goal_area,
                                             INDIRECT_KICK_OFFSET + KEEPOUT_DISTANCE_FROM_GOAL)
        self.our_goal_forbidden_area = Area.pad(self.our_goal_area, KEEPOUT_DISTANCE_FROM_GOAL)
        self.their_goal_forbidden_area = Area.pad(self.their_goal_area, KEEPOUT_DISTANCE_FROM_GOAL)

        self.center = Position(0, 0)
예제 #6
0
 def _is_ball_safe_to_kick(self):
     # Since defender can not kick the ball while inside the goal there are position where the ball is unreachable
     # The goalee must leave the goal area and kick the ball
     goal_area = self.game_state.field.our_goal_area
     width = KEEPOUT_DISTANCE_FROM_GOAL + ROBOT_DIAMETER
     area_in_front_of_goal = Area.from_limits(goal_area.top, goal_area.bottom,
                                              goal_area.left, goal_area.left - width)
     return self.game_state.field.is_ball_in_our_goal_area() or \
            area_in_front_of_goal.point_inside(self.game_state.ball.position) and self._no_enemy_around_ball()
예제 #7
0
    def border_limits(self):

        top_area = Area.from_limits(self.top + 100 * self.boundary_width,
                                    self.top + self.boundary_width,
                                    self.right + 100 * self.boundary_width,
                                    self.left - 100 * self.boundary_width)
        bottom_area = Area.from_limits(self.bottom - self.boundary_width,
                                       self.bottom - 100 * self.boundary_width,
                                       self.right + 100 * self.boundary_width,
                                       self.left - 100 * self.boundary_width)
        right_area = Area.from_limits(self.top + 100 * self.boundary_width,
                                      self.bottom - 100 * self.boundary_width,
                                      self.right + 100 * self.boundary_width,
                                      self.right + self.boundary_width)
        left_area = Area.from_limits(self.top + 100 * self.boundary_width,
                                     self.bottom - 100 * self.boundary_width,
                                     self.left - self.boundary_width,
                                     self.left - 100 * self.boundary_width)
        return [top_area, bottom_area, right_area, left_area]
예제 #8
0
    def border_limits(self):

        top_area = Area.from_limits(self.top + 100 * self.boundary_width,
                                    self.top + self.boundary_width,
                                    self.right + 100 * self.boundary_width,
                                    self.left - 100 * self.boundary_width)
        bottom_area = Area.from_limits(self.bottom - self.boundary_width,
                                       self.bottom - 100 * self.boundary_width,
                                       self.right + 100 * self.boundary_width,
                                       self.left - 100 * self.boundary_width)
        right_area = Area.from_limits(self.top + 100 * self.boundary_width,
                                      self.bottom - 100 * self.boundary_width,
                                      self.right + 100 * self.boundary_width,
                                      self.right + self.boundary_width)
        left_area = Area.from_limits(self.top + 100 * self.boundary_width,
                                     self.bottom - 100 * self.boundary_width,
                                     self.left - self.boundary_width,
                                     self.left - 100 * self.boundary_width)
        return [top_area, bottom_area, right_area, left_area]
예제 #9
0
 def _is_ball_safe_to_kick(self):
     # Since defender can not kick the ball while inside the goal there are position where the ball is unreachable
     # The goalee must leave the goal area and kick the ball
     goal_area = self.game_state.field.our_goal_area
     width = KEEPOUT_DISTANCE_FROM_GOAL + ROBOT_DIAMETER
     area_in_front_of_goal = Area.from_limits(goal_area.top,
                                              goal_area.bottom,
                                              goal_area.left,
                                              goal_area.left - width)
     return self.game_state.field.is_ball_in_our_goal_area() or \
            area_in_front_of_goal.point_inside(self.game_state.ball.position) and self._no_enemy_around_ball()
예제 #10
0
    def __init__(self, game_state: GameState, player: Player, target: Pose=Pose(),
                 penalty_kick=False, args: List[str]=None,):
        forbidden_area = [Area.pad(game_state.field.their_goal_area, KEEPOUT_DISTANCE_FROM_GOAL)]
        super().__init__(game_state, player, target, args, forbidden_areas=forbidden_area)

        self.current_state = self.defense
        self.next_state = self.defense

        self.target = Pose(self.game_state.field.our_goal, np.pi)  # Ignore target argument, always go for our goal

        self.go_kick_tactic = None # Used by clear
        self.last_intersection = None # For debug

        self.OFFSET_FROM_GOAL_LINE = Position(ROBOT_RADIUS + 10, 0)
        self.GOAL_LINE = self.game_state.field.our_goal_line
예제 #11
0
    def __init__(self,
                 game_state: GameState,
                 player: Player,
                 target: Optional[Pose] = None,
                 args: Optional[List[Any]] = None,
                 forbidden_areas: Optional[List[Area]] = None):
        self.logger = logging.getLogger(self.__class__.__name__)

        assert isinstance(
            player,
            Player), "Le player doit être un Player, non un '{}'".format(
                player)
        assert target is None or isinstance(
            target, Pose), "La target devrait être une Pose"
        self.game_state = game_state
        self.player = player
        self.player_id = player.id
        if args is None:
            self.args = []
        else:
            self.args = args

        self.current_state = self.halt
        self.next_state = self.halt
        self.status_flag = Flags.INIT
        self.target = target

        if forbidden_areas is None:
            field = self.game_state.field

            # Those limits are for ulaval local only
            areas = field.border_limits
            areas += [
                self.field.behind_our_goal_line,
                self.field.behind_their_goal_line
            ]
            #areas = []
            self.forbidden_areas = [
                Area.pad(area, KEEPOUT_DISTANCE_FROM_GOAL) for area in areas
            ]
            self.forbidden_areas += [
                self.game_state.field.their_goal_forbidden_area,
                self.game_state.field.our_goal_forbidden_area
            ]
        else:
            self.forbidden_areas = forbidden_areas
예제 #12
0
    def _find_best_player_position(self):
        if not self.auto_position:
            return self.target.position

        if self.is_offense:
            ball_offset = clamp(self.game_state.ball.position.x, 0, 1000)
            left = self.game_state.field.their_goal_area.right + ball_offset
            right = ball_offset
        else:
            ball_offset = clamp(self.game_state.ball.position.x, -1000, 0)
            left = self.game_state.field.our_goal_area.left + ball_offset
            right = ball_offset

        idx = self.idx_in_formation
        len_formation = len(self.robots_in_formation)

        PADDING = 300  # Add buffer zone between area and the field limit
        area_height = self.game_state.field.field_width - 2 * PADDING

        individual_area_size = area_height / len_formation
        top = idx * individual_area_size - area_height / 2
        bot = top + individual_area_size
        self.area = Area.from_limits(top, bot, right, left)

        center = self.area.center
        # Act as if each enemy robot was creating a repulsive force
        v = Position(0, 0)
        for enemy in self.game_state.enemy_team.available_players.values():
            d = enemy.position - center
            # Clamp distance norm
            d = MIN_DIST_FROM_CENTER * normalize(d) if d.norm < MIN_DIST_FROM_CENTER else d
            # Square of the inverse of the distance, a bit like Newton's law of universal gravitation
            v -= ATTENUATION * d / (d.norm ** 3)

        if self.area.point_inside(center + v):
            return center + v
        offset_from_center = Line(center, center + v)
        # The position must stay inside the area limits, so let's find the intersection between our vector and the area
        area_inter = self.area.intersect(offset_from_center)
        if area_inter:
            return area_inter[0]  # First intersection
        return center + v
예제 #13
0
    def _update_field_const(self):
        self.our_goal = Position(self.our_goal_x, 0)
        self.our_goal_pose = Pose(self.our_goal, 0)
        self.their_goal = Position(self.their_goal_x, 0)
        self.their_goal_pose = Pose(self.their_goal, 0)

        p1 = self.field_lines["RightPenaltyStretch"].p1
        p2 = self.field_lines["RightPenaltyStretch"].p2
        p3 = self.field_lines["RightFieldLeftPenaltyStretch"].p1
        p4 = self.field_lines["RightFieldLeftPenaltyStretch"].p2
        self.our_goal_area = Area.from_4_point(p1, p2, p3, p4)

        self.their_goal_area = Area.flip_x(self.our_goal_area)

        self.goal_line = Line(p1=Position(self.our_goal_x,
                                          +self.goal_width / 2),
                              p2=Position(self.our_goal_x,
                                          -self.goal_width / 2))

        self.our_goal_line = Line(p1=Position(self.our_goal_x,
                                              +self.goal_width / 2),
                                  p2=Position(self.our_goal_x,
                                              -self.goal_width / 2))
        self.their_goal_line = Line(p1=Position(self.their_goal_x,
                                                +self.goal_width / 2),
                                    p2=Position(self.their_goal_x,
                                                -self.goal_width / 2))
        self.behind_our_goal_line = Area.from_limits(
            self.our_goal_area.top, self.our_goal_area.bottom,
            self.our_goal_area.right + 50 * self.goal_depth,
            self.our_goal_area.left)
        self.behind_their_goal_line = Area.flip_x(self.behind_our_goal_line)

        self.free_kick_avoid_area = Area.pad(
            self.their_goal_area,
            INDIRECT_KICK_OFFSET + KEEPOUT_DISTANCE_FROM_GOAL)
        self.our_goal_forbidden_area = Area.pad(self.our_goal_area,
                                                KEEPOUT_DISTANCE_FROM_GOAL)
        self.their_goal_forbidden_area = Area.pad(self.their_goal_area,
                                                  KEEPOUT_DISTANCE_FROM_GOAL)

        self.center = Position(0, 0)
예제 #14
0
def test_area_contain_point():
    assert Position(100, 300) in Area(Position(0, 500), Position(500, 0))