예제 #1
0
    def on_enter_clear(self):
        # FIXME: what we really want is a less-precise LineKick
        #           this will require a Capture behavior that doesn't wait for the ball to stop
        kick = skills.pivot_kick.PivotKick()

        # TODO: the below dribble speed is best for a 2011 bot
        # kick.dribble_speed = constants.Robot.Dribbler.MaxPower / 3.5

        # we use low error thresholds here
        # the goalie isn't trying to make a shot, he just wants get the ball the **** out of there
        kick.aim_params['error_threshold'] = 1.0
        kick.aim_params['max_steady_ang_vel'] = 12

        # chip
        kick.chip_power = 1.0
        kick.use_chipper = True

        kick.target = robocup.Segment(
            robocup.Point(-constants.Field.Width / 2, constants.Field.Length),
            robocup.Point(constants.Field.Width / 2, constants.Field.Length))

        # FIXME: if the goalie has a fault, resort to bump

        self.add_subbehavior(kick, 'kick-clear', required=True)
def get_segments_from_rect(rect, threshold=0.75):
    outlist = []
    currentx = rect.min_x()
    currenty = rect.max_y()

    # Loop through from top left to bottom right

    while currentx <= rect.max_x():
        currenty = rect.max_y()
        # Don't include goal area.
        if constants.Field.TheirGoalZoneShape.contains_point(robocup.Point(
                currentx, rect.min_y())):
            continue
        while constants.Field.TheirGoalZoneShape.contains_point(robocup.Point(
            currentx, currenty)):
            currenty = currenty - threshold

        candiate = robocup.Segment(
            robocup.Point(currentx, rect.min_y()), robocup.Point(currentx,
                                                                 currenty))
        outlist.extend([candiate])
        currentx = currentx + threshold
    currentx = rect.min_x()
    return outlist
    def execute_marking(self):
        move = self.subbehavior_with_name('move')
        move.pos = self.move_target

        arc_left = robocup.Arc(
            robocup.Point(-constants.Field.GoalFlat / 2, 0),
            constants.Field.ArcRadius + constants.Robot.Radius * 2,
            math.pi / 2, math.pi)
        arc_right = robocup.Arc(
            robocup.Point(constants.Field.GoalFlat / 2, 0),
            constants.Field.ArcRadius + constants.Robot.Radius * 2, 0,
            math.pi / 2)
        seg = robocup.Segment(
            robocup.Point(
                -constants.Field.GoalFlat / 2,
                constants.Field.ArcRadius + constants.Robot.Radius * 2),
            robocup.Point(
                constants.Field.GoalFlat / 2,
                constants.Field.ArcRadius + constants.Robot.Radius * 2))

        if move.pos is not None:
            main.system_state().draw_circle(move.pos, 0.02,
                                            constants.Colors.Green, "Mark")
            main.system_state().draw_segment(seg, constants.Colors.Green,
                                             "Mark")
            main.system_state().draw_arc(arc_left, constants.Colors.Green,
                                         "Mark")
            main.system_state().draw_arc(arc_right, constants.Colors.Green,
                                         "Mark")

        # make the defender face the threat it's defending against
        if (self.robot is not None and self.block_line is not None):
            self.robot.face(self.block_line.get_pt(0))

        if self.robot.has_ball() and not main.game_state().is_stopped():
            self.robot.kick(0.75)
예제 #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 = evaluation.window_evaluator.WindowEvaluator()
    win_eval.excluded_robots = excluded_robots
    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
예제 #5
0
class LineUp(composite_behavior.CompositeBehavior):

    DEBOUNCE_MAX = 3
    y_start = 1.2  # sometimes we have issues if we're right in the corner, so we move it up a bit
    DefaultLine = robocup.Segment(
        robocup.Point(-constants.Field.Width / 2 + constants.Robot.Radius,
                      constants.Robot.Radius + y_start),
        robocup.Point(-constants.Field.Width / 2 + constants.Robot.Radius,
                      (constants.Robot.Radius * 2 + 0.1 + y_start) * 6))

    def __init__(self, line=None):
        super().__init__(continuous=False)

        self.line = line if line is not None else LineUp.DefaultLine
        self.debounce_count = 0

        self.add_transition(behavior.Behavior.State.start,
                            behavior.Behavior.State.running, lambda: True,
                            'immediately')
        self.add_transition(behavior.Behavior.State.running,
                            behavior.Behavior.State.completed,
                            lambda: self.all_subbehaviors_completed(),
                            'all robots reach target positions')
        self.add_transition(behavior.Behavior.State.completed,
                            behavior.Behavior.State.running,
                            lambda: not self.all_subbehaviors_completed(),
                            'robots arent lined up')

    def restart(self):
        super().restart()
        self.debounce_count = 0

    # override superclass implementation of all_subbehaviors_completed() to
    # count unassigned subbehaviors as "done running"
    def all_subbehaviors_completed(self):
        for bhvr in self.all_subbehaviors():
            if not bhvr.is_done_running() and (not isinstance(
                    bhvr, SingleRobotBehavior) or bhvr.robot is not None):
                self.debounce_count = 0
                return False
        # Give us a few cycles to change our mind
        if self.debounce_count < LineUp.DEBOUNCE_MAX:
            self.debounce_count += 1
            return False
        else:
            return True

    def execute_running(self):
        for i in range(6):
            pt = self._line.get_pt(0) + (self.diff * float(i))
            behavior = self.subbehavior_with_name("robot" + str(i))
            behavior.pos = pt

    @property
    def line(self):
        return self._line

    @line.setter
    def line(self, value):
        self._line = value
        self.diff = (self._line.get_pt(1) - self._line.get_pt(0)
                     ).normalized() * (self._line.length() / 5.0)

        # add subbehaviors for all robots, instructing them to line up
        self.remove_all_subbehaviors()
        for i in range(6):
            pt = self._line.get_pt(0) + (self.diff * float(i))
            self.add_subbehavior(skills.move.Move(pt),
                                 name="robot" + str(i),
                                 required=False,
                                 priority=6 - i)
예제 #6
0
 def execute_intercept(self):
     ball_path = robocup.Segment(
         main.ball().pos,
         main.ball().pos + main.ball().vel.normalized() * 10.0)
     dest = ball_path.nearest_point(self.robot.pos)
     self.robot.move_to(dest)
