示例#1
0
class AerialStep(BaseStep):
    def __init__(self, agent: BeepBoop):
        super().__init__(agent)
        self.aerial = Aerial(self.agent.game_info.my_car, vec3(0, 0, 0), 0)
        self.cancellable: bool = False

    def handle_aerial_start(self) -> None:
        ball_prediction: BallPrediction = self.agent.get_ball_prediction_struct()
        # Find the first viable point on the ball path to aerial to
        for i in range(ball_prediction.num_slices):
            loc = ball_prediction.slices[i].physics.location
            self.aerial.target = vec3(loc.x, loc.y, loc.z)
            self.aerial.t_arrival = ball_prediction.slices[i].game_seconds
            if self.aerial.is_viable():
                break

    def get_output(self, packet: GameTickPacket) -> Optional[SimpleControllerState]:
        self.agent.game_info.read_packet(packet)

        # RLUtilities doesn't check for equality properly between equal vec3 objects, so we have to use this ghetto way
        if self.aerial.target[0] == 0 and self.aerial.target[1] == 0 and self.aerial.target[2] == 0:
            self.handle_aerial_start()

        self.aerial.step(1 / 60)

        if not self.aerial.is_viable() or self.aerial.finished:
            self.cancellable = True
            return None
        else:
            return self.aerial.controls
示例#2
0
    def execute(self, bot):
        bot.renderer.draw_string_3d(bot.info.my_car.pos, 1, 1, "Aerial",
                                    bot.renderer.red())

        self.aerial = Aerial(bot.info.my_car, vec3(0, 0, 0), 0)
        ball = DropshotBall(bot.info.ball)

        for i in range(60):
            ball.step_ds(0.016666)
            self.aerial.target = ball.pos
            self.aerial.t_arrival = ball.t
            # Check if we can reach it by an aerial
            if self.aerial.is_viable():
                # One more step
                ball.step_ds(0.016666)
                self.aerial.target = ball.pos + vec3(0, 0, 15)
                self.aerial.t_arrival = ball.t
                break

        if self.aerial.is_viable():
            bot.plan = AerialPlan(bot.info.my_car, self.aerial.target,
                                  self.aerial.t_arrival)

        self.drive = Drive(bot.info.my_car, bot.info.ball.pos, 2300)
        self.drive.step(0.016666)
        bot.controls = self.drive.controls
示例#3
0
class QuickAerial:
    def __init__(self, bot):
        self.aerial = None
        self.drive = None
        pass

    def utility(self, bot):
        ball = bot.info.ball
        if ball.pos[2] < 1000:
            return 0

        car = bot.info.my_car
        if car.boost < 30:
            return 0

        car_to_ball = ball.pos - car.pos
        ctb_flat = vec3(car_to_ball[0], car_to_ball[1], 0)
        ang = angle_between(ctb_flat, car.forward())
        if ang > 1:
            return 0

        vf = norm(car.vel)
        if vf < 800:
            return 0

        return 0.8

    def execute(self, bot):
        bot.renderer.draw_string_3d(bot.info.my_car.pos, 1, 1, "Aerial",
                                    bot.renderer.red())

        self.aerial = Aerial(bot.info.my_car, vec3(0, 0, 0), 0)
        ball = DropshotBall(bot.info.ball)

        for i in range(60):
            ball.step_ds(0.016666)
            self.aerial.target = ball.pos
            self.aerial.t_arrival = ball.t
            # Check if we can reach it by an aerial
            if self.aerial.is_viable():
                # One more step
                ball.step_ds(0.016666)
                self.aerial.target = ball.pos + vec3(0, 0, 15)
                self.aerial.t_arrival = ball.t
                break

        if self.aerial.is_viable():
            bot.plan = AerialPlan(bot.info.my_car, self.aerial.target,
                                  self.aerial.t_arrival)

        self.drive = Drive(bot.info.my_car, bot.info.ball.pos, 2300)
        self.drive.step(0.016666)
        bot.controls = self.drive.controls
