Ejemplo n.º 1
0
    def __init__(self, defender_priorities=[20, 19]):
        super().__init__(continuous=True)

        # we could make the Defense tactic have more or less defenders, but right now we only support two
        if len(defender_priorities) != 2:
            raise RuntimeError(
                "defender_priorities should have a length of two")

        self.add_transition(behavior.Behavior.State.start,
                            behavior.Behavior.State.running, lambda: True,
                            "immediately")

        goalie = tactics.positions.submissive_goalie.SubmissiveGoalie()
        goalie.shell_id = main.root_play().goalie_id
        self.add_subbehavior(goalie, "goalie", required=False)

        # add defenders at the specified priority levels
        for num, priority in enumerate(defender_priorities):
            defender = tactics.positions.submissive_defender.SubmissiveDefender(
            )
            self.add_subbehavior(defender,
                                 'defender' + str(num + 1),
                                 required=False,
                                 priority=priority)

        self.debug = True

        self.win_eval = robocup.WindowEvaluator(main.system_state())
Ejemplo n.º 2
0
    def __init__(self, side=Side.center):
        super().__init__(continuous=True)
        self._block_robot = None
        self._area = None
        self._side = side
        self._opponent_avoid_threshold = 2.0
        self._defend_goal_radius = 0.9
        self._win_eval = robocup.WindowEvaluator(main.system_state())

        self._area = robocup.Rect(
            robocup.Point(-constants.Field.Width / 2.0,
                          constants.Field.Length),
            robocup.Point(constants.Field.Width / 2.0, 0))
        if self._side is Defender.Side.right:
            self._area.get_pt(0).x = 0
        if self._side is Defender.Side.left:
            self._area.get_pt(1).x = 0

        self.add_state(Defender.State.marking, behavior.Behavior.State.running)
        self.add_state(Defender.State.area_marking,
                       behavior.Behavior.State.running)

        self.add_transition(behavior.Behavior.State.start,
                            Defender.State.marking, lambda: True,
                            "immediately")
        self.add_transition(
            Defender.State.marking, Defender.State.area_marking,
            lambda: not self._area.contains_point(main.ball().pos) and self.
            block_robot is None, "if ball not in area and no robot to block")
        self.add_transition(
            Defender.State.area_marking, Defender.State.marking,
            lambda: self._area.contains_point(main.ball(
            ).pos) or self.find_robot_to_block() is not None,
            "if ball or opponent enters my area")
Ejemplo n.º 3
0
    def execute_running(self):
        super().execute_running()
        kicker = self.subbehavior_with_name('kicker')
        center1 = self.subbehavior_with_name('center1')
        center2 = self.subbehavior_with_name('center2')

        # see if we have a direct shot on their goal
        win_eval = robocup.WindowEvaluator(main.system_state())
        win_eval.enable_chip = kicker.robot != None and kicker.robot.has_chipper(
        )
        win_eval.min_chip_range = OurGoalKick.MinChipRange
        win_eval.max_chip_range = OurGoalKick.MaxChipRange
        windows, best = win_eval.eval_pt_to_seg(
            main.ball().pos, constants.Field.TheirGoalSegment)

        # note: the min length value is tunable
        if best != None and best.segment.length() > 0.3:
            # we DO have a shot on the goal, take it!
            kicker.target = constants.Field.TheirGoalSegment

            # FIXME: make the other robots get out of the shot path

            center1.target = robocup.Point(0.0, 1.5)
            center2.target = robocup.Point(1.0, 1.5)

        else:
            # no open shot, shoot it in-between the two centers
            center_x = constants.Field.Width * 0.15
            center_y = constants.Field.Length * 0.6

            center1.target = robocup.Point(-center_x, center_y)
            center2.target = robocup.Point(center_x, center_y)

            kicker.target = robocup.Segment(center1.target, center2.target)
Ejemplo n.º 4
0
def eval_pass(from_point, to_point, excluded_robots=[]):
    # we make a pass triangle with the far corner at the ball and the opposing side touching the receiver's mouth
    # the side along the receiver's mouth is the 'receive_seg'
    # we then use the window evaluator on this scenario to see if the pass is open
    pass_angle = math.pi / 32.0
    pass_dist = to_point.dist_to(from_point)
    pass_dir = to_point - from_point
    pass_perp = pass_dir.perp_ccw()
    receive_seg_half_len = math.tan(pass_angle) * pass_dist
    receive_seg = robocup.Segment(to_point + pass_perp * receive_seg_half_len,
                                  to_point + pass_perp * -receive_seg_half_len)

    win_eval = robocup.WindowEvaluator(main.system_state())
    for r in excluded_robots:
        win_eval.add_excluded_robot(r)
    windows, best = win_eval.eval_pt_to_seg(from_point, receive_seg)

    # this is our estimate of the likelihood of the pass succeeding
    # value can range from zero to one
    # we square the ratio of best to total to make it weigh more - we could raise it to higher power if we wanted
    if best != None:
        return 0.8 * (best.segment.length() / receive_seg.length())**2
    else:
        # the pass is completely blocked
        return 0
