Ejemplo n.º 1
0
class CollectBoost(BaseAction):
    action = None

    def get_output(self, info: Game) -> SimpleControllerState:
        car = info.my_car
        if not self.action:
            self.action = Drive(car)

        boost_pad = closest_available_boost(car.location, info.pads)

        if boost_pad is None:
            # All boost pads are inactive.
            return self.controls

        self.action.target = boost_pad.location

        self.action.step(info.time_delta)
        self.controls = self.action.controls

        return self.controls

    def get_possible(self, info: Game):
        return True

    def update_status(self, info: Game):
        if info.my_car.boost == 100:
            self.finished = True
Ejemplo n.º 2
0
    def __init__(self, car: Car, info: Game):
        self.target: vec3 = None
        self.car: Car = car
        self.info = info

        self.hover = Hover(car)
        self.drive = Drive(car)
        
        self.controls: Input = Input()

        self.__time_spent_on_ground = 0.0
Ejemplo n.º 3
0
class Kickoff:
    def __init__(self, car: Car, info: Game):
        self.car: Car = car
        self.info: Game = info
        self.controls = Input()
        self.drive = Drive(car)

    def step(self, dt):
        self.drive.target = self.info.ball.position
        self.drive.speed = 1500
        self.drive.step(self.info.time_delta)
        self.controls = self.drive.controls
Ejemplo n.º 4
0
    def __init__(self, name, team, index):
        super().__init__(name, team, index)
        Game.set_mode("soccar")
        self.game = Game(index, team)
        self.name = name
        self.controls = SimpleControllerState()
        self.timer = 0.0

        self.drive = Drive(self.game.my_car)
        self.dodge = None
        self.turn = None
        self.state = State.RESET
Ejemplo n.º 5
0
    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:

        self.game.read_game_information(packet, self.get_rigid_body_tick(),
                                        self.get_field_info())
        self.controls = SimpleControllerState()

        next_state = self.state

        if self.state == State.RESET:
            self.timer = 0.0
            self.set_gamestate_straight_moving()
            # self.set_gamestate_angled_stationary()
            # self.set_gamestate_straight_moving_towards()
            next_state = State.WAIT

        if self.state == State.WAIT:

            if self.timer > 0.2:
                next_state = State.INITIALIZE

        if self.state == State.INITIALIZE:
            self.drive = Drive(self.game.my_car)
            self.drive.target, self.drive.speed = self.game.ball.location, 2300
            next_state = State.DRIVING

        if self.state == State.DRIVING:
            self.drive.target = self.game.ball.location
            self.drive.step(self.game.time_delta)
            self.controls = self.drive.controls
            can_dodge, simulated_duration, simulated_target = self.simulate()
            if can_dodge:
                self.dodge = Dodge(self.game.my_car)
                self.turn = AerialTurn(self.game.my_car)
                print("============")
                print(simulated_duration)
                self.dodge.duration = simulated_duration - 0.1
                self.dodge.target = simulated_target
                self.timer = 0
                next_state = State.DODGING

        if self.state == State.DODGING:
            self.dodge.step(self.game.time_delta)
            self.controls = self.dodge.controls
            if self.game.time == packet.game_ball.latest_touch.time_seconds:
                print(self.timer)
            if self.dodge.finished and self.game.my_car.on_ground:
                next_state = State.RESET

        self.timer += self.game.time_delta
        self.state = next_state

        return self.controls
Ejemplo n.º 6
0
    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:
        self.game.read_game_information(packet, self.get_rigid_body_tick(),
                                        self.get_field_info())

        if not self.action:
            self.action = Drive(self.game.my_car)
            self.action.speed = 1400

        self.action.target = self.game.ball.location
        self.action.step(self.game.time_delta)

        self.controls = self.action.controls

        return self.controls
Ejemplo n.º 7
0
def estimate_time(car: Car, target, dd=1) -> float:
    turning_radius = 1 / Drive.max_turning_curvature(norm(car.velocity) + 500)
    turning = angle_between(car.forward() * dd, direction(
        car, target)) * turning_radius / 1800
    if turning < 0.5: turning = 0

    dist = ground_distance(car, target) - 200
    if dist < 0: return turning
    speed = dot(car.velocity, car.forward())

    time = 0
    result = None
    if car.boost > 0 and dd > 0:
        boost_time = car.boost / 33.33
        result = BOOST.simulate_until_limit(speed,
                                            distance_limit=dist,
                                            time_limit=boost_time)
        dist -= result.distance_traveled
        time += result.time_passed
        speed = result.speed_reached

    if dist > 0 and speed < 1410:
        result = THROTTLE.simulate_until_limit(speed, distance_limit=dist)
        dist -= result.distance_traveled
        time += result.time_passed
        speed = result.speed_reached

    if result is None or not result.distance_limit_reached:
        time += dist / speed

    return time * 1.05 + turning
Ejemplo n.º 8
0
def set_steer(agent):
    if agent.game.my_car.on_ground:
        agent.step = Step.Steer
        target = agent.game.ball.location
        agent.drive = Drive(agent.game.my_car)
        agent.drive.target = target
        agent.drive.speed = 2400
Ejemplo n.º 9
0
    def get_output(self, info: Game) -> SimpleControllerState:
        car = info.my_car
        if not self.action:
            self.action = Drive(car)

        boost_pad = closest_available_boost(car.location, info.pads)

        if boost_pad is None:
            # All boost pads are inactive.
            return self.controls

        self.action.target = boost_pad.location

        self.action.step(info.time_delta)
        self.controls = self.action.controls

        return self.controls
Ejemplo n.º 10
0
class Derevo(BaseAgent):
    """Main bot class"""
    def __init__(self, name, team, index):
        """Initializing all parameters of the bot"""
        super().__init__(name, team, index)
        Game.set_mode("soccar")
        self.game = Game(index, team)
        self.name = name
        self.team = team
        self.index = index
        self.drive = None
        self.dodge = None
        self.controls = SimpleControllerState()
        self.kickoff = False
        self.prev_kickoff = False
        self.kickoffStart = None
        self.step = None

    def initialize_agent(self):
        """Initializing all parameters which require the field info"""
        init_boostpads(self)
        self.drive = Drive(self.game.my_car)
        self.dodge = Dodge(self.game.my_car)

    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:
        """The main method which receives the packets and outputs the controls"""
        self.game.read_game_information(packet, self.get_rigid_body_tick(),
                                        self.get_field_info())
        update_boostpads(self, packet)
        self.prev_kickoff = self.kickoff
        self.kickoff = packet.game_info.is_kickoff_pause and norm(
            vec2(self.game.ball.location - vec3(0, 0, 0))) < 100
        if self.kickoff and not self.prev_kickoff:
            init_kickoff(self)
            self.prev_kickoff = True
        elif self.kickoff or self.step is Step.Dodge_2:
            kick_off(self)
        else:
            self.drive.target = self.game.ball.location
            self.drive.speed = 1410
            self.drive.step(self.game.time_delta)
            self.controls = self.drive.controls
        if not packet.game_info.is_round_active:
            self.controls.steer = 0
        return self.controls
Ejemplo n.º 11
0
 def __init__(self, car):
     self.car = car
     self.target = vec3(0, 0, 0)
     self.speed = 2300
     self.controls = SimpleControllerState()
     self.finished = False
     self.rlu_drive = RLUDrive(self.car)
     self.update_rlu_drive()
     self.power_turn = True  # Handbrake while reversing to turn around quickly
Ejemplo n.º 12
0
class Agent(BaseAgent):
    def __init__(self, name, team, index):
        self.game = Game(index, team)
        self.controls = SimpleControllerState()
        self.action = None

    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:
        self.game.read_game_information(packet, self.get_rigid_body_tick(),
                                        self.get_field_info())

        if not self.action:
            self.action = Drive(self.game.my_car)
            self.action.speed = 1400

        self.action.target = self.game.ball.location
        self.action.step(self.game.time_delta)

        self.controls = self.action.controls

        return self.controls
