コード例 #1
0
class DoubleTouch(Maneuver):
    """
    Execute a regular AerialStrike, but when it finishes, look if we could continue aerialing for a second hit.
    """
    def __init__(self, aerial_strike: AerialStrike):
        super().__init__(aerial_strike.car)
        self.aerial_strike = aerial_strike
        self.info = self.aerial_strike.info

        self.aerial = Aerial(self.car)
        self.aerial.up = vec3(0, 0, -1)

        self._flight_path: List[vec3] = []

    def find_second_touch(self):
        self.info.predict_ball(duration=4.0)
        for i in range(0, len(self.info.ball_predictions), 5):
            ball = self.info.ball_predictions[i]
            if ball.position[2] < 500: break
            self.aerial.target = ball.position - direction(
                ball, self.aerial_strike.target) * 80
            self.aerial.arrival_time = ball.time
            final_car = AerialStrike.simulate_flight(self.car, self.aerial,
                                                     self._flight_path)
            if distance(final_car, self.aerial.target) < 50:
                return

        self.finished = True

    def step(self, dt: float):
        if self.aerial_strike.finished:
            self.aerial.step(dt)
            self.controls = self.aerial.controls
            self.finished = self.aerial.finished
            if self.car.on_ground: self.finished = True

        else:
            self.aerial_strike.step(dt)
            self.controls = self.aerial_strike.controls

            if self.aerial_strike.finished:
                if not self.car.on_ground:
                    self.find_second_touch()
                else:
                    self.finished = True

    def interruptible(self) -> bool:
        return self.aerial_strike.interruptible()

    def render(self, draw: DrawingTool):
        if self.aerial_strike.finished:
            draw.color(draw.pink)
            draw.crosshair(self.aerial.target)
            draw.color(draw.lime)
            draw.polyline(self._flight_path)
        else:
            self.aerial_strike.render(draw)
コード例 #2
0
def aerial_step(aerial: Aerial, car: Car, rotation_input=None, dt=1.0 / 60.0):
    return_value = aerial.step(dt)
    if rotation_input is not None and aerial.arrival_time - car.time <= 0.5:
        aerial.controls.pitch = rotation_input.pitch
        aerial.controls.yaw = rotation_input.yaw
        aerial.controls.roll = rotation_input.roll
        # aerial.controls.boost = rotation_input.boost
    return return_value
コード例 #3
0
ファイル: double_touch.py プロジェクト: azeemba/RLBotPack
class DoubleTouch(Maneuver):
    """
    Execute a regular AerialStrike, but when it finishes, look if we could continue aerialing for a second hit.
    """
    def __init__(self, aerial_strike: AerialStrike):
        super().__init__(aerial_strike.car)
        self.aerial_strike = aerial_strike
        self.info = self.aerial_strike.info

        self.aerial = Aerial(self.car)

    def find_second_touch(self):
        self.info.predict_ball(time_limit=3.0)
        intercept = AirToAirIntercept(self.car, self.info.ball_predictions)
        self.aerial.target = intercept.position - direction(intercept, self.aerial_strike.target) * 80
        self.aerial.up = vec3(0, 0, -1)
        self.aerial.arrival_time = intercept.time

        if not intercept.is_viable:
            self.finished = True

    def step(self, dt: float):
        if self.aerial_strike.finished:
            self.aerial.step(dt)
            self.controls = self.aerial.controls
            self.finished = self.aerial.finished
        else:
            self.aerial_strike.step(dt)
            self.controls = self.aerial_strike.controls

            if self.aerial_strike.finished:
                if not self.car.on_ground:
                    self.find_second_touch()
                else:
                    self.finished = True

    def interruptible(self) -> bool:
        return self.aerial_strike.interruptible()

    def render(self, draw: DrawingTool):
        if self.aerial_strike.finished:
            draw.color(draw.pink)
            draw.crosshair(self.aerial.target)
        else:
            self.aerial_strike.render(draw)