Ejemplo n.º 5
0
    def on_enter_passing(self):
        #capture = self.subbehavior_with_name('capture')
        #passRobot1 = self.subbehavior_with_name('moveA')
        #passRobot2 = self.subbehavior_with_name('moveB')
        #to_exclude = [capture.robot, passRobot1.robot, passRobot2.robot]

        # Do shot evaluation here
        win_eval = robocup.WindowEvaluator(main.context())
        for r in self.to_exclude:
            win_eval.add_excluded_robot(r)

        _, rob_1_best_shot = win_eval.eval_pt_to_opp_goal(self.passRobot1.pos)
        _, rob_1_best_pass = win_eval.eval_pt_to_pt(self.captureRobot.pos,
                                                    self.passRobot1.pos, 0.3)
        rob_1_chance = 0
        if (rob_1_best_shot and rob_1_best_pass):
            rob_1_chance = rob_1_best_pass.shot_success * rob_1_best_shot.shot_success

        _, rob_2_best_shot = win_eval.eval_pt_to_opp_goal(self.passRobot2.pos)
        _, rob_2_best_pass = win_eval.eval_pt_to_pt(self.captureRobot.pos,
                                                    self.passRobot2.pos, 0.3)
        rob_2_chance = 0
        if (rob_2_best_shot and rob_2_best_pass):
            rob_2_chance = rob_2_best_pass.shot_success * rob_2_best_shot.shot_success

        _, direct_shot = win_eval.eval_pt_to_opp_goal(self.captureRobot.pos)

        direct_success = 0
        if direct_shot:
            if (self.captureRobot.pos.y < 4):
                direct_success = direct_shot.shot_success * 0.7
            else:
                direct_success = direct_shot.shot_success

            if (direct_shot and direct_success > rob_1_chance
                    and direct_success > rob_2_chance):
                self.kick_directly = True
                return

        if rob_1_chance > rob_2_chance:
            self.add_subbehavior(
                tactics.coordinated_pass.CoordinatedPass(self.passRobot1.pos),
                'pass')
        else:
            self.add_subbehavior(
                tactics.coordinated_pass.CoordinatedPass(self.passRobot2.pos),
                'pass')
Ejemplo n.º 6
0
def eval_best_receive_point(kick_point,
                            evaluation_zone=None,
                            ignore_robots=[]):
    win_eval = robocup.WindowEvaluator(main.context())
    for r in ignore_robots:
        win_eval.add_excluded_robot(r)

    targetSeg = constants.Field.TheirGoalSegment

    # Autogenerate kick point
    if evaluation_zone is None:
        evaluation_zone = generate_default_rectangle(kick_point)

    segments = get_segments_from_rect(evaluation_zone)

    if segments is None or len(segments) == 0:
        # We can't do anything.
        return None, None, None
    bestChance = None

    for segment in segments:
        main.debug_drawer().draw_line(segment, constants.Colors.Blue,
                                      "Candidate Lines")
        _, best = win_eval.eval_pt_to_seg(kick_point, segment)

        if best is None: continue

        currentChance = best.shot_success
        # TODO dont only aim for center of goal. Waiting on window_evaluator returning a probability.
        receivePt = best.segment.center()

        _, best = win_eval.eval_pt_to_seg(receivePt, targetSeg)

        if best is None: continue

        currentChance = currentChance * best.shot_success
        if bestChance is None or currentChance > bestChance:
            bestChance = currentChance
            targetPoint = best.segment.center()
            bestpt = receivePt

    if bestpt is None:
        return None, None, None

    return bestpt, targetPoint, bestChance
Ejemplo n.º 7
0
    def execute_shooting(self):
        kicker = skills.line_kick.LineKick()  #skills.pivot_kick.PivotKick()
        #aim for goal segmant
        win_eval = robocup.WindowEvaluator(main.context())

        for g in main.our_robots():
            win_eval.add_excluded_robot(g)

        windows, window = win_eval.eval_pt_to_opp_goal(main.ball().pos)
        if (window != None):
            kicker.target = window.segment.center()
        else:
            kicker.target = constants.Field.TheirGoalSegment

        kicker.aim_params['desperate_timeout'] = 8
        if (not self.has_subbehavior_with_name('kicker')
                or self.subbehavior_with_name('kicker').is_done_running()):
            self.remove_all_subbehaviors()
            self.add_subbehavior(kicker, 'kicker', required=False, priority=5)