Ejemplo n.º 13
0
class CustomDrive:

    def __init__(self, car):
        self.car = car
        self.target = vec3(0, 0, 0)
        self.speed = 2300
        self.controls = SimpleControllerState()
        self.finished = False
        self.rlu_drive = RLUDrive(self.car)
        self.update_rlu_drive()
        self.power_turn = True  # Handbrake while reversing to turn around quickly

    def step(self, dt: float):
        self.update_rlu_drive()
        self.rlu_drive.step(dt)
        self.finished = self.rlu_drive.finished

        car_to_target = (self.target - self.car.position)
        local_target = dot(car_to_target, self.car.orientation)
        angle = atan2(local_target[1], local_target[0])

        self.controls = self.rlu_drive.controls
        reverse = (cos(angle) < 0)
        if reverse:
            angle = -invert_angle(angle)
            if self.power_turn:
                self.controls.throttle = (-self.controls.throttle - 1) / 2
                angle *= -1
            else:
                self.controls.throttle = -1
            self.controls.steer = cap(angle * 3, -1, 1)
            self.controls.boost = False
        self.controls.handbrake = (abs(angle) > radians(70))

    def update_rlu_drive(self):
        self.target = self.target
        self.rlu_drive.target = self.target
        self.rlu_drive.speed = self.speed
Ejemplo n.º 14
0
 def determine_max_speed(self, local_target):
     low = 100
     high = 2200
     if self.kickoff:
         return high
     for i in range(5):
         mid = (low + high) / 2
         radius = (1 / RLUDrive.max_turning_curvature(mid))
         local_circle = vec3(0, copysign(radius, local_target[1]), 0)
         dist = norm(local_circle - xy(local_target))
         if dist < radius:
             high = mid
         else:
             low = mid
     return high
Ejemplo n.º 15
0
class GetToAirPoint:
    """Drive towards the point, jump and start hovering when near enough."""

    def __init__(self, car: Car, info: Game):
        self.target: vec3 = None
        self.car: Car = car
        self.info = info

        self.hover = Hover(car)
        self.drive = Drive(car)
        
        self.controls: Input = Input()

        self.__time_spent_on_ground = 0.0

    def step(self, dt):
        if self.car.on_ground and norm(self.car.position + self.car.velocity - xy(self.target)) > 2500:
            self.drive.speed = 1000
            self.drive.target = self.target
            self.drive.step(dt)
            self.controls = self.drive.controls
            self.controls.handbrake = angle_between(self.car.forward(), self.target - self.car.position) > 1.2
            return

        self.hover.target = self.target
        self.hover.up = normalize(self.car.position * -1)
        self.hover.step(dt)
        self.controls = self.hover.controls

        self.controls.throttle = not self.car.on_ground
        self.controls.jump = (self.car.position[2] < 30 or self.car.on_ground) and self.__time_spent_on_ground > 0.1

        if self.info.round_active:
            self.__time_spent_on_ground += dt
        if not self.car.on_ground:
            self.__time_spent_on_ground = 0.0
Ejemplo n.º 16
0
    def align(car: Car, target: vec3, direction: vec3):

        turnAngleAmount = math.acos(dot(car.forward(), direction))
        rotateToZeroAngle = -atan2(direction)
        posOffset = rotate2(target - car.position, rotateToZeroAngle)

        towardsZeroVector = rotate2(car.forward(), rotateToZeroAngle)
        turnDirection = math.copysign(1, -towardsZeroVector[1])

        turnRadius = 1 / RLUDrive.max_turning_curvature(norm(car.velocity))

        ANGLETERM = 10
        ANGULARTERM = -0.3
        CORRECTIONTERM = 1 / 40
        angleP = turnDirection * min(2, ANGLETERM * turnAngleAmount)
        angleD = ANGULARTERM * car.angular_velocity[2]

        finalOffset = posOffset[1] + turnDirection * turnRadius / .85 * (
            1 - math.cos(turnAngleAmount))
        offsetCorrection = CORRECTIONTERM * finalOffset

        return min(1, max(-1, angleP + angleD + offsetCorrection))
Ejemplo n.º 17
0
def init_kickoff(agent):
    """"Method that initializes the kickoff"""
    if abs(agent.game.my_car.location[0]) < 250:
        pad = get_closest_small_pad(agent, vec3(0,
                                                sign(agent.team) * 4608, 18))
        target = vec3(pad.location[0], pad.location[1],
                      pad.location[2]) + sign(agent.team) * vec3(20, 0, 0)
        agent.kickoffStart = "Center"
    elif abs(agent.game.my_car.location[0]) < 1000:
        target = vec3(0.0,
                      sign(agent.team) * 2816.0,
                      70.0) + sign(agent.team) * vec3(0, 300, 0)
        agent.kickoffStart = "offCenter"
    else:
        target = agent.game.my_car.location + 300 * agent.game.my_car.forward()
        agent.kickoffStart = "Diagonal"
    agent.drive = Drive(agent.game.my_car)
    agent.drive.target = target
    agent.drive.speed = 2400
    agent.step = Step.Drive
    agent.drive.step(agent.game.time_delta)
    agent.controls = agent.drive.controls
Ejemplo n.º 18
0
 def initialize_agent(self):
     """Initializing all parameters which require the field info"""
     init_boostpads(self)
     self.drive = Drive(self.game.my_car)
     self.dodge = Dodge(self.game.my_car)