コード例 #4
0
    def simulate_flight(car: Car, aerial: Aerial, flight_path: List[vec3] = None) -> Car:
        test_car = Car(car)
        test_aerial = Aerial(test_car)
        test_aerial.target = aerial.target
        test_aerial.arrival_time = aerial.arrival_time
        test_aerial.angle_threshold = aerial.angle_threshold
        test_aerial.up = aerial.up
        test_aerial.single_jump = aerial.single_jump

        if flight_path: flight_path.clear()

        while not test_aerial.finished:
            test_aerial.step(1 / 120)
            test_car.boost = 100  # TODO: fix boost depletion in RLU car sim
            test_car.step(test_aerial.controls, 1 / 120)

            if flight_path:
                flight_path.append(vec3(test_car.position))

        return test_car
コード例 #5
0
    def simulate_flight(self, car: Car, write_to_flight_path=True) -> Car:
        test_car = Car(car)
        test_aerial = Aerial(test_car)
        test_aerial.target = self.aerial.target
        test_aerial.arrival_time = self.aerial.arrival_time
        test_aerial.angle_threshold = self.aerial.angle_threshold
        test_aerial.up = self.aerial.up
        test_aerial.single_jump = self.aerial.single_jump

        if write_to_flight_path:
            self._flight_path.clear()

        while not test_aerial.finished:
            test_aerial.step(1 / 120)
            test_car.boost = 100  # TODO: fix boost depletion in RLU car sim
            test_car.step(test_aerial.controls, 1 / 120)

            if write_to_flight_path:
                self._flight_path.append(vec3(test_car.position))

        return test_car
コード例 #6
0
class AerialStrike(Strike):
    MAX_DISTANCE_ERROR = 50
    DELAY_TAKEOFF = True
    MINIMAL_HEIGHT = 400
    MAXIMAL_HEIGHT = 800
    MINIMAL_HEIGHT_TIME = 1.0
    MAXIMAL_HEIGHT_TIME = 2.5
    DOUBLE_JUMP = False

    def __init__(self, car: Car, info: GameInfo, target: vec3 = None):
        self.aerial = Aerial(car)
        self.aerial.angle_threshold = 0.8
        self.aerial.single_jump = not self.DOUBLE_JUMP
        super().__init__(car, info, target)
        self.arrive.allow_dodges_and_wavedashes = False

        self.aerialing = False
        self.too_early = False
        self._flight_path: List[vec3] = []

    def intercept_predicate(self, car: Car, ball: Ball):
        required_time = range_map(ball.position[2], self.MINIMAL_HEIGHT,
                                  self.MAXIMAL_HEIGHT,
                                  self.MINIMAL_HEIGHT_TIME,
                                  self.MAXIMAL_HEIGHT_TIME)
        return self.MINIMAL_HEIGHT < ball.position[
            2] < self.MAXIMAL_HEIGHT and ball.time - car.time > required_time

    def configure(self, intercept: Intercept):
        super().configure(intercept)
        self.aerial.target = intercept.position - direction(
            intercept, self.target) * 80
        self.aerial.up = normalize(
            ground_direction(intercept, self.car) + vec3(0, 0, 0.5))
        self.aerial.arrival_time = intercept.time

    def simulate_flight(self, car: Car, write_to_flight_path=True) -> Car:
        test_car = Car(car)
        test_aerial = Aerial(test_car)
        test_aerial.target = self.aerial.target
        test_aerial.arrival_time = self.aerial.arrival_time
        test_aerial.angle_threshold = self.aerial.angle_threshold
        test_aerial.up = self.aerial.up
        test_aerial.single_jump = self.aerial.single_jump

        if write_to_flight_path:
            self._flight_path.clear()

        while not test_aerial.finished:
            test_aerial.step(1 / 120)
            test_car.boost = 100  # TODO: fix boost depletion in RLU car sim
            test_car.step(test_aerial.controls, 1 / 120)

            if write_to_flight_path:
                self._flight_path.append(vec3(test_car.position))

        return test_car

    def interruptible(self) -> bool:
        return self.aerialing or super().interruptible()

    def step(self, dt):
        if self.aerialing:
            self.aerial.target_orientation = look_at(
                direction(self.car, self.target), vec3(0, 0, -1))
            self.aerial.step(dt)
            self.controls = self.aerial.controls
            self.finished = self.aerial.finished

        else:
            super().step(dt)

            # simulate aerial from current state
            simulated_car = self.simulate_flight(self.car)

            # if the car ended up too far, we're too fast and we need to slow down
            if ground_distance(self.car,
                               self.aerial.target) + 100 < ground_distance(
                                   self.car, simulated_car):
                # self.controls.throttle = -1
                pass

            # if it ended up near the target, we could take off
            elif distance(simulated_car,
                          self.aerial.target) < self.MAX_DISTANCE_ERROR:
                if angle_to(self.car, self.aerial.target) < 0.1 or norm(
                        self.car.velocity) < 1000:

                    if self.DELAY_TAKEOFF:
                        # extrapolate current state a small amount of time
                        future_car = Car(self.car)
                        time = 0.2
                        future_car.time += time
                        displacement = future_car.velocity * time if norm(future_car.velocity) > 500\
                            else normalize(future_car.velocity) * 500 * time
                        future_car.position += displacement

                        # simulate aerial fot the extrapolated car again
                        future_simulated_car = self.simulate_flight(
                            future_car, write_to_flight_path=False)

                        # if the aerial is also successful, that means we should continue driving instead of taking off
                        # this makes sure that we go for the most late possible aerials, which are the most effective
                        if distance(
                                future_simulated_car,
                                self.aerial.target) > self.MAX_DISTANCE_ERROR:
                            self.aerialing = True
                        else:
                            self.too_early = True
                    else:
                        self.aerialing = True

            else:
                # self.controls.boost = True
                self.controls.throttle = 1

    def render(self, draw: DrawingTool):
        super().render(draw)
        draw.color(draw.lime if self.aerialing else (
            draw.orange if self.too_early else draw.red))
        draw.polyline(self._flight_path)