Ejemplo n.º 8
0
    def on_enter_passing(self):
        # Do shot evaluation here
        win_eval = robocup.WindowEvaluator(main.system_state())
        for r in self.to_exclude:
            win_eval.add_excluded_robot(r)

        _, rob_1_best_shot = win_eval.eval_pt_to_opp_goal(self.passRobot1.pos)
        _, rob_1_best_pass = win_eval.eval_pt_to_pt(self.captureRobot.pos,
                                                    self.passRobot1.pos, 0.3)
        rob_1_chance = 0
        if (rob_1_best_shot and rob_1_best_pass):
            rob_1_chance = rob_1_best_pass.shot_success * rob_1_best_shot.shot_success

        _, rob_2_best_shot = win_eval.eval_pt_to_opp_goal(self.passRobot2.pos)
        _, rob_2_best_pass = win_eval.eval_pt_to_pt(self.captureRobot.pos,
                                                    self.passRobot2.pos, 0.3)
        rob_2_chance = 0
        if (rob_2_best_shot and rob_2_best_pass):
            rob_2_chance = rob_2_best_pass.shot_success * rob_2_best_shot.shot_success

        _, direct_shot = win_eval.eval_pt_to_opp_goal(self.captureRobot.pos)

        direct_success = 0
        if direct_shot:
            if (self.captureRobot.pos.y < 4):
                direct_success = direct_shot.shot_success * 0.7
            else:
                direct_success = direct_shot.shot_success

            if (direct_shot and direct_success > rob_1_chance
                    and direct_success > rob_2_chance):
                return

        if rob_1_chance > rob_2_chance:
            self.add_subbehavior(
                tactics.coordinated_pass.CoordinatedPass(self.passRobot1.pos),
                'pass')
        else:
            self.add_subbehavior(
                tactics.coordinated_pass.CoordinatedPass(self.passRobot2.pos),
                'pass')
Ejemplo n.º 9
0
 def execute_block(self):
     opposing_kicker = evaluation.ball.opponent_with_ball()
     if opposing_kicker is not None:
         winEval = robocup.WindowEvaluator(main.system_state())
         winEval.excluded_robots = [self.robot]
         best = winEval.eval_pt_to_our_goal(main.ball().pos)[1]
         if best is not None:
             shot_line = robocup.Line(opposing_kicker.pos, main.ball().pos)
             block_line = robocup.Line(
                 robocup.Point(
                     best.segment.get_pt(0).x - constants.Robot.Radius,
                     constants.Robot.Radius),
                 robocup.Point(
                     best.segment.get_pt(1).x + constants.Robot.Radius,
                     constants.Robot.Radius))
             main.system_state().draw_line(block_line, (255, 0, 0), "Debug")
             dest = block_line.line_intersection(shot_line)
             dest.x = min(Goalie.MaxX, dest.x)
             dest.x = max(-Goalie.MaxX, dest.x)
             self.robot.move_to(dest)
             return
     self.robot.move_to(robocup.Point(0, constants.Robot.Radius))
Ejemplo n.º 10
0
 def recalculate_aim_target_point(self):
     if self.robot != None:
         # find the point we want to aim at
         if isinstance(self.target, robocup.Point):
             self._aim_target_point = self.target
         elif isinstance(self.target, robocup.Segment):
             if self.use_windowing:
                 win_eval = robocup.WindowEvaluator(main.system_state())
                 for key, value in self.win_eval_params.items():
                     setattr(win_eval, key, value)
                 win_eval.chip_enabled = self.robot.has_chipper(
                 ) and self.use_chipper
                 windows, best = win_eval.eval_pt_to_seg(
                     main.ball().pos, self.target)
                 if best != None:
                     self._aim_target_point = best.segment.center()
                 else:
                     self._aim_target_point = self.target.center()
             else:
                 self._aim_target_point = self.target.center()
         else:
             raise AssertionError("Expected Point or Segment, found: " +
                                  str(self.target))
 def execute_running(self):
     win_eval = robocup.WindowEvaluator(main.system_state())
     win_eval.debug = True
     windows, best = win_eval.eval_pt_to_our_goal(main.ball().pos)