Ejemplo n.º 19
0
class MyAgent(BaseAgent):
    def __init__(self, name, team, index):
        super().__init__(name, team, index)
        Game.set_mode("soccar")
        self.game = Game(index, team)
        self.name = name
        self.controls = SimpleControllerState()
        self.timer = 0.0

        self.drive = Drive(self.game.my_car)
        self.dodge = None
        self.turn = None
        self.state = State.RESET

    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:

        # Update the game values and set the state
        self.game.read_game_information(packet, self.get_field_info())
        self.controls = SimpleControllerState()

        next_state = self.state

        # Reset everything
        if self.state == State.RESET:
            self.timer = 0.0
            # self.set_gamestate_straight_moving()
            # self.set_gamestate_straight_moving_towards()
            self.set_state_stationary_angled()
            # self.set_gamestate_angled_stationary()
            # self.set_state_stationary()
            next_state = State.WAIT

        # Wait so everything can settle in, mainly for ball prediction
        if self.state == State.WAIT:
            if self.timer > 0.2:
                next_state = State.INITIALIZE

        # Initialize the drive mechanic
        if self.state == State.INITIALIZE:
            self.drive = Drive(self.game.my_car)
            self.drive.target = self.game.ball.position
            self.drive.speed = 1400
            next_state = State.DRIVING

        # Start driving towards the target and check whether a dodge is possible, if so initialize the dodge
        if self.state == State.DRIVING:
            self.drive.target = self.game.ball.position
            self.drive.step(self.game.time_delta)
            self.controls = self.drive.controls
            a = time.time()
            target = self.game.my_car.position + 1000000 * (
                self.game.ball.position - self.game.my_car.position)
            can_dodge, simulated_duration, simulated_target = self.simulate()
            print(time.time() - a)
            if can_dodge:
                self.dodge = Dodge(self.game.my_car)
                self.turn = AerialTurn(self.game.my_car)
                self.dodge.duration = simulated_duration - 0.1
                self.dodge.target = simulated_target

                self.dodge.preorientation = look_at(simulated_target,
                                                    vec3(0, 0, 1))
                self.timer = 0
                next_state = State.DODGING

        # Perform the dodge
        if self.state == State.DODGING:
            self.dodge.step(self.game.time_delta)
            self.controls = self.dodge.controls

            T = self.dodge.duration - self.dodge.timer
            if T > 0:
                if self.dodge.timer < 0.2:
                    self.controls.boost = 1
                    # self.controls.pitch = 1
                else:
                    xf = self.game.my_car.position + 0.5 * T * T * vec3(
                        0, 0, -650) + T * self.game.my_car.velocity

                    delta_x = self.game.ball.position - xf
                    if angle_between(vec2(self.game.my_car.forward()),
                                     self.dodge.direction) < 0.3:
                        if norm(delta_x) > 50:
                            self.controls.boost = 1
                            self.controls.throttle = 0.0
                        else:
                            self.controls.boost = 0
                            self.controls.throttle = clip(
                                0.5 * (200 / 3) * T * T, 0.0, 1.0)
                    else:
                        self.controls.boost = 0
                        self.controls.throttle = 0.0
            else:
                self.controls.boost = 0

            # Great line
            # if self.game.time == packet.game_ball.latest_touch.time_seconds:
            #     print(self.game.my_car.position)
            if self.dodge.finished and self.game.my_car.on_ground:
                next_state = State.RESET

        self.timer += self.game.time_delta
        self.state = next_state

        return self.controls

    # The miraculous simulate function
    # TODO optimize heavily in case I actually need it
    # Option one: estimate the time for the current height and look at that ball prediction.
    # If its heigher use that unless it gets unreachable and else compare with the lower one.
    # If duration_estimate = 0.8 and the ball is moving up there is not sense in even simulating it.
    # Might even lower it since the higher the duration estimate the longer the simulation takes.
    def simulate(self, global_target=None):
        lol = 0
        # Initialize the ball prediction
        # Estimate the probable duration of the jump and round it down to the floor decimal
        ball_prediction = self.get_ball_prediction_struct()
        if self.game.my_car.boost < 6:
            duration_estimate = math.floor(
                get_time_at_height(self.game.ball.position[2]) * 10) / 10
        else:
            adjacent = norm(
                vec2(self.game.my_car.position - self.game.ball.position))
            opposite = (self.game.ball.position[2] -
                        self.game.my_car.position[2])
            theta = math.atan(opposite / adjacent)
            t = get_time_at_height_boost(self.game.ball.position[2], theta,
                                         self.game.my_car.boost)
            duration_estimate = (math.ceil(t * 10) / 10)
        # Loop for 6 frames meaning adding 0.1 to the estimated duration. Keeps the time constraint under 0.3s
        for i in range(6):
            # Copy the car object and reset the values for the hitbox
            car = Car(self.game.my_car)
            # Create a dodge object on the copied car object
            # Direction is from the ball to the enemy goal
            # Duration is estimated duration plus the time added by the for loop
            # preorientation is the rotation matrix from the ball to the goal
            # TODO make it work on both sides
            #  Test with preorientation. Currently it still picks a low duration at a later time meaning it
            #  wont do any of the preorientation.
            dodge = Dodge(car)
            prediction_slice = ball_prediction.slices[round(
                60 * (duration_estimate + i / 60))]
            physics = prediction_slice.physics
            ball_location = vec3(physics.location.x, physics.location.y,
                                 physics.location.z)
            # ball_location = vec3(0, ball_y, ball_z)
            dodge.duration = duration_estimate + i / 60
            if dodge.duration > 1.4:
                break

            if global_target is not None:
                dodge.direction = vec2(global_target - ball_location)
                target = vec3(vec2(global_target)) + vec3(
                    0, 0, jeroens_magic_number * ball_location[2])
                dodge.preorientation = look_at(target - ball_location,
                                               vec3(0, 0, 1))
            else:
                dodge.target = ball_location
                dodge.direction = vec2(ball_location) + vec2(ball_location -
                                                             car.position)
                dodge.preorientation = look_at(ball_location, vec3(0, 0, 1))
            # Loop from now till the end of the duration
            fps = 30
            for j in range(round(fps * dodge.duration)):
                lol = lol + 1
                # Get the ball prediction slice at this time and convert the location to RLU vec3
                prediction_slice = ball_prediction.slices[round(60 * j / fps)]
                physics = prediction_slice.physics
                ball_location = vec3(physics.location.x, physics.location.y,
                                     physics.location.z)
                dodge.step(1 / fps)

                T = dodge.duration - dodge.timer
                if T > 0:
                    if dodge.timer < 0.2:
                        dodge.controls.boost = 1
                        dodge.controls.pitch = 1
                    else:
                        xf = car.position + 0.5 * T * T * vec3(
                            0, 0, -650) + T * car.velocity

                        delta_x = ball_location - xf
                        if angle_between(vec2(car.forward()),
                                         dodge.direction) < 0.3:
                            if norm(delta_x) > 50:
                                dodge.controls.boost = 1
                                dodge.controls.throttle = 0.0
                            else:
                                dodge.controls.boost = 0
                                dodge.controls.throttle = clip(
                                    0.5 * (200 / 3) * T * T, 0.0, 1.0)
                        else:
                            dodge.controls.boost = 0
                            dodge.controls.throttle = 0.0
                else:
                    dodge.controls.boost = 0

                car.step(dodge.controls, 1 / fps)
                succesfull = self.dodge_succesfull(car, ball_location, dodge)
                if succesfull is not None:
                    if succesfull:
                        return True, j / fps, ball_location
                    else:
                        break
        return False, None, None

    def dodge_succesfull(self, car, ball_location, dodge):
        batmobile = obb()
        batmobile.half_width = vec3(64.4098892211914, 42.335182189941406,
                                    14.697200775146484)
        batmobile.center = car.position + dot(car.orientation,
                                              vec3(9.01, 0, 12.09))
        batmobile.orientation = car.orientation
        ball = sphere(ball_location, 93.15)
        b_local = dot(ball.center - batmobile.center, batmobile.orientation)

        closest_local = vec3(
            min(max(b_local[0], -batmobile.half_width[0]),
                batmobile.half_width[0]),
            min(max(b_local[1], -batmobile.half_width[1]),
                batmobile.half_width[1]),
            min(max(b_local[2], -batmobile.half_width[2]),
                batmobile.half_width[2]))

        hit_location = dot(batmobile.orientation,
                           closest_local) + batmobile.center
        if norm(hit_location - ball.center) > ball.radius:
            return None
        # if abs(ball_location[2] - hit_location[2]) < 25 and hit_location[2] < ball_location[2]:
        if abs(ball_location[2] - hit_location[2]) < 25:
            if closest_local[0] > 35 and -12 < closest_local[2] < 12:
                hit_check = True
            else:
                print("local: ", closest_local)
                hit_check = True
        else:
            hit_check = False
        # Seems to work without angle_check. No clue why though
        angle_car_simulation = angle_between(car.orientation,
                                             self.game.my_car.orientation)
        angle_simulation_target = angle_between(car.orientation,
                                                dodge.preorientation)
        angle_check = angle_simulation_target < angle_car_simulation or angle_simulation_target < 0.1
        return hit_check

    """" State setting methods for various situations"""

    def set_gamestate_straight_moving(self):
        # put the car in the middle of the field
        car_state = CarState(
            physics=Physics(location=Vector3(0, -1000, 18),
                            velocity=Vector3(0, 0, 0),
                            rotation=Rotator(0, math.pi / 2, 0),
                            angular_velocity=Vector3(0, 0, 0)))

        # put the ball in the middle of the field

        ball_state = BallState(
            physics=Physics(location=Vector3(0, 1500, 93),
                            velocity=Vector3(200, 650, 750),
                            rotation=Rotator(0, 0, 0),
                            angular_velocity=Vector3(0, 0, 0)))

        self.set_game_state(
            GameState(ball=ball_state, cars={self.game.id: car_state}))

    def set_gamestate_straight_moving_towards(self):
        # put the car in the middle of the field
        car_state = CarState(physics=Physics(
            location=Vector3(0, 0, 18),
            velocity=Vector3(0, 0, 0),
            rotation=Rotator(0, math.pi / 2, 0),
            angular_velocity=Vector3(0, 0, 0),
        ),
                             boost_amount=50)

        # put the ball in the middle of the field

        ball_state = BallState(physics=Physics(
            location=Vector3(0, 2500, 93),
            velocity=Vector3(0, -250, 500),
            rotation=Rotator(0, 0, 0),
            angular_velocity=Vector3(0, 0, 0),
        ))

        self.set_game_state(
            GameState(ball=ball_state, cars={self.game.id: car_state}))

    def set_gamestate_angled_stationary(self):
        # put the car in the middle of the field
        car_state = CarState(
            physics=Physics(location=Vector3(-1000, -2000, 18),
                            velocity=Vector3(0, 0, 0),
                            rotation=Rotator(0, math.pi / 8, 0),
                            angular_velocity=Vector3(0, 0, 0)))

        # put the ball in the middle of the field

        ball_state = BallState(
            physics=Physics(location=Vector3(0, 0, 600),
                            velocity=Vector3(0, 0, 1),
                            rotation=Rotator(0, 0, 0),
                            angular_velocity=Vector3(0, 0, 0)))

        self.set_game_state(
            GameState(ball=ball_state, cars={self.game.id: car_state}))

    def set_state_stationary(self):
        # put the car in the middle of the field
        car_state = CarState(physics=Physics(
            location=Vector3(0, -2500, 18),
            velocity=Vector3(0, 0, 0),
            rotation=Rotator(0, math.pi / 2, 0),
            angular_velocity=Vector3(0, 0, 0),
        ),
                             boost_amount=100)

        # put the ball in the middle of the field
        ball_state = BallState(physics=Physics(
            location=Vector3(0, ball_y, ball_z),
            velocity=Vector3(0, 0, 0),
            angular_velocity=Vector3(0, 0, 0),
        ))

        self.set_game_state(
            GameState(ball=ball_state, cars={self.game.id: car_state}))

    def set_state_stationary_angled(self):
        # put the car in the middle of the field
        car_state = CarState(physics=Physics(
            location=Vector3(0, -2500, 18),
            velocity=Vector3(0, 0, 0),
            rotation=Rotator(0, math.pi / 2, 0),
            angular_velocity=Vector3(0, 0, 0),
        ),
                             boost_amount=100)

        # put the ball in the middle of the field
        ball_state = BallState(physics=Physics(
            location=Vector3(1500, 0, 93),
            velocity=Vector3(0, 0, 750),
            angular_velocity=Vector3(0, 0, 0),
        ))

        self.set_game_state(
            GameState(ball=ball_state, cars={self.game.id: car_state}))