コード例 #7
0
ファイル: States.py プロジェクト: meckern/RLBotPack
class AerialHandler():
    def __init__(self, agent):
        self.agent = agent
        self.active = False
        self.timer = time.time()
        self.setup()
        self.threshold = 300

    def setup(self):
        self.aerial = Aerial(self.agent.game.my_car)
        self.turn = AerialTurn(self.agent.game.my_car)
        myGoal = center = Vector([0, 5120 * sign(self.agent.team), 200])
        enemyGoal = center = Vector([0, 5120 * -sign(self.agent.team), 200])
        aboveThreshold = False

        if self.agent.me.boostLevel > 0:
            for i in range(0, self.agent.ballPred.num_slices):
                targetVec = Vector([
                    self.agent.ballPred.slices[i].physics.location.x,
                    self.agent.ballPred.slices[i].physics.location.y,
                    self.agent.ballPred.slices[i].physics.location.z
                ])

                if self.agent.ballPred.slices[i].physics.location.z >= 300:
                    if not aboveThreshold:
                        aboveThreshold = True
                    goalDist = distance2D(center, targetVec)
                    acceptable = False
                    if self.agent.team == 0:
                        if self.agent.me.location[1] < targetVec[1]:
                            acceptable = True
                    else:
                        if self.agent.me.location[1] > targetVec[1]:
                            acceptable = True

                    if acceptable:
                        zOffset = -10
                        if goalDist < 1500:
                            if targetVec[2] > 600:
                                zOffset = 70
                        shotAngle = correctAngle(
                            math.degrees(angle2(targetVec, enemyGoal)) +
                            90 * -sign(self.agent.team))

                        if self.agent.team == 0:
                            if targetVec[1] >= 0:
                                if abs(targetVec[0]) > 893:
                                    if targetVec[0] > 0:
                                        closePost = Vector([
                                            893, 5120 * -sign(self.agent.team),
                                            200
                                        ])
                                    else:
                                        closePost = Vector([
                                            -893,
                                            5120 * -sign(self.agent.team), 200
                                        ])

                                    attackAngle = correctAngle(
                                        math.degrees(
                                            angle2(targetVec, closePost)) +
                                        90 * -sign(self.agent.team))

                                    targetLocal = toLocal(
                                        Vector([
                                            self.agent.ballPred.slices[i].
                                            physics.location.x,
                                            self.agent.ballPred.slices[i].
                                            physics.location.y,
                                            self.agent.ballPred.slices[i].
                                            physics.location.z
                                        ]), self.agent.me)
                                    carToBallAngle = correctAngle(
                                        math.degrees(
                                            math.atan2(targetLocal[1],
                                                       targetLocal[0])))
                                    totalAngle = correctAngle(
                                        math.degrees(
                                            math.tan(attackAngle) +
                                            math.tan(carToBallAngle) /
                                            (1 - (math.tan(attackAngle) *
                                                  math.tan(carToBallAngle)))))

                                    if abs(totalAngle) > 60:
                                        continue

                        elif self.agent.team == 1:
                            if targetVec[1] <= 0:
                                if abs(targetVec[0]) > 893:
                                    if targetVec[0] > 0:
                                        closePost = Vector([
                                            893, 5120 * -sign(self.agent.team),
                                            200
                                        ])
                                    else:
                                        closePost = Vector([
                                            -893,
                                            5120 * -sign(self.agent.team), 200
                                        ])

                                    attackAngle = correctAngle(
                                        math.degrees(
                                            angle2(targetVec, closePost)) +
                                        90 * -sign(self.agent.team))

                                    targetLocal = toLocal(
                                        Vector([
                                            self.agent.ballPred.slices[i].
                                            physics.location.x,
                                            self.agent.ballPred.slices[i].
                                            physics.location.y,
                                            self.agent.ballPred.slices[i].
                                            physics.location.z
                                        ]), self.agent.me)
                                    carToBallAngle = correctAngle(
                                        math.degrees(
                                            math.atan2(targetLocal[1],
                                                       targetLocal[0])))

                                    totalAngle = correctAngle(carToBallAngle +
                                                              attackAngle)

                                    if abs(totalAngle) > 60:
                                        continue

                        if abs(shotAngle) <= 75:

                            xOffset = clamp(80, -80, (shotAngle * 2) *
                                            -sign(self.agent.team))
                            self.aerial.target = vec3(
                                self.agent.ballPred.slices[i].physics.location.
                                x + xOffset, self.agent.ballPred.slices[i].
                                physics.location.y, self.agent.ballPred.
                                slices[i].physics.location.z + zOffset)

                            self.aerial.arrival_time = self.agent.ballPred.slices[
                                i].game_seconds

                            simulation = self.aerial.simulate()
                            if norm(simulation.location -
                                    self.aerial.target) < 100:

                                self.target_ball = self.agent.ballPred.slices[
                                    i]
                                self.xOffset = xOffset
                                self.zOffset = zOffset
                                self.active = True
                                if self.agent.onSurface:
                                    if self.agent.ballPred.slices[
                                            i].physics.location.z >= 400:
                                        targetLocal = toLocal(
                                            Vector([
                                                self.agent.ballPred.slices[i].
                                                physics.location.x + xOffset,
                                                self.agent.ballPred.slices[i].
                                                physics.location.y,
                                                self.agent.ballPred.slices[i].
                                                physics.location.z + zOffset
                                            ]), self.agent.me)

                                        carToBallAngle = correctAngle(
                                            math.degrees(
                                                math.atan2(
                                                    targetLocal[1],
                                                    targetLocal[0])))
                                        if abs(carToBallAngle) < 45:
                                            if distance2D(
                                                    self.agent.me.location,
                                                    targetLocal) > 1500:
                                                if self.agent.ballPred.slices[
                                                        i].physics.location.z >= 900:
                                                    self.agent.activeState = airLaunch(
                                                        self.agent)
                                                    self.active = False
                                                    return self.agent.activeState.update(
                                                    )
                                break

                else:
                    if aboveThreshold:
                        break

    def stillValid(self):
        for i in range(0, self.agent.ballPred.num_slices):
            if self.agent.ballPred.slices[i].physics.location.z >= 300:
                if abs(self.target_ball.game_seconds -
                       self.agent.ballPred.slices[i].game_seconds
                       ) < self.agent.deltaTime * 3:
                    difference = 0
                    difference += abs(
                        (self.agent.ballPred.slices[i].physics.location.x +
                         self.xOffset) -
                        (self.target_ball.physics.location.x + self.zOffset))
                    difference += abs(
                        self.agent.ballPred.slices[i].physics.location.y -
                        self.target_ball.physics.location.y)
                    difference += abs(
                        (self.agent.ballPred.slices[i].physics.location.z +
                         self.zOffset) -
                        (self.target_ball.physics.location.z + self.zOffset))
                    if difference < 10:
                        self.aerial.target = vec3(
                            self.agent.ballPred.slices[i].physics.location.x +
                            self.xOffset,
                            self.agent.ballPred.slices[i].physics.location.y,
                            self.agent.ballPred.slices[i].physics.location.z +
                            self.zOffset)

                        self.aerial.arrival_time = self.agent.ballPred.slices[
                            i].game_seconds
                        self.target_ball = self.agent.ballPred.slices[i]

                        simulation = self.aerial.simulate()
                        return

        self.active = False
        self.setup()

    def update(self):
        if self.agent.me.boostLevel > 0:
            self.setup()
            self.aerial.step(self.agent.deltaTime)
            self.controls = self.aerial.controls
            self.controls.jump = True
            if self.aerial.finished:
                self.active = False
        else:
            self.active = False
        if time.time() - self.timer > 0.5:
            if self.agent.onSurface:
                self.active = False
        return self.controls
