Ejemplo n.º 1
0
def shot_valid(agent, shot, threshold=45, target=None):
    # Returns True if the ball is still where the shot anticipates it to be
    if target is None:
        target = shot.ball_location

    # First finds the two closest slices in the ball prediction to shot's intercept_time
    # threshold controls the tolerance we allow the ball to be off by
    slices = agent.predictions['ball_struct'].slices
    soonest = 0
    latest = len(slices) - 1
    while len(slices[soonest:latest + 1]) > 2:
        midpoint = (soonest + latest) // 2
        if slices[midpoint].game_seconds > shot.intercept_time:
            latest = midpoint
        else:
            soonest = midpoint
    # preparing to interpolate between the selected slices
    dt = slices[latest].game_seconds - slices[soonest].game_seconds
    time_from_soonest = shot.intercept_time - slices[soonest].game_seconds
    soonest = (slices[soonest].physics.location.x,
               slices[soonest].physics.location.y,
               slices[soonest].physics.location.z)
    slopes = (Vector(
        slices[latest].physics.location.x, slices[latest].physics.location.y,
        slices[latest].physics.location.z) - Vector(*soonest)) * (1 / dt)
    # Determining exactly where the ball will be at the given shot's intercept_time
    predicted_ball_location = Vector(*soonest) + (slopes * time_from_soonest)
    # Comparing predicted location with where the shot expects the ball to be
    return target.dist(predicted_ball_location) < threshold
Ejemplo n.º 2
0
    def handle_panic(self, far_panic=5100, close_panic=1000):
        if self.ball_to_goal < far_panic or self.predictions['own_goal']:
            for d_shots in self.defensive_shots:
                # for d_shot in d_shots:
                self.line(*d_shots, self.renderer.team_color(alt_color=True))

            if not self.shooting:
                self.panic = True

                for shot in self.defensive_shots:
                    if self.smart_shot(shot, cap=4):
                        return

                if self.ball_to_goal < close_panic:
                    if not self.smart_shot((self.friend_goal.right_post,
                                            self.friend_goal.left_post),
                                           weight=0,
                                           cap=2):
                        if abs(self.me.location.y) > abs(self.ball.location.y):
                            self.is_clear()
                            self.push(short_shot(Vector(z=320)))
                        elif self.is_clear():
                            team = -1 if self.team == 0 else 1
                            self.push(
                                goto(
                                    Vector(y=self.ball.location.y +
                                           (team * 200))))
        else:
            self.panic = False
Ejemplo n.º 3
0
def backsolve(target, car, time, gravity):
    # Finds the acceleration required for a car to reach a target in a specific amount of time
    d = target - car.location
    dvx = ((d.x / time) - car.velocity.x) / time
    dvy = ((d.y / time) - car.velocity.y) / time
    dvz = (((d.z / time) - car.velocity.z) / time) + (gravity * -1 * time)
    return Vector(dvx, dvy, dvz)
Ejemplo n.º 4
0
    def backcheck(self, simple=False):
        if self.is_clear():
            self_from_goal = self.predictions['self_from_goal']
            if self_from_goal > 500:

                if self.playstyle != self.playstyles.Defensive and not simple and (
                    (self.team == 0 and self.ball.location.y > 2048) or
                    (self.team == 1 and self.ball.location.y < -2048)):
                    bc_x = 0
                    bc_y = 0
                    ball_loc = self.ball.location.y * side(not self.team)

                    if ball_loc > 2560 * side(not self.team):
                        if self.ball.location.x > 2048:
                            bc_x = 2048
                        elif self.ball.location.x < -2048:
                            bc_x = -2048

                    if len(self.predictions['teammates_from_goal']
                           ) > 0 and max(
                               self.predictions['teammates_from_goal']
                           ) is self_from_goal:
                        bc_y = max(1024, ball_loc - 1000) * side(not self.team)

                    self.push(goto(Vector(bc_x, bc_y, 17), self.ball.location))
                else:
                    self.push(goto(self.friend_goal.location))

                return True

            return False

        return True
Ejemplo n.º 5
0
def post_correction(ball_location, left_target, right_target):
    # this function returns target locations that are corrected to account for the ball's radius
    # If the left and right post swap sides, a goal cannot be scored
    # We purposly make this a bit larger so that our shots have a higher chance of success
    ball_radius = 120
    goal_line_perp = (right_target - left_target).cross(Vector(z=1))
    left = left_target + (
        (left_target - ball_location).normalize().cross(Vector(z=-1)) *
        ball_radius)
    right = right_target + (
        (right_target - ball_location).normalize().cross(Vector(z=1)) *
        ball_radius)
    left = left_target if (left -
                           left_target).dot(goal_line_perp) > 0 else left
    right = right_target if (right -
                             right_target).dot(goal_line_perp) > 0 else right
    swapped = True if (left - ball_location).normalize().cross(Vector(
        z=1)).dot((right - ball_location).normalize()) > -0.1 else False
    return left, right, swapped
Ejemplo n.º 6
0
def find_slope(shot_vector, car_to_target):
    # Finds the slope of your car's position relative to the shot vector (shot vector is y axis)
    # 10 = you are on the axis and the ball is between you and the direction to shoot in
    # -10 = you are on the wrong side
    # 1.0 = you're about 45 degrees offcenter
    d = shot_vector.dot(car_to_target)
    e = abs(shot_vector.cross(Vector(z=1)).dot(car_to_target))
    try:
        f = d / e
    except ZeroDivisionError:
        return 10 * sign(d)
    return cap(f, -3, 3)
Ejemplo n.º 7
0
def in_field(point, radius):
    # determines if a point is inside the standard soccer field
    point = Vector(abs(point.x), abs(point.y), abs(point.z))
    if point.x > 4080 - radius:
        return False
    elif point.y > 5900 - radius:
        return False
    elif point.x > 880 - radius and point.y > 5105 - radius:
        return False
    elif point.x > 2650 and point.y > -point.x + 8025 - radius:
        return False
    return True
Ejemplo n.º 8
0
def defaultPD(agent, local_target, direction=1.0):
    # points the car towards a given local target.
    # Direction can be changed to allow the car to steer towards a target while driving backwards
    local_target *= direction
    up = agent.me.local(Vector(z=1))  # where "up" is in local coordinates
    target_angles = (
        math.atan2(local_target.z,
                   local_target.x),  # angle required to pitch towards target
        math.atan2(local_target.y,
                   local_target.x),  # angle required to yaw towards target
        math.atan2(up.y, up.z)  # angle required to roll upright
    )
    # Once we have the angles we need to rotate, we feed them into PD loops to determing the controller inputs
    agent.controller.steer = steerPD(target_angles[1], 0) * direction
    agent.controller.pitch = steerPD(target_angles[0],
                                     agent.me.angular_velocity.y / 4)
    agent.controller.yaw = steerPD(target_angles[1],
                                   -agent.me.angular_velocity.z / 4)
    agent.controller.roll = steerPD(target_angles[2],
                                    agent.me.angular_velocity.x / 2)
    # Returns the angles, which can be useful for other purposes
    return target_angles