예제 #7
0
class Goalie(single_robot_composite_behavior.SingleRobotCompositeBehavior):

    OFFSET = 0.1
    MaxX = constants.Field.GoalWidth / 2.0
    RobotSegment = robocup.Segment(
        robocup.Point(-MaxX, constants.Robot.Radius + OFFSET),
        robocup.Point(MaxX, constants.Robot.Radius + OFFSET))
    OpponentFacingThreshold = math.pi / 8.0

    class State(enum.Enum):
        ## Normal gameplay, stay towards the side of the goal that the ball is on.
        defend = 1
        ## Opponent has a ball and is prepping a shot we should block.
        block = 2
        ## The ball is moving towards our goal and we should catch it.
        intercept = 3
        ## Get the ball out of our defense area.
        clear = 4
        ## Prepare to block the opponent's penalty shot
        setup_penalty = 5
        ## Keep calm and wait for the ball to be valid.
        chill = 6

    def __init__(self):
        super().__init__(continuous=True)

        for substate in Goalie.State:
            self.add_state(substate, behavior.Behavior.State.running)

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

        self.add_transition(Goalie.State.chill, Goalie.State.defend,
                            lambda: main.ball().valid, "ball is valid")

        non_chill_states = [s for s in Goalie.State if s != Goalie.State.chill]

        # if ball is invalid, chill
        for state in non_chill_states:
            self.add_transition(state, Goalie.State.chill,
                                lambda: not main.ball().valid,
                                "ball is invalid")

        for state in non_chill_states:
            self.add_transition(
                state, Goalie.State.setup_penalty, lambda: main.game_state(
                ).is_their_penalty() and main.game_state().is_setup_state(),
                "setting up for opponent penalty")

        for state in [
                s2 for s2 in non_chill_states if s2 != Goalie.State.intercept
        ]:
            self.add_transition(
                state, Goalie.State.intercept,
                lambda: evaluation.ball.is_moving_towards_our_goal(
                ) and not self.robot_is_facing_our_goal(evaluation.ball.
                                                        opponent_with_ball()),
                "ball coming towards our goal")

        for state in [
                s2 for s2 in non_chill_states if s2 != Goalie.State.clear
        ]:
            self.add_transition(
                state, Goalie.State.clear,
                lambda: evaluation.ball.is_in_our_goalie_zone(
                ) and not main.game_state().is_their_penalty(
                ) and not evaluation.ball.is_moving_towards_our_goal(
                ) and evaluation.ball.opponent_with_ball() is None,
                "ball in our goalie box, but not headed toward goal")

        for state in [
                s2 for s2 in non_chill_states if s2 != Goalie.State.defend
        ]:
            self.add_transition(
                state, Goalie.State.defend,
                lambda: not evaluation.ball.is_in_our_goalie_zone(
                ) and not evaluation.ball.is_moving_towards_our_goal(
                ) and not main.game_state().is_their_penalty() and not self.
                robot_is_facing_our_goal(evaluation.ball.opponent_with_ball()),
                'not much going on')

        for state in [
                s2 for s2 in non_chill_states if s2 != Goalie.State.block
        ]:
            self.add_transition(
                state, Goalie.State.block,
                lambda: not evaluation.ball.is_in_our_goalie_zone() and
                not evaluation.ball.is_moving_towards_our_goal() and self.
                robot_is_facing_our_goal(evaluation.ball.opponent_with_ball()),
                "opponents have possession")

    def robot_is_facing_our_goal(self, robot):
        if robot is None:
            return False
        goal_robot = robot.pos - robocup.Point(0, 0)
        angle = goal_robot.normalized().angle() - math.pi
        robot_angle = robot.angle * math.pi / 180.
        self.robot.add_text(str(angle - robot_angle), (255, 255, 255),
                            "OurRobot")
        if abs(angle - robot_angle) < self.OpponentFacingThreshold:
            return True
        else:
            return False

    # note that execute_running() gets called BEFORE any of the execute_SUBSTATE methods gets called
    def execute_running(self):
        if self.robot != None:
            self.robot.face(main.ball().pos)
            self.robot.set_planning_priority(planning_priority.GOALIE)

    def execute_chill(self):
        if self.robot != None:
            self.robot.move_to(
                robocup.Point(0, constants.Robot.Radius + Goalie.OFFSET))

    def execute_setup_penalty(self):
        pt = robocup.Point(0, constants.Field.PenaltyDist)
        penalty_kicker = min(main.their_robots(),
                             key=lambda r: (r.pos - pt).mag())
        angle_rad = penalty_kicker.angle
        shot_line = robocup.Line(
            penalty_kicker.pos,
            penalty_kicker.pos + robocup.Point.direction(angle_rad))

        dest = Goalie.RobotSegment.line_intersection(shot_line)
        if dest is None:
            self.robot.move_to(
                robocup.Point(0, constants.Robot.Radius + Goalie.OFFSET))
        else:
            dest.x = max(-Goalie.MaxX + constants.Robot.Radius, dest.x)
            dest.x = min(Goalie.MaxX - constants.Robot.Radius, dest.x)
            # Shots don't follow the top threat, they follow the inverse
            # FIXME this is kind of a hack
            dest.x = -dest.x
            self.robot.move_to(dest)

    def on_enter_clear(self):
        # FIXME: what we really want is a less-precise LineKick
        #           this will require a Capture behavior that doesn't wait for the ball to stop
        kick = skills.pivot_kick.PivotKick()

        # TODO: the below dribble speed is best for a 2011 bot
        # kick.dribble_speed = constants.Robot.Dribbler.MaxPower / 3.5

        # we use low error thresholds here
        # the goalie isn't trying to make a shot, he just wants get the ball the **** out of there
        kick.aim_params['error_threshold'] = 1.0
        kick.aim_params['max_steady_ang_vel'] = 12

        # chip
        kick.chip_power = 1.0
        kick.use_chipper = True

        kick.target = robocup.Segment(
            robocup.Point(-constants.Field.Width / 2, constants.Field.Length),
            robocup.Point(constants.Field.Width / 2, constants.Field.Length))

        # FIXME: if the goalie has a fault, resort to bump

        self.add_subbehavior(kick, 'kick-clear', required=True)

    def on_exit_clear(self):
        self.remove_subbehavior('kick-clear')

    def on_enter_intercept(self):
        i = skills.intercept.Intercept()
        self.add_subbehavior(i, 'intercept', required=True)

    def execute_intercept(self):
        ball_path = robocup.Segment(
            main.ball().pos,
            main.ball().pos + main.ball().vel.normalized() * 10.0)
        dest = ball_path.nearest_point(self.robot.pos)
        self.robot.move_to(dest)

    def on_exit_intercept(self):
        self.remove_subbehavior('intercept')

    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 + Goalie.OFFSET))

    def execute_defend(self):
        dest_x = main.ball().pos.x / constants.Field.Width * Goalie.MaxX
        self.robot.move_to(
            robocup.Point(dest_x, constants.Robot.Radius + Goalie.OFFSET))

    def role_requirements(self):
        reqs = super().role_requirements()

        for req in role_assignment.iterate_role_requirements_tree_leaves(reqs):
            req.required_shell_id = self.shell_id if self.shell_id != None else -1

        return reqs

    @property
    def shell_id(self):
        return self._shell_id

    @shell_id.setter
    def shell_id(self, value):
        self._shell_id = value