Ejemplo n.º 20
0
    def tick(self, packet: GameTickPacket) -> bool:
        #self.agent.renderer.begin_rendering()

        kickoff = packet.game_info.is_round_active and packet.game_info.is_kickoff_pause

        carAccelerations = []
        for i in range(packet.num_cars):
            car = packet.game_cars[i]
            velocity = vec3(car.physics.velocity.x, car.physics.velocity.y,
                            car.physics.velocity.z)
            carAccelerations.append((velocity - self.lastVelocities[i]) /
                                    self.agent.ticksThisPacket * 120)
            self.lastVelocities[i] = velocity

        # car info
        myCar = packet.game_cars[self.agent.index]
        carLocation = Vec3(myCar.physics.location)
        carVelocity = Vec3(myCar.physics.velocity)
        carSpeed = carVelocity.length()

        # ball info
        realBallLocation = ballLocation = Vec3(
            packet.game_ball.physics.location)
        ballVelocity = Vec3(packet.game_ball.physics.velocity)
        if ballLocation.z < 100:
            self.balanceTime = 0
            #return False
        action_display = f"Air time: {self.balanceTime}"
        self.balanceTime += 1

        # unstuck goal hack
        if abs(carLocation.y) > 5100:
            ballLocation.x = 0

        # target ball info
        #targetBallLocation, targetBallVelocity, targetAngle = getTargetBall(self.agent, packet, carLocation)

        teamDirection = 1 if packet.game_cars[
            self.agent.index].team == 0 else -1
        sidewaysDiff = abs(carLocation.x) - 893 + 100
        isInCorner = sidewaysDiff > 0
        if isInCorner:
            sidewaysDiff = max(
                0, sidewaysDiff + 0.4 * (carLocation.y * teamDirection -
                                         (5120 - 100)))
            inTriangleAmount = max(0, min(1, sidewaysDiff / 4500))
            scale = 0.55
        else:
            scale = 2
            inTriangleAmount = 0
        targetBallLocation = Vec3(0, (5120 + 100 - sidewaysDiff * scale) *
                                  teamDirection, 0)

        ## if teammate is closer to the ball, go to defend position.
        ballToCarAbsoluteLocation = (ballLocation - carLocation).flat()
        ballToCarDistance = ballToCarAbsoluteLocation.length()
        futurePositionScoreVector = ballLocation + 1 * ballVelocity - carLocation
        positionScore = Vec3(futurePositionScoreVector.x, futurePositionScoreVector.y * (1 if futurePositionScoreVector.y * (2*self.agent.team-1) < 0 else 3), 0).length()\
                      + Vec3(ballToCarAbsoluteLocation.x, ballToCarAbsoluteLocation.y * (1 if ballToCarAbsoluteLocation.y * (2*self.agent.team-1) < 0 else 3), 0).length()

        beAnnoying = False
        for carIndex in range(packet.num_cars):
            car = packet.game_cars[carIndex]
            if car.team == self.agent.team and carIndex != self.agent.index and not car.is_demolished:
                OtherCarToBall = ballLocation - Vec3(car.physics.location)
                OtherFutureCarToBall = ballLocation + 1 * ballVelocity - Vec3(
                    car.physics.location)
                otherPositionScore = Vec3(OtherCarToBall.x      , OtherCarToBall.y       * (1 if OtherCarToBall.y       * (2*self.agent.team-1) < 0 else 3), 0).length()\
                                   + Vec3(OtherFutureCarToBall.x, OtherFutureCarToBall.y * (1 if OtherFutureCarToBall.y * (2*self.agent.team-1) < 0 else 3), 0).length()

                # print(f"[{self.agent.index} {round(positionScore)}] {carIndex}: {round(otherPositionScore)}!")
                if otherPositionScore + math.copysign(
                        5, carIndex - self.agent.index) < positionScore:

                    # print(f"{self.agent.index} other one is closer!")

                    teamClosestDistance = math.inf
                    enemyClosestDistance = math.inf
                    for carIndex in range(packet.num_cars):
                        car = packet.game_cars[carIndex]
                        distance = (
                            ballLocation -
                            Vec3(car.physics.location)).flat().length()
                        if car.team == self.agent.team:
                            teamClosestDistance = min(teamClosestDistance,
                                                      distance)
                        else:
                            enemyClosestDistance = min(enemyClosestDistance,
                                                       distance)
                    teamHasBallControl = teamClosestDistance - 500 < enemyClosestDistance

                    targetScore = math.inf
                    target = None
                    for carIndex in range(packet.num_cars):
                        car = packet.game_cars[carIndex]
                        # print(f"[{self.agent.index} {self.agent.team}] {carIndex} {car.team}")
                        if car.team != self.agent.team:
                            score = (
                                ballLocation - Vec3(car.physics.location)
                            ).flat().length() + teamHasBallControl * (
                                Vec3(0, 5120 * (2 * car.team - 1), 0) -
                                Vec3(car.physics.location)).flat().length()
                            # print(f"[{self.agent.index}] considering car {carIndex}")
                            if score < targetScore:
                                targetScore = score
                                target = car

                    if target != None:

                        beAnnoying = True

                        huntLocation = Vec3(target.physics.location)
                        for _ in range(20):
                            time = min(
                                .6, 900 /
                                max(1,
                                    Vec3(target.physics.velocity).length()),
                                (carLocation - huntLocation).length() /
                                max(carSpeed, 1))
                            huntLocation = Vec3(
                                target.physics.location) + time * Vec3(
                                    target.physics.velocity)

                        ballLocation = huntLocation
                        ballVelocity = Vec3(0, 0,
                                            0)  #Vec3(target.physics.velocity)
                        ballToCarAbsoluteLocation = (ballLocation -
                                                     carLocation).flat()
                        ballToCarDistance = ballToCarAbsoluteLocation.length()

                    break

        ## if convenient, change ball location to nearby boost pad.
        fieldInfo = self.agent.get_field_info()
        carFutureLocation = carLocation + 0.2 * carVelocity
        ballToFutureCarAbsoluteLocation = (ballLocation -
                                           carFutureLocation).flat()
        ballToFutureCarDistance = ballToFutureCarAbsoluteLocation.length()
        goingForBoost = False
        if ballToCarDistance > 250 and myCar.boost < 88:
            convenientBoostPads = []
            costs = []
            for i in range(fieldInfo.num_boosts):
                if not packet.game_boosts[i].is_active:
                    continue
                boostPad = fieldInfo.boost_pads[i]
                boostLocation = Vec3(boostPad.location)

                maxOffset = (208 if boostPad.is_full_boost else 144) - 20
                orth = (boostLocation -
                        carLocation).orthogonalize(ballToCarAbsoluteLocation)
                boostLocation -= orth.normalized() * min(
                    orth.length(), maxOffset)

                carToBoostLength = (boostLocation - carFutureLocation).length()
                detourLength = (ballLocation -
                                boostLocation).length() + carToBoostLength
                cost = (detourLength - ballToFutureCarDistance) / (
                    1450 if boostPad.is_full_boost else 250)
                costs.append(cost)
                if cost < ((100 - myCar.boost) / 100)**1.5:
                    convenientBoostPads.append(
                        (i, carToBoostLength * cost, boostLocation))
                    #self.agent.renderer.draw_line_3d(boostLocation, boostLocation + Vec3(0, 0, 100), self.agent.renderer.pink())

            #print(round(min(costs), 1))

            if len(convenientBoostPads) > 0:
                convenientBoostPads.sort(key=lambda b: b[1], reverse=False)
                boostPad = fieldInfo.boost_pads[convenientBoostPads[0][0]]
                boostLocation = convenientBoostPads[0][2]
                #self.agent.renderer.draw_line_3d(boostLocation, boostLocation + Vec3(0, 0, 400), self.agent.renderer.pink())

                ballLocation = boostLocation
                ballVelocity = Vec3(0, 0, 0)

                ballToCarAbsoluteLocation = (ballLocation - carLocation).flat()
                ballToCarDistance = ballToCarAbsoluteLocation.length()
                goingForBoost = True

        ## time to next bounce
        if not goingForBoost:
            pass

        ## calculate angles
        ballDirection = math.atan2(ballVelocity.y, -ballVelocity.x)
        carDirection = -myCar.physics.rotation.yaw
        carToBallAngle = math.atan2(
            ballToCarAbsoluteLocation.y,
            -ballToCarAbsoluteLocation.x) - carDirection
        if abs(carToBallAngle) > math.pi:
            if carToBallAngle > 0:
                carToBallAngle -= 2 * math.pi
            else:
                carToBallAngle += 2 * math.pi
        ballToTargetAbsoluteLocation = (ballLocation -
                                        targetBallLocation).flat()
        carToTargetAngle = math.atan2(
            ballToTargetAbsoluteLocation.y,
            -ballToTargetAbsoluteLocation.x) - carDirection
        if abs(carToTargetAngle) > math.pi:
            if carToTargetAngle > 0:
                carToTargetAngle -= 2 * math.pi
            else:
                carToTargetAngle += 2 * math.pi
        carToTargetAbsoluteLocation = (carLocation - targetBallLocation).flat()

        ## separate into steering and throttle components
        ballToCarLocation = ballToCarAbsoluteLocation.rotate_2D(carDirection)
        ballToTargetLocation = ballToTargetAbsoluteLocation.rotate_2D(
            carDirection)
        carToTargetLocation = carToTargetAbsoluteLocation.rotate_2D(
            carDirection)

        ballToCarVelocity = (ballVelocity -
                             carVelocity).flat().rotate_2D(carDirection)
        #carToTargetVelocity = (carVelocity - targetBallVelocity).flat().rotate_2D(carDirection)

        maxSpeed = max(1410, min(2300,
                                 1410 + (2300 - 1410) / 33 * myCar.boost))
        carToMaxSpeed = carVelocity.flat().length() - maxSpeed
        desiredSpeed = 1200

        if ballToTargetLocation.y < 500:
            self.carToTargetIntegral += ballToTargetLocation
        else:
            self.carToTargetIntegral = Vec3()



        canYeet = myCar.has_wheel_contact \
                and (not goingForBoost) \
                and ballToCarLocation.length() < 275 \
                and ballLocation.z > 100 \
                and ballLocation.z < 275 \
                and packet.game_info.seconds_elapsed - packet.game_ball.latest_touch.time_seconds < 0.1
        teamDirection = 1 if packet.game_cars[
            self.agent.index].team == 0 else -1
        inCornerDegree = math.atan(
            (max(abs(carLocation.x), 893) - 893) /
            max(5120 - carLocation.y * teamDirection, 1))
        shouldYeet = ((ballLocation + 1 * ballVelocity).flat() * teamDirection - Vec3(0, 5120+100, 0)).length() < 1500 \
                and inCornerDegree < math.pi * 2 / 6 \
                and 4200 - abs(ballLocation.y) < 0.7 * abs(ballVelocity.y)

        #print(f"{canYeet}\t{shouldYeet}\t{round(4200 - abs(ballLocation.y))}\t{round(0.7 * abs(ballVelocity.y))}")
        #action_display = f"{round((ballLocation.flat() - Vec3(0, 5120+100 * teamDirection, 0)).length())}"
        carlocs = []
        if canYeet and shouldYeet:

            inComingCar = False
            for i in range(packet.num_cars):
                if i == self.agent.index:
                    continue
                car = packet.game_cars[i]
                if car.team == myCar.team or car.is_demolished:
                    continue
                #print(round(0.1 + norm(carAccelerations[i]) / RLUDrive.throttle_accel(Vec3(car.physics.velocity).length()), 2))
                for throttle in (
                        0,
                        min(
                            1, 0.1 + norm(carAccelerations[i]) /
                            RLUDrive.throttle_accel(
                                Vec3(car.physics.velocity).length()))):
                    carBoost = car.boost

                    attackerCarLocation = Vec3(car.physics.location)
                    # divide by 120, to go from per second to per frame
                    STEPSIZE = 120
                    gravity = packet.game_info.world_gravity_z / STEPSIZE**2
                    attackerCarVelocity = vec3(
                        car.physics.velocity.x, car.physics.velocity.y,
                        car.physics.velocity.z) / STEPSIZE
                    attackerCarAngular = axis_to_rotation(
                        vec3(car.physics.angular_velocity.x,
                             car.physics.angular_velocity.y,
                             car.physics.angular_velocity.z) / STEPSIZE)

                    ballV = ballVelocity / STEPSIZE

                    for j in range(round(STEPSIZE *
                                         0.7)):  # simulate 40 ticks forwards
                        attackerCarLocation += Vec3(attackerCarVelocity[0],
                                                    attackerCarVelocity[1],
                                                    attackerCarVelocity[2])
                        if car.has_wheel_contact:
                            attackerCarVelocity = dot(attackerCarAngular,
                                                      attackerCarVelocity)
                        attackerCarVelocity += vec3(0, 0, gravity)
                        if throttle == 0:
                            attackerCarVelocity -= vec3(
                                math.copysign(
                                    min(525 / STEPSIZE,
                                        abs(attackerCarVelocity[0])),
                                    attackerCarVelocity[0]), 0, 0)
                        else:
                            acceleration = (991.667 * (carBoost > 0) +
                                            RLUDrive.throttle_accel(
                                                norm(attackerCarVelocity)))
                            attackerCarVelocity += normalize(
                                attackerCarVelocity) * acceleration / STEPSIZE
                        if attackerCarLocation.z < ballLocation.z:
                            attackerCarLocation.z = ballLocation.z
                        carlocs.append(attackerCarLocation)
                        if (attackerCarLocation - ballLocation +
                                j * ballV).flat().length(
                                ) < 750:  # longest car has a diagonal of 157uu
                            inComingCar = True
                            break
                        #print(f"{j}\t{ (attackerCarLocation - ballLocation + j * ballV).flat().length()}")
                    if inComingCar:
                        break

                    carBoost -= 1 / 3 / STEPSIZE

                if inComingCar:

                    self.agent.stateMachine.changeStateMidTick(Yeet)
                    return inComingCar

        if kickoff and (carLocation - realBallLocation
                        ).length() < 800 and myCar.has_wheel_contact:
            self.agent.stateMachine.changeStateMidTick(Frontflip)
            return True

        ## STEERING
        steer = 0
        steerBias = 0
        # ball to car proportional
        #print(f"{round(min(15, max(-15, 0.02 * ballToCarLocation.y)), 2)}\t{round(0.003 * ballToCarVelocity.y, 2)}")
        steer += min(15, max(-15, 0.02 * ballToCarLocation.y))
        if not goingForBoost:
            # ball to car derivative
            steer += 0.005 * ballToCarVelocity.y
            #print(f"pos: {round(min(15, max(-15, 0.02 * ballToCarLocation.y)), 2)}\tvel: {round(0.009 * ballToCarVelocity.y,2)}")
            # ball to target proportional
            targetSteer = ballToTargetLocation.y
            #action_display = f"{round(carToTargetLocation.x)}"
            if carToTargetLocation.x > 300:
                targetSteer = math.copysign(100000, targetSteer)
            steerBias += 0.005 * targetSteer
            # ball to target derivative
            #steerBias += 0.002 * carToTargetVelocity.y
            # ball to target integral
            #steerBias += 0.000001 * self.carToTargetIntegral.y
            #print(f"{round(steerBias, 1)}\t{round(0.008 * carToTargetVelocity.y, 1)}")

            applySpeedLimit = True
            if kickoff or beAnnoying:
                self.steerBiasLimit = 0
            if abs(carLocation.x) < 930 and abs(
                    carLocation.y) > 5120 - 550 and ballLocation.z > 500:
                self.steerBiasLimit = 2.5
                applySpeedLimit = False
            if ballLocation.z > 160 or ballToCarLocation.length() > 800:
                self.steerBiasLimit = max(0.5, self.steerBiasLimit - 0.1)
            elif ballLocation.z < 100:
                self.steerBiasLimit = max(0.5, self.steerBiasLimit - 0.1)
            else:
                self.steerBiasLimit = min(
                    2.5, 1 + 1 * max(0, carSpeed - 600) / 1800,
                    self.steerBiasLimit + 0.065)

            if applySpeedLimit and ballToCarLocation.length() < 180:
                self.steerBiasLimit = min(
                    self.steerBiasLimit,
                    1.3 + (1400 - carVelocity.flat().length()) / 800)

            steer += min(self.steerBiasLimit,
                         max(-self.steerBiasLimit, steerBias))
            action_display = f"SBL {round(self.steerBiasLimit, 1)} SB: {round(min(self.steerBiasLimit, max(-self.steerBiasLimit, steerBias)), 1)}"
            #action_display = f"{round(ballToTargetLocation.x)}"

        ## THROTTLE
        throttle = 0
        # ball to car proportional
        throttle += 0.07 * ballToCarLocation.x
        # ball to car derivative
        throttle += 0.015 * ballToCarVelocity.x

        #print(ballVelocity.length())
        if (
                ballToCarLocation.length() < 300
                and not (abs(ballToCarLocation.y) > 100
                         and ballVelocity.length() < 500)
        ) and not beAnnoying:  # if the ball is too far from the car, use speed to drive car to ball

            throttleBias = 0
            ## NORMAL TARGET BIAS
            #ball to target proportional
            #throttleBias += 0.004 * ballToTargetLocation.x
            # ball to target derivative
            if ballLocation.z > 100:
                #action_display = f"triangle: {round((1 - inTriangleAmount), 1)}\ttargetangle: {round(0.8*math.cos(carToTargetAngle/2), 1)}"
                carToDesiredSpeed = carVelocity.flat().length(
                ) - desiredSpeed * max(0.2, (1 - inTriangleAmount))
                throttleBias += 0.005 * carToDesiredSpeed
            # ball to target integral
            #throttleBias += 0.00001 * self.carToTargetIntegral.x

            ## STEERING HELP BIAS WHEN FAR AWAY
            #targetSteeringSpeed = 400 + 3000 * math.pow(math.cos(carToTargetAngle/2), 16)
            #throttleSteeringBias = max(-1, 3 * (carSpeed - targetSteeringSpeed) / 1400)

            # alpha = max(0, min(1, (ballToTargetLocation.length() - 1000) / 3000))

            # throttleBias = throttleSteeringBias * alpha + throttleBias * (1 - alpha)

            throttle += min(2, max(-0.9, throttleBias))
            #action_display = f"TB: {round(throttleBias, 1)}\tT: {round(throttle, 1)}"
        else:
            throttle = 1 - 0.8 * math.cos(carToBallAngle)

        #print(action_display)

        if goingForBoost:
            throttle = max(throttle, 1)

        ## set controller state
        self.controller.steer = min(1, max(-1, steer))
        self.controller.throttle = min(1, max(-1, throttle))
        if myCar.has_wheel_contact and throttle > 1.7 and carLocation.z < 100 and realBallLocation.z < 500:
            self.controller.boost = carSpeed < 2300 - 991.667 / 120 * (
                1 if self.controller.boost else 10)
        else:
            self.controller.boost = False

            ## test if forward dodge is needed
            if abs(
                    steer
            ) < 0.5 and not kickoff and carSpeed > 1400 and carSpeed < 2200 and (
                    myCar.boost == 0 or carSpeed > 2300 - 20 - 500):

                try:
                    angleCoeff = carVelocity.normalized().dot(
                        ballVelocity.normalized())
                except:
                    angleCoeff = -1

                if angleCoeff > 0.95:

                    dist = (realBallLocation - carLocation).length()
                    vel = (carSpeed + 500 - ballVelocity.length())
                    time = dist / vel
                    ballAfterLocation = realBallLocation + time * ballVelocity
                    isStillInMap = abs(
                        ballAfterLocation.x) < 4096 + 500 and abs(
                            ballAfterLocation.y) < 5120 + 500
                    if time > 1.5:
                        self.agent.stateMachine.changeStateMidTick(Frontflip)
                        return True

        # print(self.ballToTargetIntegral)
        # action_display = f"steer: {round(ballToTargetLocation.y)}"
        # action_display = f"distance: {round(ballToTargetLocation.x)}"

        # # Find the direction of our car using the Orientation class
        #car_orientation = Orientation(myCar.physics.rotation).forward
        #car_direction = car_orientation.forward

        # steer_correction_radians = find_correction(car_direction, ballToCarLocation)

        # turnProportional = max(-1, min(1, steer_correction_radians * 4))
        # #action_display = f"turn {round(turn, 2)}"
        # self.controller.steer = turnProportional

        # throttleProportional = 10
        # speed = Vec3.length(myCar.physics.velocity)
        # targetSpeed = min(boostSpeed, Vec3.dist(ballLocation, carLocation) * 5 * math.cos(steer_correction_radians))

        # self.controller.throttle = max(-1, min(1, (targetSpeed - speed) * 1000))
        # self.controller.steer = turnProportional
        # self.controller.boost = speed < targetSpeed if self.controller.boost or (abs(turnProportional) < 1 and targetSpeed > normalSpeed) else (abs(turnProportional) < 1 and speed < targetSpeed - 400)

        # targetBallLocation.z = 150
        #draw_debug(self.agent, myCar, packet.game_ball, action_display, targetBallLocation, carlocs)

        return True