コード例 #8
0
ファイル: agent.py プロジェクト: samuelpmish/RLUtilities
class Agent(BaseAgent):

    def __init__(self, name, team, index):
        Game.set_mode("soccar")
        self.game = Game(index, team)
        self.controls = SimpleControllerState()

        self.timer = 0.0
        self.timeout = 5.0

        self.aerial = None
        self.turn = None
        self.state = State.RESET
        self.ball_predictions = None

        self.target_ball = None
        self.log = open("../../analysis/aerial/info.ndjson", "w")

    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

            b_position = Vector3(random.uniform(-1500,  1500),
                                 random.uniform( 2500,  3500),
                                 random.uniform(  300,   500))

            b_velocity = Vector3(random.uniform(-300,  300),
                                 random.uniform(-100,  100),
                                 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)
            ))

            # this just initializes the car and ball
            # to different starting points each time
            c_position = Vector3(b_position.x, 0 * random.uniform(-1500, -1000), 25)

            #c_position = Vector3(200, -1000, 25)
            car_state = CarState(physics=Physics(
                location=c_position,
                velocity=Vector3(0, 800, 0),
                rotation=Rotator(0, 1.6, 0),
                angular_velocity=Vector3(0, 0, 0)
            ), boost_amount=100)

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

            next_state = State.WAIT

        if self.state == State.WAIT:

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

        if self.state == State.INITIALIZE:

            self.aerial = Aerial(self.game.my_car)
            # self.aerial.up = normalize(vec3(
            #     random.uniform(-1, 1),
            #     random.uniform(-1, 1),
            #     random.uniform(-1, 1)))
            self.turn = AerialTurn(self.game.my_car)

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

            for i in range(100):

                prediction.step(0.016666)
                prediction.step(0.016666)
                self.ball_predictions.append(vec3(prediction.location))

                # if the ball is in the air
                if prediction.location[2] > 500:

                    self.aerial.target = prediction.location
                    self.aerial.arrival_time = prediction.time

                    simulation = self.aerial.simulate()

                    # # check if we can reach it by an aerial
                    if norm(simulation.location - self.aerial.target) < 100:
                        prediction.step(0.016666)
                        prediction.step(0.016666)
                        self.aerial.target = prediction.location
                        self.aerial.arrival_time = prediction.time
                        self.target_ball = Ball(prediction)
                        break


            next_state = State.RUNNING

        if self.state == State.RUNNING:

            self.log.write(f"{{\"car\":{self.game.my_car.to_json()},"
                           f"\"ball\":{self.game.ball.to_json()}}}\n")

            self.aerial.step(self.game.time_delta)
            self.controls = self.aerial.controls

            if self.timer > self.timeout:
                next_state = State.RESET

                self.aerial = None
                self.turn = None

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

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

        if self.aerial:
            r = 200
            x = vec3(r, 0, 0)
            y = vec3(0, r, 0)
            z = vec3(0, 0, r)
            target = self.aerial.target

            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)

        if self.ball_predictions:
            self.renderer.draw_polyline_3d(self.ball_predictions, purple)

        self.renderer.end_rendering()

        return self.controls