예제 #8
0
    def recalculate(self):
        goalie = self.subbehavior_with_name('goalie')
        defender1 = self.subbehavior_with_name('defender1')
        defender2 = self.subbehavior_with_name('defender2')
        behaviors = [goalie, defender1, defender2]

        # if we don't have any bots to work with, don't waste time calculating
        if all(bhvr.robot == None for bhvr in behaviors):
            return

        # A threat to our goal - something we'll actively defend against
        class Threat:
            def __init__(self, source=None):
                self.source = source
                self.ball_acquire_chance = 1.0
                self.shot_chance = 1.0
                self.assigned_handlers = []
                self.best_shot_window = None

            # an OpponentRobot or Point
            @property
            def source(self):
                return self._source

            @source.setter
            def source(self, value):
                self._source = value

            # our source can be a Point or an OpponentRobot, this method returns the location of it
            @property
            def pos(self):
                if self.source != None:
                    return self.source if isinstance(
                        self.source, robocup.Point) else self.source.pos

            # a list of our behaviors that will be defending against this threat
            # as of now only Defender and Goalie
            @property
            def assigned_handlers(self):
                return self._assigned_handlers

            @assigned_handlers.setter
            def assigned_handlers(self, value):
                self._assigned_handlers = value

            # our estimate of the chance that this threat will acquire the ball
            # 1.0 if it already has it
            # otherwise, a value from 0 to 1 gauging its likelihood to receive a pass
            @property
            def ball_acquire_chance(self):
                return self._ball_acquire_chance

            @ball_acquire_chance.setter
            def ball_acquire_chance(self, value):
                self._ball_acquire_chance = value

            # our estimate of the chance of this threat making its shot on the goal given that it gets/has the ball
            # NOTE: this is calculated excluding all of our robots on the field as obstacles
            @property
            def shot_chance(self):
                return self._shot_chance

            @shot_chance.setter
            def shot_chance(self, value):
                self._shot_chance = value

            # his best window on our goal
            @property
            def best_shot_window(self):
                return self._best_shot_window

            @best_shot_window.setter
            def best_shot_window(self, value):
                self._best_shot_window = value

            # our assessment of the risk of this threat
            # should be between 0 and 1
            @property
            def score(self):
                return self.ball_acquire_chance * self.shot_chance

            # available behaviors we have to assign to threats
            # only look at ones that have robots
            # as we handle threats, we remove the handlers from this list

        unused_threat_handlers = list(
            filter(lambda bhvr: bhvr.robot != None,
                   [goalie, defender1, defender2]))

        def set_block_lines_for_threat_handlers(threat):
            if len(threat.assigned_handlers) == 0:
                return

            # make sure goalie is in the middle
            if len(threat.assigned_handlers) > 1:
                if goalie in threat.assigned_handlers:
                    idx = threat.assigned_handlers.index(goalie)
                    if idx != 1:
                        del threat.assigned_handlers[idx]
                        threat.assigned_handlers.insert(1, goalie)

            if threat.best_shot_window != None:
                center_line = robocup.Line(
                    threat.pos, threat.best_shot_window.segment.center())
            else:
                center_line = robocup.Line(
                    threat.pos, constants.Field.OurGoalSegment.center())

            # find the angular width that each defender can block.  We then space these out accordingly
            angle_widths = []
            for handler in threat.assigned_handlers:
                dist_from_threat = handler.robot.pos.dist_to(threat.pos)
                w = min(
                    2.0 * math.atan2(constants.Robot.Radius, dist_from_threat),
                    0.15)
                angle_widths.append(w)

            # start on one edge of our available angle coverage and work counter-clockwise,
            # assigning block lines to the bots as we go
            spacing = 0.01 if len(
                threat.assigned_handlers
            ) < 3 else 0.0  # spacing between each bot in radians
            total_angle_coverage = sum(angle_widths) + (len(angle_widths) -
                                                        1) * spacing
            start_vec = center_line.delta().normalized()
            start_vec.rotate(robocup.Point(0, 0), -total_angle_coverage / 2.0)
            for i in range(len(angle_widths)):
                handler = threat.assigned_handlers[i]
                w = angle_widths[i]
                start_vec.rotate(robocup.Point(0, 0), w / 2.0)
                handler.block_line = robocup.Line(threat.pos,
                                                  threat.pos + start_vec * 10)
                start_vec.rotate(robocup.Point(0, 0), w / 2.0 + spacing)

        def recalculate_threat_shot(threat_index):
            if not isinstance(threat_index, int):
                raise TypeError("threat_index should be an int")

            # ignore all of our robots
            excluded_robots = list(main.our_robots())

            # behaviors before this threat are counted as obstacles in their TARGET position (where we've
            # assigned them to go, not where they are right now)
            hypothetical_obstacles = []
            for t in threats[0:threat_index]:
                hypothetical_obstacles.extend(
                    map(lambda bhvr: bhvr.move_target, t.assigned_handlers))

            threat = threats[threat_index]
            self.win_eval.excluded_robots.clear()
            for r in excluded_robots:
                self.win_eval.add_excluded_robot(r)
            _, threat.best_shot_window = self.win_eval.eval_pt_to_our_goal(
                threat.pos)
            if threat.best_shot_window is not None:
                threat.shot_chance = threat.best_shot_window.shot_success
            else:
                threat.shot_chance = 0.0

        threats = []

        # secondary threats are those that are somewhat close to our goal and open for a pass
        # if they're farther than this down the field, we don't consider them threats
        threat_max_y = constants.Field.Length / 2.0
        potential_threats = [
            opp for opp in main.their_robots() if opp.pos.y < threat_max_y
        ]

        # find the primary threat
        # if the ball is not moving OR it's moving towards our goal, it's the primary threat
        # if it's moving, but not towards our goal, the primary threat is the robot on their team most likely to catch it
        if main.ball().vel.mag() > 0.4:
            # the line the ball's moving along
            ball_travel_line = robocup.Line(main.ball().pos,
                                            main.ball().pos + main.ball().vel)

            # this is a shot on the goal!
            if evaluation.ball.is_moving_towards_our_goal():
                ball_threat = Threat(main.ball().pos)
                ball_threat.ball_acquire_chance = 1.0
                ball_threat.shot_chance = 1.0
                threats.append(ball_threat)
            else:
                # Check for a bot that's about to capture this ball and potentially shoot on the goal
                # potential_receivers is an array of (OpponentRobot, angle) tuples, where the angle
                # is the angle between the ball_travel_line and the line from the ball to the opponent
                # bot - this is our metric for receiver likeliness.
                potential_receivers = []
                for opp in potential_threats:
                    # see if the bot is in the direction the ball is moving
                    if (opp.pos - ball_travel_line.get_pt(0)).dot(
                            ball_travel_line.delta()) > 0:
                        # calculate the angle and add it to the list if it's within reason
                        nearest_pt = ball_travel_line.nearest_point(opp.pos)
                        dx = (nearest_pt - main.ball().pos).mag()
                        dy = (opp.pos - nearest_pt).mag()
                        angle = abs(math.atan2(dy, dx))
                        if angle < math.pi / 4.0:
                            potential_receivers.append((opp, 1.0))

                # choose the receiver with the smallest angle from the ball travel line
                if len(potential_receivers) > 0:
                    best_receiver_tuple = min(
                        potential_receivers,
                        key=lambda rcrv_tuple: rcrv_tuple[1])
                    if best_receiver_tuple != None:
                        receiver_threat = Threat(best_receiver_tuple[0])
                        receiver_threat.ball_acquire_chance = 0.9  # note: this value is arbitrary
                        receiver_threat.shot_chance = 0.9  # FIXME: calculate this
                        threats.append(receiver_threat)
                else:
                    ball_threat = Threat(main.ball().pos)
                    ball_threat.ball_acquire_chance = 1.0
                    ball_threat.shot_chance = 0.9
                    threats.append(ball_threat)

        else:
            # primary threat is the ball or the opponent holding it
            opp_with_ball = evaluation.ball.opponent_with_ball()

            threat = Threat(
                opp_with_ball if opp_with_ball != None else main.ball().pos)
            threat.ball_acquire_chance = 1.0
            threat.shot_chance = 1.0  # FIXME: calculate, don't use 1.0
            threats.append(threat)