Ejemplo n.º 21
0
    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:

        # Update the game values and set the state
        self.game.read_game_information(packet, self.get_field_info())
        self.controls = SimpleControllerState()

        next_state = self.state

        # Reset everything
        if self.state == State.RESET:
            self.timer = 0.0
            # self.set_gamestate_straight_moving()
            # self.set_gamestate_straight_moving_towards()
            self.set_state_stationary_angled()
            # self.set_gamestate_angled_stationary()
            # self.set_state_stationary()
            next_state = State.WAIT

        # Wait so everything can settle in, mainly for ball prediction
        if self.state == State.WAIT:
            if self.timer > 0.2:
                next_state = State.INITIALIZE

        # Initialize the drive mechanic
        if self.state == State.INITIALIZE:
            self.drive = Drive(self.game.my_car)
            self.drive.target = self.game.ball.position
            self.drive.speed = 1400
            next_state = State.DRIVING

        # Start driving towards the target and check whether a dodge is possible, if so initialize the dodge
        if self.state == State.DRIVING:
            self.drive.target = self.game.ball.position
            self.drive.step(self.game.time_delta)
            self.controls = self.drive.controls
            a = time.time()
            target = self.game.my_car.position + 1000000 * (
                self.game.ball.position - self.game.my_car.position)
            can_dodge, simulated_duration, simulated_target = self.simulate()
            print(time.time() - a)
            if can_dodge:
                self.dodge = Dodge(self.game.my_car)
                self.turn = AerialTurn(self.game.my_car)
                self.dodge.duration = simulated_duration - 0.1
                self.dodge.target = simulated_target

                self.dodge.preorientation = look_at(simulated_target,
                                                    vec3(0, 0, 1))
                self.timer = 0
                next_state = State.DODGING

        # Perform the dodge
        if self.state == State.DODGING:
            self.dodge.step(self.game.time_delta)
            self.controls = self.dodge.controls

            T = self.dodge.duration - self.dodge.timer
            if T > 0:
                if self.dodge.timer < 0.2:
                    self.controls.boost = 1
                    # self.controls.pitch = 1
                else:
                    xf = self.game.my_car.position + 0.5 * T * T * vec3(
                        0, 0, -650) + T * self.game.my_car.velocity

                    delta_x = self.game.ball.position - xf
                    if angle_between(vec2(self.game.my_car.forward()),
                                     self.dodge.direction) < 0.3:
                        if norm(delta_x) > 50:
                            self.controls.boost = 1
                            self.controls.throttle = 0.0
                        else:
                            self.controls.boost = 0
                            self.controls.throttle = clip(
                                0.5 * (200 / 3) * T * T, 0.0, 1.0)
                    else:
                        self.controls.boost = 0
                        self.controls.throttle = 0.0
            else:
                self.controls.boost = 0

            # Great line
            # if self.game.time == packet.game_ball.latest_touch.time_seconds:
            #     print(self.game.my_car.position)
            if self.dodge.finished and self.game.my_car.on_ground:
                next_state = State.RESET

        self.timer += self.game.time_delta
        self.state = next_state

        return self.controls