示例#4
0
    def torus_flight_pattern(self, packet, drones: List[Drone],
                             start_time) -> StepResult:

        # self.renderer.begin_rendering(drones[0].index)
        radian_spacing = 2 * math.pi / len(drones)

        if len(self.aerials) == 0:
            for index, drone in enumerate(drones):
                self.aerials.append(
                    Aerial(self.game_info.cars[drone.index], vec3(0, 0, 0), 0))
                self.angular_progress.append(index * radian_spacing)

        elapsed = packet.game_info.seconds_elapsed - start_time
        # radius = 4000 - elapsed * 100
        if self.previous_seconds_elapsed == 0:
            time_delta = 0
        else:
            time_delta = packet.game_info.seconds_elapsed - self.previous_seconds_elapsed

        radius = 900 * (1 + math.cos(elapsed * TORUS_RATE)) + 300
        height = 450 * (1 + math.sin(elapsed * TORUS_RATE)) + 800

        # self.renderer.draw_string_2d(10, 10, 2, 2, f"r {radius}", self.renderer.white())
        # self.renderer.draw_string_2d(10, 30, 2, 2, f"z {drones[0].pos[2]}", self.renderer.white())

        for index, drone in enumerate(drones):
            if "sniped" in drone.attributes:
                continue

            # This function was fit from the following data points, where I experimentally found deltas which
            # worked well with sampled radius values.
            # {2500, 0.7}, {1000, 0.9}, {500, 1.2}, {200, 2.0}
            # Originally was 2476 / (radius + 1038)
            # angular_delta = time_delta * (800 / radius + 0.2)
            angular_delta = time_delta * RADIUS_SPEED.lerp(radius)
            self.angular_progress[index] += angular_delta
            aerial = self.aerials[index]
            progress = self.angular_progress[index]
            target = Vec3(radius * math.sin(progress),
                          radius * math.cos(progress), height)
            to_target = target - Vec3(drone.pos[0], drone.pos[1], drone.pos[2])
            # self.renderer.draw_line_3d(drone.pos, target, self.renderer.yellow())
            aerial.target = vec3(target.x, target.y, target.z)
            aerial.t_arrival = drone.time + to_target.length() / 2000 + 0.3
            aerial.step(0.008)
            drone.ctrl.boost = aerial.controls.boost
            drone.ctrl.pitch = aerial.controls.pitch
            drone.ctrl.yaw = aerial.controls.yaw
            drone.ctrl.roll = aerial.controls.roll
            drone.ctrl.jump = aerial.controls.jump

        self.previous_seconds_elapsed = packet.game_info.seconds_elapsed
        # self.renderer.end_rendering()

        return StepResult(finished=elapsed > 160)
示例#5
0
    def tick(self, packet: GameTickPacket) -> StepResult:

        if self.game_info is None:
            self.game_info = GameInfo(self.index,
                                      packet.game_cars[self.index].team)
        self.game_info.read_packet(packet)

        if self.aerial is None:
            self.aerial = Aerial(
                self.game_info.my_car,
                vec3(self.target.x, self.target.y, self.target.z),
                self.arrival_time)

        self.aerial.step(SECONDS_PER_TICK)
        controls = SimpleControllerState()
        controls.boost = self.aerial.controls.boost
        controls.pitch = self.aerial.controls.pitch
        controls.yaw = self.aerial.controls.yaw
        controls.roll = self.aerial.controls.roll
        controls.jump = self.aerial.controls.jump

        return StepResult(controls,
                          packet.game_info.seconds_elapsed > self.arrival_time)
示例#6
0
class AerialStep(Step):
    """
    This uses the Aerial controller provided by RLUtilities. Thanks chip!
    It will take care of jumping off the ground and flying toward the target.
    This will only work properly if you call tick repeatedly on the same instance.
    """
    def __init__(self, target: Vec3, arrival_time: float, index: int):
        self.index = index
        self.aerial: Aerial = None
        self.game_info: GameInfo = None
        self.target = target
        self.arrival_time = arrival_time

    def tick(self, packet: GameTickPacket) -> StepResult:

        if self.game_info is None:
            self.game_info = GameInfo(self.index,
                                      packet.game_cars[self.index].team)
        self.game_info.read_packet(packet)

        if self.aerial is None:
            self.aerial = Aerial(
                self.game_info.my_car,
                vec3(self.target.x, self.target.y, self.target.z),
                self.arrival_time)

        self.aerial.step(SECONDS_PER_TICK)
        controls = SimpleControllerState()
        controls.boost = self.aerial.controls.boost
        controls.pitch = self.aerial.controls.pitch
        controls.yaw = self.aerial.controls.yaw
        controls.roll = self.aerial.controls.roll
        controls.jump = self.aerial.controls.jump

        return StepResult(controls,
                          packet.game_info.seconds_elapsed > self.arrival_time)
示例#7
0
    def __init__(self, car: Car, ball_predictions, predicate: callable = None, power = 1000):
        self.ball: Ball = None
        self.is_viable = True

        #find the first reachable ball slice that also meets the predicate
        test_aerial = Aerial(car, vec3(0, 0, 0), 0)
        for ball in ball_predictions:
            test_aerial.target = ball.pos
            test_aerial.t_arrival = ball.t
            test_aerial.calculate_course()
            if test_aerial.B_avg < power and (predicate is None or predicate(car, ball)):
                self.ball = ball
                break

        #if no slice is found, use the last one
        if self.ball is None:
            self.ball = ball_predictions[-1]
            self.is_viable = False

        self.time = self.ball.t
        self.ground_pos = ground(self.ball.pos)
        self.pos = self.ball.pos