# if an opponent has the ball or is potentially about to receive the ball,
# we look at potential receivers of it as threats
        if isinstance(threats[0].source, robocup.OpponentRobot):
            for opp in filter(lambda t: t.visible, potential_threats):
                pass_chance = evaluation.passing.eval_pass(
                    main.ball().pos, opp.pos, excluded_robots=[opp])
                # give it a small chance because the obstacles in the way could move soon and we don't want to consider it a zero threatos, )
                if pass_chance < 0.001: pass_chance = 0.4

                # record the threat
                threat = Threat(opp)
                threat.ball_acquire_chance = pass_chance
                threats.append(threat)

                # Now we evaluate this opponent's shot on the goal
                # exclude robots that have already been assigned to handle other threats
                self.win_eval.excluded_robots.clear()
                for r in map(lambda bhvr: bhvr.robot, unused_threat_handlers):
                    self.win_eval.add_excluded_robot(r)
                _, threat.best_shot_window = self.win_eval.eval_pt_to_our_goal(
                    opp.pos)
                if threat.best_shot_window is not None:
                    threat.shot_chance = threat.best_shot_window.shot_success
                else:
                    threat.shot_chance = 0.0

                if threat.shot_chance == 0:
                    # gve it a small chance because the shot could clear up a bit later and we don't want to consider it a zero threat
                    threat.shot_chance = 0.2

        else:
            # the ball isn't possessed by an opponent, so we just look at opponents with shots on the goal
            for opp in potential_threats:
                # record the threat
                lurker = Threat(opp)
                lurker.ball_acquire_chance = 0.5  # note: this is a bullshit value
                threats.append(lurker)
                recalculate_threat_shot(len(threats) - 1)

        # only consider the top three threats
        threats.sort(key=lambda threat: threat.score, reverse=True)
        threats = threats[0:3]

        # print("sorted threats:")
        # for idx, t in enumerate(threats):
        #     print("t[" + str(idx) + "]: " + str(t.source) + "shot: " + str(t.shot_chance) + "; pass:"******"; score:" + str(t.score))

        # print("sorted threat scores: " + str(list(map(lambda t: str(t.score) + " " + str(t.source), threats))))

        # print("Unused handlers: " + str(unused_threat_handlers))
        # print("---------------------")

        smart = False
        if not smart:

            # only deal with top two threats
            threats_to_block = threats[0:2]

            # print('threats to block: ' + str(list(map(lambda t: t.source, threats_to_block))))
            threat_idx = 0
            while len(unused_threat_handlers) > 0:
                threats_to_block[threat_idx].assigned_handlers.append(
                    unused_threat_handlers[0])
                del unused_threat_handlers[0]

                threat_idx = (threat_idx + 1) % len(threats_to_block)

            for t_idx, t in enumerate(threats_to_block):
                recalculate_threat_shot(t_idx)
                set_block_lines_for_threat_handlers(t)

        else:
            # assign all of our defenders to do something
            while len(unused_threat_handlers) > 0:
                # prioritize by threat score, highest first
                top_threat = max(threats, key=lambda threat: threat.score)

                # assign the next handler to this threat
                handler = unused_threat_handlers[0]
                top_threat.assigned_handlers.append(handler)
                del unused_threat_handlers[0]

                # reassign the block line for each handler of this threat
                set_block_lines_for_threat_handlers(top_threat)

                # recalculate the shot now that we have
                recalculate_threat_shot(0)

        # tell the bots where to move / what to block and draw some debug stuff
        for idx, threat in enumerate(threats):

            # recalculate, including all current bots
            # FIXME: do we want this?
            # recalculate_threat_shot(idx)

            # the line they'll be shooting down/on
            if threat.best_shot_window != None:
                shot_line = robocup.Segment(
                    threat.pos, threat.best_shot_window.segment.center())
            else:
                shot_line = robocup.Segment(threat.pos, robocup.Point(0, 0))

            # debug output
            if self.debug:
                for handler in threat.assigned_handlers:
                    # handler.robot.add_text("Marking: " + str(threat.source), constants.Colors.White, "Defense")
                    main.system_state().draw_circle(handler.move_target, 0.02,
                                                    constants.Colors.Blue,
                                                    "Defense")

                # draw some debug stuff
                if threat.best_shot_window != None:
                    # draw shot triangle
                    pts = [
                        threat.pos,
                        threat.best_shot_window.segment.get_pt(0),
                        threat.best_shot_window.segment.get_pt(1)
                    ]
                    shot_color = (255, 0, 0, 150)  # translucent red
                    main.system_state().draw_polygon(pts, shot_color,
                                                     "Defense")
                    main.system_state().draw_segment(
                        threat.best_shot_window.segment, constants.Colors.Red,
                        "Defense")

                    self.win_eval.excluded_robots.clear()
                    _, best_window = self.win_eval.eval_pt_to_our_goal(
                        threat.pos)
                    if best_window is not None:
                        chance = best_window.shot_success
                    else:
                        chance = 0.0

                    main.system_state().draw_text(
                        "Shot: " + str(int(threat.shot_chance * 100.0)) +
                        "% / " + str(int(chance * 100)) + "%",
                        shot_line.center(), constants.Colors.White, "Defense")

                # draw pass lines
                if idx > 0:
                    pass_line = robocup.Segment(main.ball().pos, threat.pos)
                    main.system_state().draw_line(pass_line,
                                                  constants.Colors.Red,
                                                  "Defense")
                    main.system_state().draw_text(
                        "Pass: "******"%",
                        pass_line.center(), constants.Colors.White, "Defense")