Ejemplo n.º 12
0
def find_gap(target_pos=constants.Field.TheirGoalSegment.center(), max_shooting_angle=60, robot_offset=8, dist_from_point=.75):
    if (not main.ball().valid):
        return target_pos

    # Find the hole in the defenders to kick at
    # The limit is 20 cm so any point past it should be defenders right there
    win_eval = robocup.WindowEvaluator(main.system_state())

    # 500 cm min circle distance plus the robot width
    test_distance = dist_from_point + constants.Robot.Radius

    # +- max offset to dodge ball
    max_angle = max_shooting_angle * constants.DegreesToRadians

    # How much left and right of a robot to give
    # Dont make this too big or it will always go far to the right or left of the robots
    robot_angle_offset = robot_offset * constants.DegreesToRadians

    zero_point = robocup.Point(0, 0)

    # Limit the angle so as we get closer, we dont miss the goal completely as much
    goal_vector = target_pos - main.ball().pos
    max_length_vector = robocup.Point(constants.Field.Length, constants.Field.Width)
    goal_limit = (goal_vector.mag() / max_length_vector.mag()) * max_angle

    # Limit on one side so we dont directly kick out of bounds
    # Add in the angle from the sideline to the target
    field_limit = (1 - abs(main.ball().pos.x) / (constants.Field.Width / 2)) * max_angle
    field_limit = field_limit + goal_vector.angle_between(robocup.Point(0, 1))

    # Limit the angle based on the opponent robots to try and always minimize the
    left_robot_limit = 0
    right_robot_limit = 0

    for robot in main.their_robots():
        ball_to_bot = robot.pos - main.ball().pos

        # Add an extra radius as wiggle room
        # kick eval already deals with the wiggle room so it isn't needed there
        if (ball_to_bot.mag() <= test_distance + constants.Robot.Radius):
            angle = goal_vector.angle_between(ball_to_bot)

            # Try and rotate onto the goal vector
            # if we actually do, then the robot is to the right of the ball vector
            ball_to_bot.rotate(zero_point, angle)
            if (ball_to_bot.angle_between(goal_vector) < 0.01):
                right_robot_limit = max(right_robot_limit, angle + robot_angle_offset)
            else:
                left_robot_limit = max(left_robot_limit, angle + robot_angle_offset)
        else:
            win_eval.add_excluded_robot(robot)


    # Angle limit on each side of the bot->goal vector
    left_angle = max_angle
    right_angle = max_angle

    # Make sure we limit the correct side due to the field
    if main.ball().pos.x < 0:
        left_angle = min(left_angle, field_limit)
    else:
        right_angle = min(right_angle, field_limit)

    # Limit due to goal
    left_angle = min(left_angle, goal_limit)
    right_angle = min(right_angle, goal_limit)

    # Limit to just over the robots
    if (left_robot_limit is not 0):
        left_angle = min(left_angle, left_robot_limit)
    if (right_robot_limit is not 0):
        right_angle = min(right_angle, right_robot_limit)

    # Get the angle that we need to rotate the target angle behind the defenders
    # since kick eval doesn't support a nonsymmetric angle around a target
    rotate_target_angle = (left_angle + -right_angle)/2
    target_width = (left_angle + right_angle)

    target_point = goal_vector.normalized() * test_distance
    target_point.rotate(zero_point, rotate_target_angle)

    windows, window = win_eval.eval_pt_to_pt(main.ball().pos, target_point + main.ball().pos, target_width)

    # Test draw points
    target_point.rotate(zero_point, target_width/2)
    p1 = target_point + main.ball().pos
    target_point.rotate(zero_point, -target_width)
    p2 = target_point + main.ball().pos
    p3 = main.ball().pos
    main.system_state().draw_polygon([p1, p2, p3], (0, 0, 255), "Free Kick search zone")


    is_opponent_blocking = False

    for robot in main.their_robots():
        if (goal_vector.dist_to(robot.pos) < constants.Robot.Radius and
            (main.ball().pos - robot.pos).mag() < test_distance):
            is_opponent_blocking = True

    # Vector from ball position to the goal
    ideal_shot = (target_pos - main.ball().pos).normalized()

    # If on our side of the field and there are enemy robots around us,
    # prioritize passing forward vs passing towards their goal
    # Would have to change this if we are not aiming for their goal
    if main.ball().pos.y < constants.Field.Length / 2 and len(windows) > 1:
        ideal_shot = robocup.Point(0, 1)

    main.system_state().draw_line(robocup.Line(main.ball().pos, target_pos), (0, 255, 0), "Target Point")

    # Weights for determining best shot
    k1 = 1.5 # Weight of closeness to ideal shot
    k2 = 1 # Weight of shot chance

    # print("ideal shot:", ideal_shot)
    # print("number of windows:", len(windows))
    # Iterate through all possible windows to find the best possible shot
    if windows:
        best_shot = window.segment.center()
        best_weight = 0
        for wind in windows:
            pos_to_wind = (wind.segment.center() - main.ball().pos).normalized()
            dot_prod = pos_to_wind.dot(ideal_shot)
            # print("weighted dot product:", dot_prod)
            # print("weighted shot chance:", wind.shot_success)
            weight = k1 * dot_prod + k2 * wind.shot_success
            if weight > best_weight:
                best_weight = weight
                best_shot = wind.segment.center()

        main.system_state().draw_line(robocup.Line(main.ball().pos, best_shot), (255, 255, 0), "Target Shot")

        best_shot = robocup.Point(0,1) + main.ball().pos
        return best_shot
    else:
        return constants.Field.TheirGoalSegment.center()