Ejemplo n.º 22
0
 def __init__(self, car: Car, info: Game):
     self.car: Car = car
     self.info: Game = info
     self.controls = Input()
     self.drive = Drive(car)
Ejemplo n.º 23
0
def kick_off(agent):
    ball = agent.game.ball
    car = agent.game.my_car
    t = distance_2d(ball.location, car.location) / 2200
    batmobile_resting = 17.00
    robbies_constant = (ball.location - vec3(0, 0, 92.75 - batmobile_resting) -
                        car.location - car.velocity * t) * 2 * t**-2
    robbies_boost_constant = dot(normalize(xy(
        car.forward())), normalize(
            xy(robbies_constant))) > (0.3 if car.on_ground else 0.1)
    """"Module that performs the kickoffs"""
    if agent.kickoffStart == "Diagonal":
        if agent.step is Step.Drive:
            agent.drive.step(agent.game.time_delta)
            agent.controls = agent.drive.controls
            if agent.drive.finished:
                ball_location = ball.location + vec3(
                    0, -sign(agent.team) * 500, 0)
                target = car.location + 250 * normalize(ball_location -
                                                        car.location)
                agent.drive = Drive(car)
                agent.drive.target = target
                agent.drive.speed = 2400
                agent.step = Step.Drive_1
        if agent.step is Step.Drive_1:
            agent.drive.step(agent.game.time_delta)
            agent.controls = agent.drive.controls
            if agent.drive.finished:
                target = vec3(
                    dot(
                        rotation(
                            math.radians(-sign(agent.game.team) *
                                         sign(car.location[0]) * 60)),
                        vec2(car.forward())) * 10000)
                preorientation = dot(
                    axis_to_rotation(
                        vec3(
                            0, 0,
                            math.radians(-sign(agent.game.team) *
                                         -sign(car.location[0]) * 30))),
                    car.rotation)
                setup_first_dodge(agent, 0.05, 0.3, target, preorientation)
        elif agent.step is Step.Dodge_1:
            agent.timer += agent.game.time_delta
            if agent.timer > 0.8:
                lerp_var = lerp(
                    normalize(robbies_constant),
                    normalize(ball.location -
                              vec3(0, 0, 92.75 - batmobile_resting) -
                              car.location), 0.8)
                agent.turn.target = look_at(lerp_var, vec3(0, 0, 1))
                agent.turn.step(agent.game.time_delta)
                agent.controls = agent.turn.controls
                if car.on_ground:
                    agent.step = Step.Catching
            else:
                agent.dodge.step(agent.game.time_delta)
                agent.controls = agent.dodge.controls
            agent.controls.boost = robbies_boost_constant
    elif agent.kickoffStart == "Center":
        if agent.step is Step.Drive:
            agent.drive.step(agent.game.time_delta)
            agent.controls = agent.drive.controls
            if agent.drive.finished:
                target = vec3(
                    dot(rotation(math.radians(-65)), vec2(car.forward())) *
                    10000)
                preorientation = dot(
                    axis_to_rotation(vec3(0, 0, math.radians(45))),
                    car.rotation)
                setup_first_dodge(agent, 0.05, 0.4, target, preorientation)
        elif agent.step is Step.Dodge_1:
            agent.timer += agent.game.time_delta
            if agent.timer > 0.8:
                agent.turn.target = look_at(xy(ball.location - car.location),
                                            vec3(0, 0, 1))
                agent.turn.step(agent.game.time_delta)
                agent.controls = agent.turn.controls
                set_steer(agent)
            else:
                agent.dodge.step(agent.game.time_delta)
                agent.controls = agent.dodge.controls
            agent.controls.boost = robbies_boost_constant
        elif agent.step is Step.Steer:
            agent.drive.step(agent.game.time_delta)
            agent.controls = agent.drive.controls
            if distance_2d(car.location, ball.location) < 800:
                agent.step = Step.Dodge_2
                agent.dodge = Dodge(car)
                agent.dodge.duration = 0.075
                agent.dodge.target = ball.location
        elif agent.step is Step.Dodge_2:
            agent.dodge.step(agent.game.time_delta)
            agent.controls = agent.dodge.controls
            if agent.dodge.finished and car.on_ground:
                agent.step = Step.Catching
    elif agent.kickoffStart == "offCenter":
        if agent.step is Step.Drive:
            agent.drive.step(agent.game.time_delta)
            agent.controls = agent.drive.controls
            if distance_2d(car.location, agent.drive.target) < 650:
                target = vec3(
                    dot(
                        rotation(
                            math.radians(-sign(agent.game.team) *
                                         -sign(car.location[0]) * 100)),
                        vec2(car.forward())) * 10000)
                preorientation = dot(
                    axis_to_rotation(
                        vec3(
                            0, 0,
                            math.radians(-sign(agent.game.team) *
                                         sign(car.location[0]) * 30))),
                    car.rotation)
                setup_first_dodge(agent, 0.05, 0.4, target, preorientation)
        elif agent.step is Step.Dodge_1:
            agent.timer += agent.game.time_delta
            if agent.timer > 0.8:
                lerp_var = lerp(
                    normalize(robbies_constant),
                    normalize(ball.location -
                              vec3(0, 0, 92.75 - batmobile_resting) -
                              car.location), 0.25)
                agent.turn.target = look_at(lerp_var, vec3(0, 0, 1))
                agent.turn.step(agent.game.time_delta)
                agent.controls = agent.turn.controls
                set_steer(agent)
            else:
                agent.dodge.step(agent.game.time_delta)
                agent.controls = agent.dodge.controls
            agent.controls.boost = robbies_boost_constant
        elif agent.step is Step.Steer:
            agent.drive.step(agent.game.time_delta)
            agent.controls = agent.drive.controls
            if distance_2d(ball.location, car.location) < 800:
                agent.step = Step.Dodge_2
                agent.dodge = Dodge(car)
                agent.dodge.duration = 0.075
                agent.dodge.target = ball.location
        elif agent.step is Step.Dodge_2:
            agent.dodge.step(agent.game.time_delta)
            agent.controls = agent.dodge.controls
            if agent.dodge.finished and car.on_ground:
                agent.step = Step.Catching