예제 #9
0
    def execute_marking(self):
        #main.system_state().draw_line(robocup.Line(self._area.get_pt(0), self._area.get_pt(1)), (127,0,255), "Defender")
        self.block_robot = self.find_robot_to_block()
        if self.block_robot is not None:
            # self.robot.add_text("Blocking Robot " + str(self.block_robot.shell_id()), (255,255,255), "RobotText")
            pass
        if self.robot.pos.near_point(robocup.Point(0, 0),
                                     self._opponent_avoid_threshold):
            self.robot.set_avoid_opponents(False)
        else:
            self.robot.set_avoid_opponents(True)

        target = None
        if self.block_robot is None:
            target = main.ball().pos + main.ball().vel * 0.3
        else:
            target = self.block_robot.pos + self.block_robot.vel * 0.3

        goal_line = robocup.Segment(
            robocup.Point(-constants.Field.GoalWidth / 2.0, 0),
            robocup.Point(constants.Field.GoalWidth / 2.0, 0))

        self._win_eval.excluded_robots = [self.robot]

        # TODO defenders should register themselves with some static list on init
        # TODO make this happen in python-land
        # for (Defender *f :  otherDefenders)
        # {
        # 	if (f->robot)
        # 	{
        # 		_winEval.exclude.push_back(f->robot->pos);
        # 	}
        # }

        windows = self._win_eval.eval_pt_to_seg(target, goal_line)[0]

        best = None
        goalie = main.our_robot_with_id(main.root_play().goalie_id)

        if goalie is not None and self.side is not Defender.Side.center:
            for window in windows:
                if best is None:
                    best = window
                elif self.side is Defender.Side.left and window.segment.center.x < goalie.pos.x and window.segment.length > best.segment.length:
                    best = window
                elif self.side is Defender.Side.right and window.segment.center.x > goalie.pos.x and window.segment.length > best.segment.length:
                    best = window
        else:
            best_dist = 0
            for window in windows:
                seg = robocup.Segment(window.segment.center(), main.ball().pos)
                new_dist = seg.dist_to(self.robot.pos)
                if best is None or new_dist < best_dist:
                    best = window
                    best_dist = new_dist

        shoot_seg = None
        if best is not None:
            if self.block_robot is not None:
                dirvec = robocup.Point.direction(self.block_robot.angle *
                                                 (math.pi / 180.0))
                shoot_seg = robocup.Segment(
                    self.block_robot.pos, self.block_robot.pos + dirvec * 7.0)
            else:
                shoot_seg = robocup.Segment(
                    main.ball().pos,
                    main.ball().pos + main.ball().vel.normalized() * 7.0)

        need_task = False
        if best is not None:
            winseg = best.segment
            if main.ball().vel.magsq() > 0.03 and winseg.segment_intersection(
                    shoot_seg) != None:
                self.robot.move_to(shoot_seg.nearest_point(self.robot.pos))
                self.robot.face_none()
            else:
                winsize = winseg.length()

                if winsize < constants.Ball.Radius:
                    need_task = True
                else:
                    arc = robocup.Circle(robocup.Point(0, 0),
                                         self._defend_goal_radius)
                    shot = robocup.Line(winseg.center(), target)
                    dest = [robocup.Point(0, 0), robocup.Point(0, 0)]

                    intersected, dest[0], dest[1] = shot.intersects_circle(arc)

                    if intersected:
                        self.robot.move_to(
                            dest[0] if dest[0].y > 0 else dest[1])
                        if self.block_robot is not None:
                            self.robot.face(self.block_robot.pos)
                        else:
                            self.robot.face(main.ball().pos)
                    else:
                        need_task = True
        if need_task:
            self.robot.face(main.ball().pos)

        backVec = robocup.Point(1, 0)
        backPos = robocup.Point(-constants.Field.Width / 2, 0)
        shotVec = robocup.Point(main.ball().pos - self.robot.pos)
        backVecRot = robocup.Point(backVec.perp_ccw())
        facing_back_line = (backVecRot.dot(shotVec) < 0)
        if not facing_back_line and self.robot.has_ball():
            if self.robot.has_chipper():
                self.robot.chip(255)
            else:
                self.robot.kick(255)
