Exemplo n.º 1
0
class GoToStaticBall(Action):
    '''
    Move defender to the ball when static
    '''
    preconditions = [(lambda w, r: abs(
        utils.defender_get_rotation_to_catch_point(
            Vector(r.x, r.y, r.angle, 0), Vector(w.ball.x, w.ball.y, 0, 0), r.
            catch_distance)[0]) < ROTATION_THRESHOLD,
                      "Defender is facing ball"),
                     (lambda w, r: r.catcher == 'OPEN', "Grabbers are open."),
                     (lambda w, r: utils.ball_is_static(w), "Ball is static.")]

    def perform(self, comms):
        # reset dynamic threshold
        # TODO: has to be restarted everywhere!
        global ROTATION_THRESHOLD
        ROTATION_THRESHOLD = 0.1

        dx = self.world.ball.x - self.robot.x
        dy = self.world.ball.y - self.robot.y
        displacement = math.hypot(dx, dy)

        if displacement == 0:
            alpha = 0
        else:
            # TODO: has to handle this edge case better
            try:
                alpha = math.degrees(
                    math.asin(self.robot.catch_distance / float(displacement)))
            except ValueError as er:
                print(er)
                x = self.world.ball.x
                y = self.world.ball.y
                angle = utils.get_rotation_to_point(self.robot.vector,
                                                    Vector(x, y, 0, 0))
                logging.info("Wants to close-rotate by: " + str(angle))
                comms.turn(angle)
                return 1  # TODO: NO FIXED DELAY
        beta = 90 - alpha

        if math.sin(math.radians(alpha)) == 0:
            distance_to_move = 15  # something is obviously wrong so we have to move a bit
        else:
            distance_to_move = math.sin(
                math.radians(beta)) * self.robot.catch_distance / math.sin(
                    math.radians(alpha))

        # Find the movement side
        angle, side = utils.defender_get_rotation_to_catch_point(
            Vector(self.robot.x, self.robot.y, self.robot.angle, 0),
            Vector(self.world.ball.x, self.world.ball.y, 0, 0),
            self.robot.catch_distance)
        if side == "left":
            distance_to_move = -distance_to_move

        logging.info("Wants to move by: " + str(distance_to_move))
        comms.move(distance_to_move)

        return utils.defender_move_delay(distance_to_move)
Exemplo n.º 2
0
class AlignForGrab(Action):
    preconditions = [(lambda w, r: r.catcher == 'OPEN', "Grabbers are open."),
                     (lambda w, r: abs((r.angle - w.ball.angle + pi / 2) % pi - pi / 2) < 0.6, "Ball vector and robot vector within 35 degrees."),
                     (lambda w, r: not utils.ball_is_static(w), "The ball is moving")]

    def perform(self, comms):
        dist = utils.defender_get_alignment_offset(self.robot, self.world.ball, self.world.ball.angle)
        logging.info("Aligning with ball. (Move %f right)", dist)
        if abs(dist) > MOVEMENT_THRESHOLD:
            comms.move(dist)
            return utils.defender_move_delay(dist)
Exemplo n.º 3
0
class GoToGrabStaticBall(Action):
    preconditions = [(lambda w, r: utils.ball_is_static(w), "Ball is static"),
                     (lambda w, r: is_robot_facing_position(w, r, w.ball.vector), "Attacker is facing ball"),
                     (lambda w, r: r.catcher == 'OPEN', "Attacker's grabbers are open")]

    def perform(self, comms):
        d = None
        dx = self.world.ball.x - self.robot.x
        dy = self.world.ball.y - self.robot.y
        d = math.sqrt(dx**2 + dy**2)
        comms.move(d - GRAB_DISTANCE)
Exemplo n.º 4
0
 def get_goal(self, world, robot):
     '''
     Selects a goal for robot
     '''
     if robot.penalty:
         return None
     elif self.current_task == 'game' and world.game_state is not None:
         utils.defender_rotation_to_defend_point(robot, world.ball, world.our_goal.vector, defender.GOAL_RADIUS, world.our_side)
         if robot.has_ball(world.ball):
             info("Defender goal choice: Pass the ball")
             return defender.Pass(world, robot)
         elif utils.dist(world.our_goal, world.ball) < defender.GOAL_RADIUS:
             return None
         elif not utils.ball_heading_to_our_goal(world) and utils.defender_should_grab_ball(world):
             info("Defender goal choice: Retrieve the ball")
             return defender.GetBall(world, robot)
         else:
             info("Defender goal choice: Do the wiggle dance!")
             return defender.Defend(world, robot)
     elif self.current_task == 'oldgame' and world.game_state is not None:
         if robot.has_ball(world.ball):
             info("Defender goal choice: kick the ball")
             return defender.Pass(world, robot)
         elif utils.ball_heading_to_our_goal(world) and world.in_our_half(world.ball):
             info("Defender goal choice: Intercept")
             return defender.ReactiveGrabGoal(world, robot)
         elif utils.ball_is_static(world) and world.in_our_half(world.ball):
             ourdist = math.hypot(world.ball.x - robot.x, world.ball.y - robot.y)
             oppdists = [math.hypot(world.ball.x - r.x, world.ball.y - r.y)
                         for r in world.their_robots if not r.is_missing()]
             if (len(oppdists) == 0 or ourdist < min(oppdists)) and world.game_state == 'normal-play':
                 info("Defender goal choice: Retrieve ball")
                 return defender.GetBall(world, robot)
             else:
                 info("Defender goal choice: Block")
                 return defender.Block(world, robot)
         else:
             info("Defender goal choice: Return to defence area")
             return defender.ReturnToDefenceArea(world, robot)
     elif self.current_task == 'move-grab':
         return defender.GetBall(world, robot)
     elif self.current_task == 'defend':
         return defender.Defend(world, robot)
     elif self.current_task == 'reactive-grab':
         return defender.ReactiveGrabGoal(world, robot)
     elif self.current_task == 'm1':
         return defender.ReceivingPass(world, robot)
     elif self.current_task == 'm2':
         return defender.ReceiveAndPass(world, robot)
     elif self.current_task == 'm31':
         return defender.InterceptPass(world, robot)
     elif self.current_task == 'm32':
         return defender.InterceptGoal(world, robot)