Ejemplo n.º 24
0
class MyAgent(BaseAgent):
    def __init__(self, name, team, index):
        super().__init__(name, team, index)
        self.game = Game(index, team)
        self.name = name
        self.controls = SimpleControllerState()

        self.timer = 0.0

        self.drive = Drive(self.game.my_car)
        self.navigator = None
        self.dodge = None
        self.turn = None
        self.state = State.RESET

    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:

        self.game.read_game_information(packet, self.get_rigid_body_tick(),
                                        self.get_field_info())
        self.controls = SimpleControllerState()

        next_state = self.state

        if self.state == State.RESET:
            self.timer = 0.0
            self.set_gamestate_straight_moving()
            # self.set_gamestate_angled_stationary()
            # self.set_gamestate_straight_moving_towards()
            next_state = State.WAIT

        if self.state == State.WAIT:

            if self.timer > 0.2:
                next_state = State.INITIALIZE

        if self.state == State.INITIALIZE:
            self.drive = Drive(self.game.my_car)
            self.drive.target, self.drive.speed = self.game.ball.location, 2300
            next_state = State.DRIVING

        if self.state == State.DRIVING:
            self.drive.target = self.game.ball.location
            self.drive.step(self.game.time_delta)
            self.controls = self.drive.controls
            can_dodge, simulated_duration, simulated_target = self.simulate()
            if can_dodge:
                self.dodge = Dodge(self.game.my_car)
                self.turn = AerialTurn(self.game.my_car)
                print("============")
                print(simulated_duration)
                self.dodge.duration = simulated_duration - 0.1
                self.dodge.target = simulated_target
                self.timer = 0
                next_state = State.DODGING

        if self.state == State.DODGING:
            self.dodge.step(self.game.time_delta)
            self.controls = self.dodge.controls
            if self.game.time == packet.game_ball.latest_touch.time_seconds:
                print(self.timer)
            if self.dodge.finished and self.game.my_car.on_ground:
                next_state = State.RESET

        self.timer += self.game.time_delta
        self.state = next_state

        return self.controls

    def simulate(self):
        ball_prediction = self.get_ball_prediction_struct()
        duration_estimate = math.floor(
            get_time_at_height(self.game.ball.location[2], 0.2) * 10) / 10
        for i in range(6):
            car = Car(self.game.my_car)
            ball = Ball(self.game.ball)
            batmobile = obb()
            batmobile.half_width = vec3(64.4098892211914, 42.335182189941406,
                                        14.697200775146484)
            batmobile.center = car.location + dot(car.rotation,
                                                  vec3(9.01, 0, 12.09))
            batmobile.orientation = car.rotation
            dodge = Dodge(car)
            dodge.duration = duration_estimate + i / 60
            dodge.target = ball.location
            for j in range(round(60 * dodge.duration)):
                dodge.target = ball.location
                dodge.step(1 / 60)
                car.step(dodge.controls, 1 / 60)
                prediction_slice = ball_prediction.slices[j]
                physics = prediction_slice.physics
                ball_location = vec3(physics.location.x, physics.location.y,
                                     physics.location.z)
                dodge.target = ball_location
                batmobile.center = car.location + dot(car.rotation,
                                                      vec3(9.01, 0, 12.09))
                batmobile.orientation = car.rotation
                if intersect(sphere(ball_location, 93.15), batmobile) and abs(
                        ball_location[2] - car.location[2]
                ) < 25 and car.location[2] < ball_location[2]:
                    return True, j / 60, ball_location
        return False, None, None

    def set_gamestate_straight_moving(self):
        # put the car in the middle of the field
        car_state = CarState(
            physics=Physics(location=Vector3(0, -1000, 18),
                            velocity=Vector3(0, 0, 0),
                            rotation=Rotator(0, math.pi / 2, 0),
                            angular_velocity=Vector3(0, 0, 0)))

        # put the ball in the middle of the field

        ball_state = BallState(
            physics=Physics(location=Vector3(0, 1500, 93),
                            velocity=Vector3(0, random.randint(-250, 800),
                                             random.randint(700, 800)),
                            rotation=Rotator(0, 0, 0),
                            angular_velocity=Vector3(0, 0, 0)))

        self.set_game_state(
            GameState(ball=ball_state, cars={self.game.id: car_state}))

    def set_gamestate_straight_moving_towards(self):
        # put the car in the middle of the field
        car_state = CarState(physics=Physics(
            location=Vector3(0, 0, 18),
            velocity=Vector3(0, 0, 0),
            angular_velocity=Vector3(0, 0, 0),
        ))

        # put the ball in the middle of the field

        ball_state = BallState(physics=Physics(
            location=Vector3(0, 2500, 93),
            velocity=Vector3(0, -250, 700),
            rotation=Rotator(0, 0, 0),
            angular_velocity=Vector3(0, 0, 0),
        ))

        self.set_game_state(
            GameState(ball=ball_state, cars={self.game.id: car_state}))

    def set_gamestate_angled_stationary(self):
        # put the car in the middle of the field
        car_state = CarState(
            physics=Physics(location=Vector3(-1000, -1500, 18),
                            velocity=Vector3(0, 0, 0),
                            rotation=Rotator(0, math.pi / 8, 0),
                            angular_velocity=Vector3(0, 0, 0)))

        # put the ball in the middle of the field

        ball_state = BallState(
            physics=Physics(location=Vector3(0, 0, 750),
                            velocity=Vector3(0, 0, 1),
                            rotation=Rotator(0, 0, 0),
                            angular_velocity=Vector3(0, 0, 0)))

        self.set_game_state(
            GameState(ball=ball_state, cars={self.game.id: car_state}))