示例#8
0
from RLUtilities.Simulation import Car, Ball
from RLUtilities.LinearAlgebra import vec3, dot

from RLUtilities.Maneuvers import AerialTurn, Aerial

c = Car()

b = Ball()
b.pos = vec3(0, 0, 1000)
b.vel = vec3(0, 0, 0)
b.omega = vec3(0, 0, 0)
b.t = 0

action = Aerial(c, b.pos, b.t)

b.step(0.0166)
print(action.t_arrival)
print(action.target)
示例#9
0
    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:
        self.info.read_packet(packet)
        self.controls = SimpleControllerState()

        if self.timer == 0.0:

            self.csign = random.choice([-1, 1])

            # this just initializes the car and ball
            # to different starting points each time
            c_position = Vector3(random.uniform(-1000, 1000),
                                 random.uniform(-4500, -4000),
                                 25)

            car_state = CarState(physics=Physics(
                location=c_position,
                velocity=Vector3(0, 1000, 0),
                rotation=Rotator(0, 1.5 * self.csign, 0),
                angular_velocity=Vector3(0, 0, 0)
            ))

            self.bsign = random.choice([-1, 1])

            b_position = Vector3(random.uniform(-3500, -3000) * self.bsign,
                                 random.uniform(-1500,  1500),
                                 random.uniform(  150,   500))

            b_velocity = Vector3(random.uniform( 1000, 1500) * self.bsign,
                                 random.uniform(- 500,  500),
                                 random.uniform( 1000, 1500))

            ball_state = BallState(physics=Physics(
                location=b_position,
                velocity=b_velocity,
                rotation=Rotator(0, 0, 0),
                angular_velocity=Vector3(0, 0, 0)
            ))

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

            self.increment_timer = True

        if self.timer < 0.3:
            self.controls.throttle = 1 * self.csign
        else:
            if self.action == None:

                # set empty values for target and t_arrival initially
                self.action = Aerial(self.info.my_car, vec3(0,0,0), 0)

                # predict where the ball will be
                prediction = Ball(self.info.ball)
                self.ball_predictions = [vec3(prediction.pos)]

                for i in range(150):
                    prediction.step(0.016666)
                    prediction.step(0.016666)
                    self.ball_predictions.append(vec3(prediction.pos))

                    # if the ball is in the air
                    if prediction.pos[2] > 100:

                        self.action.target = prediction.pos
                        self.action.t_arrival = prediction.t

                        # check if we can reach it by an aerial
                        if self.action.is_viable():
                            break

            nsteps = 30
            delta_t = self.action.t_arrival - self.info.my_car.time
            prediction = Car(self.info.my_car)
            self.car_predictions = [vec3(prediction.pos)]
            for i in range(nsteps):
                prediction.step(Input(), delta_t / nsteps)
                self.car_predictions.append(vec3(prediction.pos))

            r = 200
            self.renderer.begin_rendering()
            purple = self.renderer.create_color(255, 230, 30, 230)
            white  = self.renderer.create_color(255, 230, 230, 230)

            x = vec3(r,0,0)
            y = vec3(0,r,0)
            z = vec3(0,0,r)
            target = self.action.target
            future = self.action.target - self.action.A

            self.renderer.draw_polyline_3d(self.ball_predictions, purple)
            self.renderer.draw_line_3d(target - x, target + x, purple)
            self.renderer.draw_line_3d(target - y, target + y, purple)
            self.renderer.draw_line_3d(target - z, target + z, purple)

            self.renderer.draw_polyline_3d(self.car_predictions, white)
            self.renderer.draw_line_3d(future - x, future + x, white)
            self.renderer.draw_line_3d(future - y, future + y, white)
            self.renderer.draw_line_3d(future - z, future + z, white)
            self.renderer.end_rendering()

            self.action.step(1.0 / 60.0)
            self.controls = self.action.controls

            if self.action.finished or self.timer > 10.0:
                self.timer = 0.0
                self.action = None
                self.increment_timer = False
                self.predictions = []

        if self.increment_timer:
            self.timer += 1.0 / 60.0

        self.info.my_car.last_input.roll  = self.controls.roll
        self.info.my_car.last_input.pitch = self.controls.pitch
        self.info.my_car.last_input.yaw   = self.controls.yaw
        self.info.my_car.last_input.boost = self.controls.boost

        return self.controls
示例#10
0
 def __init__(self, agent: BeepBoop):
     super().__init__(agent)
     self.aerial = Aerial(self.agent.game_info.my_car, vec3(0, 0, 0), 0)
     self.cancellable: bool = False