예제 #10
0
    def execute_area_marking(self):
        if self.robot.pos.near_point(robocup.Point(0, 0),
                                     self._opponent_avoid_threshold):
            self.robot.set_avoid_opponents(False)
        else:
            self.robot.set_avoid_opponents(True)
        goal_target = robocup.Point(0, -constants.Field.GoalDepth / 2.0)
        goal_line = robocup.Segment(
            robocup.Point(-constants.Field.GoalWidth / 2.0, 0),
            robocup.Point(constants.Field.GoalWidth / 2.0, 0))

        if self.side is Defender.Side.left:
            goal_line.get_pt(1).x = 0
            goal_line.get_pt(1).y = 0
        if self.side is Defender.Side.right:
            goal_line.get_pt(0).x = 0
            goal_line.get_pt(0).y = 0

        for robot in main.system_state().their_robots:
            self._win_eval.excluded_robots.append(robot)

        if main.root_play().goalie_id is not None:
            self._win_eval.excluded_robots.append(
                main.our_robot_with_id(main.root_play().goalie_id))

        # TODO (cpp line 186)
        # windows = self._win_eval.
        windows = []

        best = None
        angle = 0.0
        for window in windows:
            if best is None:
                best = window
                angle = window.a0 - window.a1
            elif window.a0 - window.a1 > angle:
                best = window
                angle = window.a0 - window.a1

        shootline = robocup.Segment(robocup.Point(0, 0), robocup.Point(0, 0))
        if best is not None:
            angle = (best.a0 + best.a1) / 2.0
            shootline = robocup.Segment(
                self._win_eval.origin(),
                robocup.Point.direction(
                    angle * (math.pi / 180.0)))  # FIXME :no origin.
            main.system_state().draw_line(shootline, (255, 0, 0), "Defender")

        need_task = False
        if best is not None:
            winseg = best.segment
            arc = robocup.Circle(robocup.Point(0, 0), self._defend_goal_radius)
            shot = robocup.Line(shootline.get_pt(0), shootline.get_pt(1))
            dest = [robocup.Point(0, 0), robocup.Point(0, 0)]
            intersected, dest[0], dest[1] = shot.intersects_circle(arc)
            if intersected:
                self.robot.move_to(dest[0] if dest[0].y > 0 else dest[1])
            else:
                need_task = True
        if need_task:
            self.robot.face(main.ball().pos)

        if main.ball().pos.y < constants.Field.Length / 2.0:
            self.robot.set_dribble_speed(255)

        backVec = robocup.Point(1, 0)
        backPos = robocup.Point(-constants.Field.Width / 2, 0)
        shotVec = robocup.Point(main.ball().pos - self.robot.pos)
        backVecRot = robocup.Point(backVec.perp_ccw())
        facing_back_line = (backVecRot.dot(shotVec) < 0)
        if not facing_back_line and self.robot.has_ball():
            if self.robot.has_chipper():
                self.robot.chip(255)
            else:
                self.robot.kick(255)
예제 #11
0
class SubmissiveGoalie(
        single_robot_composite_behavior.SingleRobotCompositeBehavior):

    MaxX = constants.Field.GoalWidth / 2.0
    SegmentY = constants.Robot.Radius + 0.05

    # The segment we stay on during the 'block' state
    # It's right in front of the goal
    RobotSegment = robocup.Segment(robocup.Point(-MaxX, SegmentY),
                                   robocup.Point(MaxX, SegmentY))

    class State(enum.Enum):
        "Actively blocking based on a given threat"
        block = 2
        "The ball is moving towards our goal and we should catch it."
        intercept = 3
        "Get the ball out of our defense area."
        clear = 4

    def __init__(self):
        super().__init__(continuous=True)

        for substate in SubmissiveGoalie.State:
            self.add_state(substate, behavior.Behavior.State.running)

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

        non_block_states = [
            s for s in SubmissiveGoalie.State
            if s != SubmissiveGoalie.State.block
        ]

        for state in [
                s2 for s2 in SubmissiveGoalie.State
                if s2 != SubmissiveGoalie.State.intercept
        ]:
            self.add_transition(
                state, SubmissiveGoalie.State.intercept,
                lambda: evaluation.ball.is_moving_towards_our_goal(),
                "ball coming towards our goal")

        for state in [
                s2 for s2 in SubmissiveGoalie.State
                if s2 != SubmissiveGoalie.State.clear
        ]:
            self.add_transition(
                state, SubmissiveGoalie.State.clear,
                lambda: evaluation.ball.is_in_our_goalie_zone() and
                not evaluation.ball.is_moving_towards_our_goal() and main.ball(
                ).vel.mag() < 0.4 and evaluation.ball.opponent_with_ball() is
                None, "ball in our goalie box, but not headed toward goal")

        for state in non_block_states:
            self.add_transition(
                state, SubmissiveGoalie.State.block,
                lambda: not evaluation.ball.is_in_our_goalie_zone(
                ) and not evaluation.ball.is_moving_towards_our_goal(),
                'ball not in goal or moving towards it')

        self.block_line = None
        self._move_target = robocup.Point(0, 0)

    # the line we expect a threat to shoot from
    # sits on the intersection of this line and the goalie segment
    @property
    def block_line(self):
        return self._block_line

    @block_line.setter
    def block_line(self, value):
        self._block_line = value

        if self.block_line == None:
            self._move_target = SubmissiveGoalie.RobotSegment.center()
        else:
            self._move_target = self.block_line.line_intersection(
                SubmissiveGoalie.RobotSegment)

        self._move_target.x = min(
            max(self._move_target.x, -SubmissiveGoalie.MaxX),
            SubmissiveGoalie.MaxX)

    # The point we'll be going to in order to block the given block_line
    @property
    def move_target(self):
        return self._move_target

    # note that execute_running() gets called BEFORE any of the execute_SUBSTATE methods gets called
    def execute_running(self):
        self.robot.face(main.ball().pos)

    def on_enter_clear(self):
        # FIXME: what we really want is a less-precise LineKick
        #           this will require a Capture behavior that doesn't wait for the ball to stop
        kick = skills.pivot_kick.PivotKick()

        # TODO: the below dribble speed is best for a 2011 bot
        # kick.dribble_speed = constants.Robot.Dribbler.MaxPower / 3.5

        # we use low error thresholds here
        # the goalie isn't trying to make a shot, he just wants get the ball the **** out of there
        kick.aim_params['error_threshold'] = 1.0
        kick.aim_params['max_steady_ang_vel'] = 12

        # chip
        kick.chip_power = constants.Robot.Chipper.MaxPower
        kick.use_chipper = True

        kick.target = robocup.Segment(
            robocup.Point(-constants.Field.Width / 2, constants.Field.Length),
            robocup.Point(constants.Field.Width / 2, constants.Field.Length))

        # FIXME: if the goalie has a fault, resort to bump

        self.add_subbehavior(kick, 'kick-clear', required=True)

    def on_exit_clear(self):
        self.remove_subbehavior('kick-clear')

    def on_enter_intercept(self):
        i = skills.intercept.Intercept()
        i.shape_constraint = SubmissiveGoalie.RobotSegment
        self.add_subbehavior(i, 'intercept', required=True)

    def on_exit_intercept(self):
        self.remove_subbehavior('intercept')

    def on_enter_block(self):
        move = skills.move.Move()
        self.add_subbehavior(move, 'move', required=True)

    def execute_block(self):
        move = self.subbehavior_with_name('move')
        move.pos = self.move_target

    def on_exit_block(self):
        self.remove_subbehavior('move')

    def role_requirements(self):
        reqs = super().role_requirements()

        for req in role_assignment.iterate_role_requirements_tree_leaves(reqs):
            req.required_shell_id = self.shell_id
        return reqs

    @property
    def shell_id(self):
        return self._shell_id

    @shell_id.setter
    def shell_id(self, value):
        self._shell_id = value