Exemplo n.º 5
0
 def perform(self, comms):
     d = None
     if utils.ball_is_static(self.world):
         dx = self.world.ball.x - self.robot.x
         dy = self.world.ball.y - self.robot.y
         d = math.sqrt(dx**2 + dy**2)
     else:
         # TODO Find ball path
         dx = self.world.ball.x - self.robot.x
         dy = self.world.ball.y - self.robot.y
         d = math.sqrt(dx**2 + dy**2)
     # TODO grabbing area size
     grabber_size = 50
     comms.move(d - grabber_size)
Exemplo n.º 6
0
class WaitForBallToCome(Action):
    '''
    Defender just waits for the ball to approach it
    '''

    # FIXME: ball_can_reach_robot doesn't do anything.
    # FIXME: robot_can_reach_ball doesn't do anything.
    preconditions = [(lambda w, r: abs(utils.get_rotation_to_point(r.vector, w.ball.vector)) < ROTATION_BALL_THRESHOLD, "Defender is facing ball"),
                     (lambda w, r: utils.ball_can_reach_robot(w.ball, r), "The ball can reach the robot"),
                     (lambda w, r: utils.robot_can_reach_ball(w.ball, r), "Defender can reach the ball"),
                     (lambda w, r: r.catcher == 'OPEN', "Grabbers are open."),
                     (lambda w, r: not utils.ball_is_static(w), "The ball is moving.")]

    def perform(self, comms):
        pass
Exemplo n.º 7
0
class RotateAndAlignForGrab(Action):
    preconditions = [(lambda w, r: r.catcher == 'OPEN', "Grabbers are open."),
                     (lambda w, r: abs((r.angle - w.ball.angle + pi / 2) % pi - pi / 2) >= 0.6, "Ball vector and robot vector not within 35 degrees."),
                     (lambda w, r: not utils.ball_is_static(w), "The ball is moving")]

    def perform(self, comms):
        target_rotation = (self.world.ball.angle - self.robot.angle + pi / 2) % pi - pi / 2
        dist = utils.defender_get_alignment_offset(self.robot, self.world.ball, self.world.ball.angle, target_rotation)
        logging.info("Aligning with ball. (Rotate %f degrees, move %f right)", math.degrees(target_rotation), dist)
        if abs(dist) > MOVEMENT_THRESHOLD:
            comms.turn_then_move(target_rotation, dist)
            return utils.defender_turn_delay(target_rotation) + utils.defender_move_delay(dist)
        else:
            comms.turn(target_rotation)
            return utils.defender_turn_delay(target_rotation)
Exemplo n.º 8
0
class FollowBall(Action):
    '''
    Be in the trajectory of moving ball as long as it's predicted
    that the ball reaches the robot
    '''

    # Different precondition: Face counter to ball trajectory instead of facing
    # the ball (allows intercepting as well as possible.
    preconditions = [(lambda w, r: r.catcher == 'OPEN', "Grabbers are open."),
                     (lambda w, r: not utils.ball_is_static(w), "The ball is moving.")]

    def perform(self, comms):
        turn_angle = (self.world.ball.angle - self.robot.angle) % (2 * pi) - pi
        dist = math.hypot(self.robot.x - self.world.ball.x, self.robot.y - self.world.ball.y)
        tri_angle = utils.get_rotation_to_point(self.world.ball.vector, self.robot)
        dist *= math.cos(tri_angle)
        if abs(turn_angle) < ROTATION_BALL_THRESHOLD:
            logging.info("Adjusting to ball position by distance: " + str(dist))
            comms.move(dist)
        else:
            logging.info("Adjusting angle by %f, distance by %f." % (turn_angle, dist))
            comms.turn_then_move(turn_angle, dist)
        return 2