Ejemplo n.º 25
0
class CustomDrive:
    def __init__(self, car):
        self.car = car
        self.target = vec3(0, 0, 0)
        self.speed = 2300
        self.controls = SimpleControllerState()
        self.finished = False
        self.rlu_drive = RLUDrive(self.car)
        self.update_rlu_drive()
        self.power_turn = True  # Handbrake while reversing to turn around quickly
        self.aerial_turn = AerialTurn(car)
        self.kickoff = False

    def step(self, dt: float):
        self.speed = abs(self.speed)
        car_to_target = (self.target - self.car.location)
        local_target = dot(car_to_target, self.car.rotation)
        angle = atan2(local_target[1], local_target[0])
        vel = norm(self.car.velocity)
        in_air = (not self.car.on_ground)
        on_wall = (self.car.location[2] > 250 and not in_air)

        reverse = (cos(angle) < 0 and not (on_wall or in_air or self.kickoff))

        get_off_wall = (on_wall and local_target[2] > 450)
        if get_off_wall:
            car_to_target[2] = -self.car.location[2]
            local_target = dot(car_to_target, self.car.rotation)
            angle = atan2(local_target[1], local_target[0])

        max_speed = self.determine_max_speed(local_target)

        self.update_rlu_drive(reverse, max_speed)
        self.rlu_drive.step(dt)
        self.finished = self.rlu_drive.finished

        self.controls = self.rlu_drive.controls
        self.controls.handbrake = False

        if reverse:
            angle = -invert_angle(angle)
            if self.power_turn and not on_wall:
                angle *= -1
                self.controls.handbrake = (vel > 200)
            self.controls.steer = cap(angle * 3, -1, 1)
            self.controls.boost = False
        if not self.controls.handbrake:
            self.controls.handbrake = (abs(angle) > radians(70) and vel > 500
                                       and not on_wall)
        if self.controls.handbrake:
            self.controls.handbrake = (dot(self.car.velocity, car_to_target) >
                                       -150)

        if in_air:
            self.aerial_turn.target = look_at(xy(car_to_target), vec3(0, 0, 1))
            self.aerial_turn.step(dt)
            aerial_turn_controls = self.aerial_turn.controls
            self.controls.pitch = aerial_turn_controls.pitch
            self.controls.yaw = aerial_turn_controls.yaw
            self.controls.roll = aerial_turn_controls.roll
            self.controls.boost = False

    def update_rlu_drive(self, reverse: bool = False, max_speed: float = 2200):
        self.target = self.target
        self.rlu_drive.target = self.target
        self.rlu_drive.speed = cap(self.speed * (-1 if reverse else 1),
                                   -max_speed, max_speed)

    def determine_max_speed(self, local_target):
        low = 100
        high = 2200
        if self.kickoff:
            return high
        for i in range(5):
            mid = (low + high) / 2
            radius = (1 / RLUDrive.max_turning_curvature(mid))
            local_circle = vec3(0, copysign(radius, local_target[1]), 0)
            dist = norm(local_circle - xy(local_target))
            if dist < radius:
                high = mid
            else:
                low = mid
        return high