예제 #12
0
class Field:
    Length = 9.00
    Width = 6.00
    Border = 0.70

    LineWidth = 0.01

    GoalWidth = 1.000
    GoalDepth = 0.180
    GoalHeight = 0.160

    # Distance of the penalty marker from the goal line
    PenaltyDist = 1.0
    PenaltyDiam = 0.010

    # Radius of the goal arcs
    ArcRadius = 1.0

    # diameter of the center circle
    CenterRadius = 0.5
    CenterDiameter = 1.0

    # flat area for defense markings
    GoalFlat = 0.5

    FloorLength = Length + 2.0 * Border
    FloorWidth = Width + 2.0 * Border

    CenterPoint = robocup.Point(0.0, Length / 2.0)

    OurGoalZoneShape = robocup.CompositeShape()
    OurGoalZoneShape.add_shape(
        robocup.Circle(robocup.Point(-GoalFlat / 2.0, 0), ArcRadius))
    OurGoalZoneShape.add_shape(
        robocup.Circle(robocup.Point(GoalFlat / 2.0, 0), ArcRadius))
    OurGoalZoneShape.add_shape(
        robocup.Rect(robocup.Point(-GoalFlat / 2.0, ArcRadius),
                     robocup.Point(GoalFlat / 2.0, 0)))

    TheirGoalShape = robocup.CompositeShape()
    TheirGoalShape.add_shape(
        robocup.Circle(robocup.Point(-GoalFlat / 2.0, Length), ArcRadius))
    TheirGoalShape.add_shape(
        robocup.Circle(robocup.Point(GoalFlat / 2.0, Length), ArcRadius))
    TheirGoalShape.add_shape(
        robocup.Rect(robocup.Point(-GoalFlat / 2.0, Length),
                     robocup.Point(GoalFlat / 2.0, Length - ArcRadius)))

    FieldBorders = [
        robocup.Line(robocup.Point(-Width / 2.0, 0),
                     robocup.Point(-Width / 2.0, Length)),
        robocup.Line(robocup.Point(-Width / 2.0, Length),
                     robocup.Point(Width / 2.0, Length)),
        robocup.Line(robocup.Point(Width / 2.0, Length),
                     robocup.Point(Width / 2.0, 0)),
        robocup.Line(robocup.Point(Width / 2.0, 0),
                     robocup.Point(-Width / 2.0, 0))
    ]

    FieldRect = robocup.Rect(robocup.Point(-Width / 2.0, 0),
                             robocup.Point(Width / 2.0, Length))

    TheirGoalSegment = robocup.Segment(robocup.Point(GoalWidth / 2.0, Length),
                                       robocup.Point(-GoalWidth / 2.0, Length))
    OurGoalSegment = robocup.Segment(robocup.Point(GoalWidth / 2.0, 0),
                                     robocup.Point(-GoalWidth / 2.0, 0))

    TheirHalf = robocup.Rect(robocup.Point(-Width / 2, Length),
                             robocup.Point(Width / 2, Length / 2))
    OurHalf = robocup.Rect(robocup.Point(-Width / 2, 0),
                           robocup.Point(Width / 2, Length / 2))