コード例 #9
0
ファイル: aerial_strike.py プロジェクト: Darxeal/BotimusPrime
class AerialStrike(Strike):
    MAX_DISTANCE_ERROR = 50
    DELAY_TAKEOFF = True
    MINIMAL_HEIGHT = 500
    MAXIMAL_HEIGHT = 800
    MINIMAL_HEIGHT_TIME = 0.8
    MAXIMAL_HEIGHT_TIME = 1.5
    DOUBLE_JUMP = False

    def __init__(self, car: Car, info: GameInfo, target: vec3 = None):
        self.aerial = Aerial(car)
        self.aerial.angle_threshold = 0.8
        self.aerial.double_jump = self.DOUBLE_JUMP
        super().__init__(car, info, target)
        self.arrive.allow_dodges_and_wavedashes = False

        self.aerialing = False
        self.too_early = False
        self._flight_path: List[vec3] = []

    def intercept_predicate(self, car: Car, ball: Ball):
        required_time = range_map(ball.position[2], self.MINIMAL_HEIGHT,
                                  self.MAXIMAL_HEIGHT,
                                  self.MINIMAL_HEIGHT_TIME,
                                  self.MAXIMAL_HEIGHT_TIME)
        return self.MINIMAL_HEIGHT < ball.position[
            2] < self.MAXIMAL_HEIGHT and ball.time - car.time > required_time

    def configure(self, intercept: Intercept):
        super().configure(intercept)
        self.aerial.target_position = intercept.position - direction(
            intercept, self.target) * 100
        self.aerial.up = normalize(
            ground_direction(intercept, self.car) + vec3(0, 0, 0.5))
        self.aerial.arrival_time = intercept.time

    @staticmethod
    def simulate_flight(car: Car,
                        aerial: Aerial,
                        flight_path: List[vec3] = None) -> Car:
        test_car = Car(car)
        test_aerial = Aerial(test_car)
        test_aerial.target_position = aerial.target_position
        test_aerial.arrival_time = aerial.arrival_time
        test_aerial.angle_threshold = aerial.angle_threshold
        test_aerial.up = aerial.up
        test_aerial.double_jump = aerial.double_jump

        if flight_path: flight_path.clear()

        while not test_aerial.finished:
            test_aerial.step(1 / 120)
            test_car.boost = 100  # TODO: fix boost depletion in RLU car sim
            test_car.step(test_aerial.controls, 1 / 120)

            if flight_path:
                flight_path.append(vec3(test_car.position))

        return test_car

    def interruptible(self) -> bool:
        return self.aerialing or super().interruptible()

    def step(self, dt):
        time_left = self.aerial.arrival_time - self.car.time

        if self.aerialing:
            to_ball = direction(self.car, self.info.ball)

            # freestyling
            if self.car.position[2] > 200:
                # if time_left > 0.7:
                #     rotation = axis_to_rotation(self.car.forward() * 0.5)
                #     self.aerial.up = dot(rotation, self.car.up())
                # else:
                self.aerial.up = vec3(0, 0, -1) + xy(to_ball)

            self.aerial.target_orientation = look_at(to_ball,
                                                     vec3(0, 0, -3) + to_ball)
            self.aerial.step(dt)

            self.controls = self.aerial.controls
            self.finished = self.aerial.finished and time_left < -0.3

        else:
            super().step(dt)

            # simulate aerial from current state
            simulated_car = self.simulate_flight(self.car, self.aerial,
                                                 self._flight_path)

            speed_towards_target = dot(
                self.car.velocity,
                ground_direction(self.car, self.aerial.target_position))
            speed_needed = ground_distance(
                self.car, self.aerial.target_position) / time_left

            # too fast, slow down
            if speed_towards_target > speed_needed and angle_to(
                    self.car, self.aerial.target_position) < 0.1:
                self.controls.throttle = -1

            # if it ended up near the target, we could take off
            elif distance(
                    simulated_car,
                    self.aerial.target_position) < self.MAX_DISTANCE_ERROR:
                if angle_to(self.car,
                            self.aerial.target_position) < 0.1 or norm(
                                self.car.velocity) < 1000:

                    if self.DELAY_TAKEOFF and ground_distance(
                            self.car, self.aerial.target_position) > 1000:
                        # extrapolate current state a small amount of time
                        future_car = Car(self.car)
                        time = 0.5
                        future_car.time += time
                        displacement = future_car.velocity * time if norm(future_car.velocity) > 500\
                            else normalize(future_car.velocity) * 500 * time
                        future_car.position += displacement

                        # simulate aerial fot the extrapolated car again
                        future_simulated_car = self.simulate_flight(
                            future_car, self.aerial)

                        # if the aerial is also successful, that means we should continue driving instead of taking off
                        # this makes sure that we go for the most late possible aerials, which are the most effective
                        if distance(future_simulated_car, self.aerial.
                                    target_position) > self.MAX_DISTANCE_ERROR:
                            self.aerialing = True
                        else:
                            self.too_early = True
                    else:
                        self.aerialing = True

            else:
                # self.controls.boost = True
                self.controls.throttle = 1

    def render(self, draw: DrawingTool):
        super().render(draw)
        draw.color(draw.lime if self.aerialing else (
            draw.orange if self.too_early else draw.red))
        draw.polyline(self._flight_path)
コード例 #10
0
class AerialHandler():
    def __init__(self,agent):
        self.agent = agent
        self.active = False
        self.setup()

    def setup(self):
        self.aerial = Aerial(self.agent.game.my_car)
        self.turn = AerialTurn(self.agent.game.my_car)
        myGoal = center = Vector([0, 5200 * sign(self.agent.team), 200])
        enemyGoal = center = Vector([0, 5200 * -sign(self.agent.team), 200])
        if self.agent.me.boostLevel > 0:
            for i in range(0, self.agent.ballPred.num_slices):
                targetVec = Vector([self.agent.ballPred.slices[i].physics.location.x,
                                    self.agent.ballPred.slices[i].physics.location.y,
                                    self.agent.ballPred.slices[i].physics.location.z])
                # interferenceTimer += self.agent.deltaTime
                # if interferenceTimer < 1:
                #     if findEnemyClosestToLocation(self.agent,targetVec)[1] < 150:
                #         break
                if self.agent.ballPred.slices[i].physics.location.z >= 300:
                    goalDist = distance2D(center, targetVec)
                    #if distance2D(myGoal, targetVec) > distance2D(myGoal, self.agent.me.location):
                    if self.agent.me.location[1] * sign(self.agent.team) > self.agent.ballPred.slices[i].physics.location.y * sign(self.agent.team):
                        zOffset = 0
                        if goalDist < 1500:
                            if targetVec[2] > 600:
                                zOffset = 70
                        shotAngle = correctAngle(math.degrees(angle2(targetVec, enemyGoal)) + 90 * -sign(self.agent.team))


                        if abs(shotAngle) <=80:
                            xOffset = clamp(80,-80,(shotAngle*2)*-sign(self.agent.team))
                            self.aerial.target = vec3(self.agent.ballPred.slices[i].physics.location.x+xOffset,
                                                      self.agent.ballPred.slices[i].physics.location.y,
                                                      self.agent.ballPred.slices[i].physics.location.z+zOffset)

                            self.aerial.arrival_time = self.agent.ballPred.slices[i].game_seconds

                            simulation = self.aerial.simulate()

                            # # check if we can reach it by an aerial
                            if norm(simulation.location - self.aerial.target) < 100:
                                self.target_ball = self.agent.ballPred.slices[i]
                                self.xOffset = xOffset
                                self.zOffset = zOffset
                                self.active = True
                                break

    def stillValid(self):
        for i in range(0, self.agent.ballPred.num_slices):
            if self.agent.ballPred.slices[i].physics.location.z >= 300:
                if abs(self.target_ball.game_seconds - self.agent.ballPred.slices[i].game_seconds) < self.agent.deltaTime*3:
                    difference = 0
                    difference+= abs((self.agent.ballPred.slices[i].physics.location.x+self.xOffset) - (self.target_ball.physics.location.x+self.zOffset))
                    difference += abs(self.agent.ballPred.slices[i].physics.location.y - self.target_ball.physics.location.y)
                    difference += abs((self.agent.ballPred.slices[i].physics.location.z+self.zOffset) - (self.target_ball.physics.location.z+self.zOffset))
                    if difference < 10:
                        self.aerial.target = vec3(self.agent.ballPred.slices[i].physics.location.x + self.xOffset,
                                                  self.agent.ballPred.slices[i].physics.location.y,
                                                  self.agent.ballPred.slices[i].physics.location.z + self.zOffset)

                        self.aerial.arrival_time = self.agent.ballPred.slices[i].game_seconds
                        self.target_ball = self.agent.ballPred.slices[i]

                        simulation = self.aerial.simulate()
                        return

        self.active = False
        self.setup()

    def update(self):
        if self.agent.me.boostLevel > 0:
            self.setup()
            self.aerial.step(self.agent.deltaTime)
            self.controls = self.aerial.controls
            self.controls.jump = True
            if self.aerial.finished:
                self.active = False
        else:
            self.active = False
        return self.controls