예제 #13
0
def setFieldConstantsFromField_Dimensions(value):
    Field.Length = value.Length()
    Field.Width = value.Width()
    Field.Border = value.Border()
    Field.LineWidth = value.LineWidth()
    Field.GoalWidth = value.GoalWidth()
    Field.GoalDepth = value.GoalDepth()
    Field.GoalHeight = value.GoalHeight()
    Field.PenaltyDist = value.PenaltyDist()
    Field.PenaltyDiam = value.PenaltyDiam()
    Field.ArcRadius = value.ArcRadius()
    Field.CenterRadius = value.CenterRadius()
    Field.CenterDiameter = value.CenterDiameter()
    Field.GoalFlat = value.GoalFlat()
    Field.FloorLength = value.FloorLength()
    Field.FloorWidth = value.FloorWidth()

    Field.CenterPoint = robocup.Point(0.0, Field.Length / 2.0)

    Field.OurGoalZoneShape = robocup.CompositeShape()
    Field.OurGoalZoneShape.add_shape(
        robocup.Circle(robocup.Point(-Field.GoalFlat / 2.0, 0),
                       Field.ArcRadius))
    Field.OurGoalZoneShape.add_shape(
        robocup.Circle(robocup.Point(Field.GoalFlat / 2.0, 0),
                       Field.ArcRadius))
    Field.OurGoalZoneShape.add_shape(
        robocup.Rect(robocup.Point(-Field.GoalFlat / 2.0, Field.ArcRadius),
                     robocup.Point(Field.GoalFlat / 2.0, 0)))

    Field.TheirGoalShape = robocup.CompositeShape()
    Field.TheirGoalShape.add_shape(
        robocup.Circle(robocup.Point(-Field.GoalFlat / 2.0, Field.Length),
                       Field.ArcRadius))
    Field.TheirGoalShape.add_shape(
        robocup.Circle(robocup.Point(Field.GoalFlat / 2.0, Field.Length),
                       Field.ArcRadius))
    Field.TheirGoalShape.add_shape(
        robocup.Rect(
            robocup.Point(-Field.GoalFlat / 2.0, Field.Length),
            robocup.Point(Field.GoalFlat / 2.0,
                          Field.Length - Field.ArcRadius)))

    Field.TheirGoalSegment = robocup.Segment(
        robocup.Point(Field.GoalWidth / 2.0, Field.Length),
        robocup.Point(-Field.GoalWidth / 2.0, Field.Length))
    Field.OurGoalSegment = robocup.Segment(
        robocup.Point(Field.GoalWidth / 2.0, 0),
        robocup.Point(-Field.GoalWidth / 2.0, 0))

    Field.TheirHalf = robocup.Rect(
        robocup.Point(-Field.Width / 2, Field.Length),
        robocup.Point(Field.Width / 2, Field.Length / 2))
    Field.OurHalf = robocup.Rect(
        robocup.Point(-Field.Width / 2, 0),
        robocup.Point(Field.Width / 2, Field.Length / 2))

    Field.FieldBorders = [
        robocup.Line(robocup.Point(-Width / 2.0, 0),
                     robocup.Point(-Width / 2.0, Length)),
        robocup.Line(robocup.Point(-Width / 2.0, Length),
                     robocup.Point(Width / 2.0, Length)),
        robocup.Line(robocup.Point(Width / 2.0, Length),
                     robocup.Point(Width / 2.0, 0)),
        robocup.Line(robocup.Point(Width / 2.0, 0),
                     robocup.Point(-Width / 2.0, 0))
    ]

    Field.FieldRect = robocup.Rect(robocup.Point(-Width / 2.0, 0),
                                   robocup.Point(Width / 2.0, Length))
예제 #14
0
    def set_defender_block_lines(self, threats_to_block, assigned_handlers):
        goalie = self.subbehavior_with_name('goalie')
        defender1 = self.subbehavior_with_name('defender1')
        defender2 = self.subbehavior_with_name('defender2')

        # Check keep defenders from occupying the same spot
        # it will break if you change this
        handlers = [goalie, defender1, defender2]

        # For each threat
        for threat_idx in range(len(threats_to_block)):
            # Get the threat pos and score
            threat = threats_to_block[threat_idx]
            # Grab the list of handlers assigned to this threat
            assigned_handler = assigned_handlers[threat_idx]

            # Exclude any robots we are about to assign to find the threats best shot
            self.kick_eval.excluded_robots.clear()
            for handler in handlers:
                self.kick_eval.add_excluded_robot(handler.robot)

            # Add opp robot into exclude list, assuming it is not a ball
            if (threat[2] is not None):
                self.kick_eval.add_excluded_robot(threat[2])

            # If nobody is assigned, move to next one
            if len(assigned_handler) == 0:
                continue

            # Put goalie in the middle if possible
            if len(assigned_handler) > 1:
                if goalie in assigned_handler:
                    idx = assigned_handler.index(goalie)

                    if idx != 1:
                        del assigned_handler[idx]
                        assigned_handler.insert(1, goalie)

            # Get best shot from that threat postiion
            point, shot_chance = self.kick_eval.eval_pt_to_our_goal(threat[0])
            shot_line = robocup.Line(threat[0], point)

            # find the angular width that each defender can block.  We then space these out accordingly
            angle_widths = []
            for handler in assigned_handler:
                dist_from_threat = handler.robot.pos.dist_to(threat[0])
                w = min(
                    2.0 * math.atan2(constants.Robot.Radius, dist_from_threat),
                    0.15)
                angle_widths.append(w)

            # start on one edge of our available angle coverage and work counter-clockwise,
            # assigning block lines to the bots as we go
            spacing = 0.01 if len(
                assigned_handler
            ) < 3 else 0.0  # spacing between each bot in radians
            total_angle_coverage = sum(angle_widths) + (len(angle_widths) -
                                                        1) * spacing
            start_vec = shot_line.delta().normalized()
            start_vec.rotate(robocup.Point(0, 0), -total_angle_coverage / 2.0)
            for i in range(len(angle_widths)):
                handler = assigned_handler[i]
                w = angle_widths[i]
                start_vec.rotate(robocup.Point(0, 0), w / 2.0)
                handler.block_line = robocup.Line(threat[0],
                                                  threat[0] + start_vec * 10)
                start_vec.rotate(robocup.Point(0, 0), w / 2.0 + spacing)

            # Draw all the debug stuff
            if self.debug:
                main.debug_drawer().draw_line(shot_line, constants.Colors.Red,
                                              "Defense-Shot Line")
                main.debug_drawer().draw_text(
                    "Shot: " + str(int(shot_chance * 100.0)), threat[0],
                    constants.Colors.White, "Defense-Shot Percent")

                # Other threats besides ball
                if threat_idx > 0:
                    pass_line = robocup.Segment(main.ball().pos, threat[0])
                    main.debug_drawer().draw_line(pass_line,
                                                  constants.Colors.Red,
                                                  "Defense-Pass Line")

            # keep defenders from occupying the same spot
            # only matters if there are 2 defenders (and the goalie)
            if len(handlers) == 3:
                handler1 = handlers[1]
                handler2 = handlers[2]

                #vector between the 2 points
                overlap = handler2.move_target - handler1.move_target

                #if the robots overlap
                if overlap.mag() < (2 * constants.Robot.Radius) + .005:
                    #move the robots away from each other
                    overlap = overlap - (overlap.normalized() * 1.8 *
                                         constants.Robot.Radius)

                    handler1._move_target += overlap
                    handler2._move_target -= overlap
예제 #15
0
    def create_lineup(self):
        xsize = constants.Field.Width / 2 - .5

        return robocup.Segment(robocup.Point(xsize, .25),
                               robocup.Point(xsize, 1.5))