コード例 #1
0
ファイル: game_info.py プロジェクト: Supersilver10/RLBotPack
    def predict_ball(self, duration=5.0, dt=1 / 120):
        self.about_to_score = False
        self.about_to_be_scored_on = False
        self.time_of_goal = -1

        self.ball_predictions = []
        prediction = Ball(self.ball)

        # nearest_opponent = Car(min(self.get_opponents(), key=lambda opponent: distance(opponent, prediction)))

        while prediction.time < self.time + duration:
            # if prediction.time < self.time + 1.0:
            #     nearest_opponent.step(Input(), dt)
            #     nearest_opponent.velocity[2] = 0
            #     prediction.step(dt, nearest_opponent)
            # else:
            prediction.step(dt)
            self.ball_predictions.append(Ball(prediction))

            if self.time_of_goal == -1:
                if self.my_goal.inside(prediction.position):
                    self.about_to_be_scored_on = True
                    self.time_of_goal = prediction.time
                if self.their_goal.inside(prediction.position):
                    self.about_to_score = True
                    self.time_of_goal = prediction.time
コード例 #2
0
def get_closest_point_on_trajectory(b: Ball, target: vec3):
    closest = vec3(target)
    while True:
        b.step(1.0 / 120.0)
        if abs(veclen(target - b.location)) > abs(veclen(target - closest)):
            return closest
        closest = vec3(b.location)
コード例 #3
0
    def step(self, dt):
        ball = Ball(self.ball)
        car = self.car

        # simulate ball until it gets near the floor
        while (ball.position[2] > 120 or ball.velocity[2] > 0) and ball.time < car.time + 10:
            ball.step(1/60)

        ball_local = local(car, ground(ball.position))
        target = local(car, self.target)

        shift = ground(direction(ball_local, target))
        shift[1] *= 1.8
        shift = normalize(shift)
        
        max_turn = clamp(norm(car.velocity) / 800, 0, 1)
        max_shift = normalize(vec3(1 - max_turn, max_turn * sign(shift[1]), 0))

        if abs(shift[1]) > abs(max_shift[1]) or shift[0] < 0:
            shift = max_shift
        shift *= clamp(car.boost, 40, 60)

        shift[1] *= clamp(norm(car.velocity)/1000, 1, 2)

        self._shift_direction = normalize(world(car, shift) - car.position)

        target = world(car, ball_local - shift)
        speed = distance(car.position, target) / max(0.001, ball.time - car.time)

        self.drive.target_speed = speed
        self.drive.target_pos = target

        self.drive.step(dt)
        self.controls = self.drive.controls
        self.finished = self.ball.position[2] < 100 or ground_distance(self.ball, self.car) > 2000
コード例 #4
0
    def simulate(self, bot) -> vec3:
        # print('simulate intercept')

        # Init vars
        c = Car(bot.game.my_car)
        b = Ball(bot.game.ball)
        t = vec3(bot.target)
        intercept = self.location
        dt = 1.0 / 60.0
        hit = False
        min_error = None

        # Drive towards intercept (moving in direction of c.forward())
        c.rotation = look_at(intercept, c.up())
        direction = normalize(intercept - c.location)  #c.forward()
        advance_distance = norm(intercept - c.location) - c.hitbox(
        ).half_width[0] - b.collision_radius
        translation = direction * advance_distance
        sim_start_state: ThrottleFrame = BoostAnalysis().travel_distance(
            advance_distance, norm(c.velocity))
        c.velocity = direction * sim_start_state.speed
        c.location += translation
        c.time += sim_start_state.time
        bot.ball_predictions = [vec3(b.location)]

        while b.time < c.time:
            b.step(dt)
            bot.ball_predictions.append(vec3(b.location))

        # print(c.time, b.time)
        # print(c.location, b.location)

        # Simulate the collision and resulting
        for i in range(60 * 3):
            c.location += c.velocity * dt
            b.step(dt, c)

            # Check if we hit the ball yet
            if norm(b.location - c.location) < (c.hitbox().half_width[0] +
                                                b.collision_radius) * 1.05:
                hit = True
                # print('hit')

            # Measure dist from target
            error = t - b.location
            if hit and (min_error == None or norm(error) < norm(min_error)):
                min_error = error

            # Record trajectory
            bot.ball_predictions.append(vec3(b.location))

        if not hit: return None
        return min_error
コード例 #5
0
ファイル: hit.py プロジェクト: twobackfromtheend/carball
def get_hit_frame_numbers(df: pd.DataFrame):
    ball_df = df[DF_BALL_PREFIX]

    hit_frame_numbers = get_hit_frame_numbers_by_ball_ang_vel(df)
    # Filter by hit_team_no
    hit_frame_numbers = ball_df.loc[hit_frame_numbers].index[~ball_df.loc[
        hit_frame_numbers, "hit_team_no"].isna()].tolist()
    logger.info(f"hit: {hit_frame_numbers}")

    delta_df = df.loc[:, (DF_GAME_PREFIX, 'delta')]
    RLUGame.set_mode("soccar")
    filtered_hit_frame_numbers = []
    for frame_number in hit_frame_numbers:
        previous_frame_number = frame_number - 1
        ball_previous_frame = ball_df.loc[previous_frame_number, :]
        initial_ang_vel = ball_previous_frame.loc[[
            'ang_vel_x', 'ang_vel_y', 'ang_vel_z'
        ]].values

        ball = Ball()
        # noinspection PyPropertyAccess
        ball.location = vec3(
            *ball_previous_frame.loc[['pos_x', 'pos_y', 'pos_z']])
        # noinspection PyPropertyAccess
        ball.velocity = vec3(
            *ball_previous_frame.loc[['vel_x', 'vel_y', 'vel_z']])
        # noinspection PyPropertyAccess
        ball.angular_velocity = vec3(*initial_ang_vel)

        frame_delta = delta_df[frame_number]
        delta_simulated = 0
        while delta_simulated < frame_delta:
            dt = 1 / 120
            time_to_simulate = min(dt, frame_delta - delta_simulated)
            ball.step(time_to_simulate)
            delta_simulated += time_to_simulate

        simulated_ball_ang_vel = np.array([
            ball.angular_velocity[0], ball.angular_velocity[1],
            ball.angular_velocity[2]
        ])
        actual_ball_ang_vel = ball_df.loc[
            frame_number, ['ang_vel_x', 'ang_vel_y', 'ang_vel_z']].values
        actual_ang_vel_change = ((actual_ball_ang_vel -
                                  initial_ang_vel)**2).sum()**0.5
        end_ang_vel_difference = ((simulated_ball_ang_vel -
                                   actual_ball_ang_vel)**2).sum()**0.5

        relative_ang_vel_difference = end_ang_vel_difference / actual_ang_vel_change
        if relative_ang_vel_difference > 0.8:
            filtered_hit_frame_numbers.append(frame_number)
    return filtered_hit_frame_numbers
コード例 #6
0
ファイル: game_info.py プロジェクト: azeemba/RLBotPack
    def predict_ball(self, time_limit=6.0, dt=1 / 120):
        self.about_to_score = False
        self.about_to_be_scored_on = False
        self.time_of_goal = -1

        self.ball_predictions = []
        prediction = Ball(self.ball)

        while prediction.time < self.ball.time + time_limit:
            prediction.step(dt)
            self.ball_predictions.append(Ball(prediction))

            if self.time_of_goal == -1:
                if self.my_goal.inside(prediction.position):
                    self.about_to_be_scored_on = True
                    self.time_of_goal = prediction.time
                if self.their_goal.inside(prediction.position):
                    self.about_to_score = True
                    self.time_of_goal = prediction.time
コード例 #7
0
    def predict_ball(self, num_steps, dt):

        self.about_to_score = False
        self.about_to_be_scored_on = False
        self.time_of_goal = -1

        self.ball_predictions = []
        prediction = Ball(self.ball)

        for _ in range(0, num_steps):
            prediction.step(dt)
            self.ball_predictions.append(Ball(prediction))

            if self.time_of_goal == -1:
                if self.my_goal.inside(prediction.position):
                    self.about_to_be_scored_on = True
                    self.time_of_goal = prediction.time
                if self.their_goal.inside(prediction.position):
                    self.about_to_score = True
                    self.time_of_goal = prediction.time
コード例 #8
0
ファイル: agent.py プロジェクト: samuelpmish/RLUtilities
    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:
        self.game.read_game_information(packet, self.get_rigid_body_tick(), self.get_field_info())

        # make a copy of the ball's info that we can change
        b = Ball(self.game.ball)

        ball_predictions = []
        for i in range(360):

            # simulate the forces acting on the ball for 1 frame
            b.step(1.0 / 120.0)

            # and add a copy of new ball position to the list of predictions
            ball_predictions.append(vec3(b.location))

        self.renderer.begin_rendering()
        red = self.renderer.create_color(255, 255, 30, 30)
        self.renderer.draw_polyline_3d(ball_predictions, red)
        self.renderer.end_rendering()

        return controller.get_output()
コード例 #9
0
ファイル: shots.py プロジェクト: twobackfromtheend/carball
def set_shots(hits_by_goal_number: Dict[int, Hit], game: Game,
              df: pd.DataFrame):
    ball_df = df[DF_BALL_PREFIX]
    player_id_to_team = {
        player.id.id: player.is_orange
        for player in game.players
    }

    for hits_list in hits_by_goal_number.values():
        for hit in hits_list:
            direction_factor = -1**player_id_to_team[
                hit.player_id.id]  # -1 if orange, 1 if blue
            ball_data = ball_df.loc[hit.frame_number]

            ball = Ball()
            # noinspection PyPropertyAccess
            ball_location = ball_data.loc[['pos_x', 'pos_y', 'pos_z']]
            ball.location = vec3(*ball_location)
            # noinspection PyPropertyAccess
            ball_velocity = ball_data.loc[['vel_x', 'vel_y', 'vel_z']]
            ball.velocity = vec3(*ball_velocity)
            # noinspection PyPropertyAccess
            ball_angular_velocity = ball_data.loc[[
                'ang_vel_x', 'ang_vel_y', 'ang_vel_z'
            ]]
            ball.angular_velocity = vec3(*ball_angular_velocity)

            delta_simulated = 0
            while delta_simulated < SHOT_SECONDS_SIMULATED:
                dt = 1 / 120
                ball.step(min(dt, SHOT_SECONDS_SIMULATED - delta_simulated))
                delta_simulated += dt

                ball_y = ball.location[1]
                if ball_y * direction_factor > FIELD_Y_LIM:
                    hit.shot = True
                    break
コード例 #10
0
ファイル: agent.py プロジェクト: samuelpmish/RLUtilities
    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
コード例 #11
0
c = Car()

c.location = vec3(-164.13, 0, 88.79)
c.velocity = vec3(1835.87, 0, 372.271)
c.angular_velocity = vec3(0, 3.78721, 0)
c.rotation = mat3(0.9983, -5.23521e-6, 0.0582877, 5.5498e-6, 1.0, -5.23521e-6,
                  -0.0582877, 5.5498e-6, 0.9983)

b = Ball()

b.location = vec3(0, 0, 150)
b.velocity = vec3(0, 0, 0)
b.angular_velocity = vec3(0, 0, 0)

print("before:")
print(b.location)
print(b.velocity)
print(b.angular_velocity)
print("overlapping: ", intersect(c.hitbox(), b.hitbox()))

print()

b.step(0.008333, c)

print("after:")
print(b.location)
print(b.velocity)
print(b.angular_velocity)
print("overlapping: ", intersect(c.hitbox(), b.hitbox()))
コード例 #12
0
    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:

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

        self.controls = SimpleControllerState()

        next_state = self.state

        # Reset everything
        if self.state == State.RESET:
            self.timer = 0.0
            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 + 200 * normalize(
                vec3(vec2(self.game.ball.position - vec3(0, 5120, 0))))
            self.drive.speed = 1400
            next_state = State.DRIVING

        # Start driving towards the target and check whether an aerial is possible, if so initialize the dodge
        if self.state == State.DRIVING:
            self.drive.target = self.game.ball.position + 200 * normalize(
                vec3(vec2(self.game.ball.position - vec3(0, 5120, 0))))
            self.drive.step(self.game.time_delta)
            self.controls = self.drive.controls

            # Initialize the aerial and aerial turn
            self.aerial = Aerial(self.game.my_car)
            self.turn = AerialTurn(self.game.my_car)

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

            # Loop over 87 frames which results in a time limit of 1.45
            # Seeing we jump once and hold it for 0.2s we keep our second dodge until that moment
            a = time.time()
            for i in range(87):
                # Step the ball prediction and add it to the array for rendering
                prediction.step(0.016666)
                self.ball_predictions.append(vec3(prediction.location))
                # TODO dont hardcode the goal vector!
                # Set the target to a slight offset of the ball so we will hit it towards the target or goal
                # Set the arrival time to the time the ball will be in that location
                # Set the preorientation so we will look at the goal
                goal = vec3(0, 5120, 0)
                # self.aerial.target = prediction.location + 200 * normalize(prediction.location - goal)
                self.aerial.target = vec3(
                    0, 0, ball_z) + 200 * normalize(prediction.location - goal)
                self.aerial.arrival_time = prediction.time
                print(prediction.time)
                # self.aerial.target_rotation = look_at(goal - self.aerial.target, vec3(0, 0, 1))
                self.aerial.target_rotation = look_at(
                    goal - self.game.my_car.position, vec3(0, 0, 1))
                # Simulate the aerial and see whether its doable or not
                simulation = self.aerial.simulate
                # # check if we can reach it by an aerial
                if norm(simulation.location -
                        self.aerial.target) < 100 and angle_between(
                            simulation.rotation,
                            self.aerial.target_rotation) < 0.01:
                    print(i)
                    print(prediction.location)
                    print(self.game.my_car.orientation)
                    print("predicted rotation")
                    print(simulation.rotation)
                    next_state = State.RUNNING
                    break
            print("time:")
            print(time.time() - a)

        # Perform the aerial mechanic
        if self.state == State.RUNNING:
            self.aerial.step(self.game.time_delta)
            self.controls = self.aerial.controls
            if self.game.time == packet.game_ball.latest_touch.time_seconds:
                print(self.game.my_car.double_jumped)
                self.controls.jump = True
                print("actual rotation")
                print(self.game.my_car.orientation)
            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

        # Render the target for the aerial
        self.renderer.begin_rendering()
        purple = self.renderer.create_color(255, 230, 30, 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)
            # self.renderer.draw_line_3d(self.game.my_car.position,
            #                            1000 * dot(self.aerial.target_rotation, self.game.my_car.forward()), purple)

        # Render ball prediction
        if self.ball_predictions:
            self.renderer.draw_polyline_3d(self.ball_predictions, purple)

        self.renderer.end_rendering()

        return self.controls
コード例 #13
0
    def calculate(car: Car, ball: Ball, target: vec3, ball_predictions=None):
        # Init vars
        b = Ball(ball)
        dt = 1.0 / 60.0

        # Generate predictions of ball path
        if ball_predictions is None:
            ball_predictions = []
            for i in range(60 * 5):
                b.step(dt)
                ball_predictions.append(vec3(b.location))

        # Gradually converge on ball location by aiming at a location, checking time to that location,
        # and then aiming at the ball's NEW position. Guaranteed to converge (typically in <10 iterations)
        # unless the ball is moving away from the car faster than the car's max boost speed
        intercept = Intercept(b.location)
        intercept.purpose = 'ball'
        intercept.boost = True
        intercept_ball_position = vec3(b.location)
        collision_achieved = False
        last_horizontal_error = None
        last_horizontal_offset = None
        i = 0
        max_tries = 101
        analyzer = BoostAnalysis() if intercept.boost else ThrottleAnalysis()
        while i < max_tries:
            i += 1
            fake_car = Car(car)
            direction = normalize(intercept.location - car.location)
            fake_car.rotation = look_at(direction, fake_car.up())

            for t in range(60 * 5):
                # Step car location with throttle/boost analysis data
                # Not super efficient but POITROAE
                frame = analyzer.travel_time(dt, norm(fake_car.velocity))
                # print('in 1 frame I travel', frame.time, frame.distance, frame.speed)
                fake_car.location += direction * frame.distance
                fake_car.velocity = direction * frame.speed
                fake_car.time += dt
                ball_location = ball_predictions[t]

                # Check for collision
                p = closest_point_on_obb(fake_car.hitbox(), ball_location)
                if norm(p - ball_location) <= ball.collision_radius:
                    direction_vector = p - (fake_car.location - normalize(
                        fake_car.forward()) * 13.88)  # octane center of mass
                    direction_vector[2] = 0
                    target_direction_vector = target - ball_location
                    target_direction_vector[2] = 0
                    intercept_ball_position = ball_location
                    direction = atan2(direction_vector[1], direction_vector[0])
                    ideal_direction = atan2(target_direction_vector[1],
                                            target_direction_vector[0])
                    horizontal_error = direction - ideal_direction

                    # intercept.location = vec3(ball_location)
                    # intercept.time = fake_car.time
                    # return intercept

                    # Now descend the hit direction gradient
                    # Kick off the gradient descent with an arbitrary seed value
                    if last_horizontal_error is None:
                        last_horizontal_error = horizontal_error
                        last_horizontal_offset = 0
                        if horizontal_error > 0:
                            horizontal_offset = 25
                        else:
                            horizontal_offset = 25
                        intercept.location = ball_location - normalize(
                            fake_car.left()) * horizontal_offset
                        break

                    # Recursive case of gradient descent
                    if horizontal_offset == last_horizontal_offset:
                        gradient = 0
                    else:
                        gradient = (horizontal_error - last_horizontal_error
                                    ) / (horizontal_offset -
                                         last_horizontal_offset)

                    if gradient == 0:
                        predicted_horizontal_offset = horizontal_offset
                    else:
                        predicted_horizontal_offset = horizontal_offset - horizontal_error / gradient

                    # Base case (convergence)
                    if abs(gradient) < 0.0005:
                        print(f'convergence in {i} iterations')
                        print(f'gradient = {gradient}')
                        print(
                            f'last_horizontal_offset = {last_horizontal_offset}'
                        )
                        print(f'direction = {degrees(direction)}')
                        print(f'ideal direction = {degrees(ideal_direction)}')
                        print(f'target = {target}')
                        print(f'ball_location = {ball_location}')
                        return intercept

                    # Edge case exit: offset maxed out
                    max_horizontal_offset = car.hitbox(
                    ).half_width[1] + ball.collision_radius
                    if predicted_horizontal_offset > max_horizontal_offset:
                        predicted_horizontal_offset = max_horizontal_offset
                    elif predicted_horizontal_offset < -max_horizontal_offset:
                        predicted_horizontal_offset = -max_horizontal_offset
                    last_horizontal_offset = horizontal_offset
                    last_horizontal_error = horizontal_error
                    horizontal_offset = predicted_horizontal_offset

                    # Return the latest intercept location and continue descending the gradient
                    intercept.location = ball_location - normalize(
                        fake_car.left()) * predicted_horizontal_offset
                    print(f'iteration {i}')
                    print(f'gradient = {gradient}')
                    print(f'horizontal_offset = {horizontal_offset}')
                    print(f'horizontal_error = {degrees(horizontal_error)}')
                    # print(f'ideal direction = {degrees(ideal_direction)}')
                    break

                # Check for arrival
                if norm(fake_car.location -
                        intercept.location) < ball.collision_radius / 2:
                    intercept.location = ball_location
                    break

        if i >= max_tries:
            print(
                f'Warning: max tries ({max_tries}) exceeded for calculating intercept'
            )
        return intercept
コード例 #14
0
    def calculate_old(car: Car,
                      ball: Ball,
                      target: vec3,
                      ball_predictions=None):
        # Init vars
        fake_car = Car(car)
        b = Ball(ball)

        # Generate predictions of ball path
        if ball_predictions is None:
            ball_predictions = [vec3(b.location)]
            for i in range(60 * 5):
                b.step(1.0 / 60.0)
                ball_predictions.append(vec3(b.location))

        # Gradually converge on ball location by aiming at a location, checking time to that location,
        # and then aiming at the ball's NEW position. Guaranteed to converge (typically in <10 iterations)
        # unless the ball is moving away from the car faster than the car's max boost speed
        intercept = Intercept(b.location)
        intercept.purpose = 'ball'
        intercept.boost = True
        intercept_ball_position = vec3(b.location)
        i = 0
        max_tries = 100
        analyzer = BoostAnalysis() if intercept.boost else ThrottleAnalysis()
        while i < max_tries:
            # Find optimal spot to hit the ball
            optimal_hit_vector = normalize(
                target - intercept_ball_position) * b.collision_radius
            optimal_hit_location = intercept_ball_position - optimal_hit_vector

            # Find ideal rotation, unless it intersects with ground
            optimal_rotation = look_at(
                optimal_hit_vector, vec3(0, 0, 1)
            )  #axis_to_rotation(optimal_hit_vector) # this might be wrong
            fake_car.rotation = optimal_rotation
            # print(f'fake_car.location {fake_car.location}')
            # print(f'get_car_front_center(fake_car) {get_car_front_center(fake_car)}')
            fake_car.location += optimal_hit_location - get_car_front_center(
                fake_car
            )  # try to position the car's front center directly on top of the best hit vector
            euler = rotation_to_euler(optimal_rotation)
            # todo put some super precise trigonometry in here to find the max angle allowed at given height
            if fake_car.location[2] <= fake_car.hitbox().half_width[0]:
                euler.pitch = 0
            fake_car.rotation = euler_to_rotation(
                vec3(euler.pitch, euler.yaw, euler.roll))
            fake_car.location += optimal_hit_location - get_car_front_center(
                fake_car
            )  # try to position the car's front center directly on top of the best hit vector

            # Adjust vertical position if it (still) intersects with ground
            if fake_car.location[2] < 17.0:
                fake_car.location[2] = 17.0
            intercept.location = get_car_front_center(fake_car)

            # Calculate jump time needed
            jump_height_time = JumpAnalysis().get_frame_by_height(
                intercept.location[2]).time  # or solve with motion equation

            # car_euler = rotation_to_euler(car.rotation)
            # jump_pitch_time = (euler.pitch - car_euler.pitch) / 5.5 + 0.35 # disregarding angular acceleration
            # jump_yaw_time = (euler.yaw - car_euler.yaw) / 5.5 + 0.35 # disregarding angular acceleration
            # jump_roll_time = (euler.roll - car_euler.roll) / 5.5 + 0.35 # disregarding angular acceleration
            # jump_time = max(jump_height_time, jump_pitch_time, jump_yaw_time, jump_roll_time)
            jump_time = jump_height_time  # todo revisit rotation time
            # print('jump_time', jump_time)

            # Calculate distance to drive before jumping (to arrive perfectly on target)
            total_translation = intercept.location - get_car_front_center(car)
            total_translation[2] = 0
            total_distance = norm(total_translation)
            start_index = analyzer.get_index_by_speed(norm(car.velocity))
            start_frame = analyzer.frames[start_index]
            custom_error_func = lambda frame: abs(total_distance - (
                frame.distance - start_frame.distance) - frame.speed *
                                                  jump_time)
            drive_analysis = analyzer.get_frame_by_error(
                custom_error_func, start_index)
            arrival_time = drive_analysis.time - start_frame.time + jump_time
            # print('drive_analysis.time', drive_analysis.time)
            # print('drive_analysis', start_index)

            # arrival_time = analyzer.travel_distance(total_distance, norm(car.velocity)).time

            # drive_analysis = analyzer.travel_distance(norm(intercept.location - c.location), norm(c.velocity))
            ball_index = int(round(arrival_time * 60))
            if ball_index >= len(ball_predictions):
                intercept.location = ball_predictions[-1]
                intercept.time = len(ball_predictions) / 60.0
                break
            ball_location = ball_predictions[ball_index]
            # print(f'Iteration {i} distance {norm(ball_location + vec3(optimal_hit_vector[0], optimal_hit_vector[1], 0) - intercept.location)}')
            if norm(ball_location - intercept_ball_position) <= 1:
                # if norm(intercept_ball_position - get_car_front_center(fake_car)) > 100:
                #     intercept.location = ball_predictions[-1]
                #     intercept.time = len(ball_predictions) / 60.0
                #     return intercept

                intercept.dodge = True  #jump_time > 0.2
                intercept.jump_time = car.time + arrival_time - jump_time
                intercept.dodge_preorientation = euler_to_rotation(
                    vec3(euler.pitch, euler.yaw, euler.roll))
                intercept.dodge_delay = jump_time
                intercept.dodge_direction = normalize(vec2(optimal_hit_vector))
                # print(f'intercept_ball_position', intercept_ball_position)
                # print(f'intercept.location', intercept.location)
                # print(f'time until jump {drive_analysis.time}')
                # print(f'time now {car.time}')
                # print(f'distance until jump {drive_analysis.distance}')
                # print(f'total distance to target {total_distance}')
                # print(f'horiz speed @ jump {drive_analysis.speed}')
                # print(f'time intended to be in air {jump_time}')
                # print(f'distance travelled in air {jump_time * drive_analysis.speed}')
                # print(f'distance remaining to target @ jump {total_distance - drive_analysis.distance}')
                # print(f'Intercept convergence in {i} iterations')
                # print(f'desired roll {euler.roll}')
                # print(f'actual roll {rotation_to_euler(c.rotation).roll}')
                break

            intercept_ball_position = vec3(ball_location)
            # intercept.location = vec3(ball_location)
            # intercept.location[2] = 0
            intercept.time = arrival_time
            i += 1

        if i >= max_tries:
            print(
                f'Warning: max tries ({max_tries}) exceeded for calculating intercept'
            )

        # Intercept is only meant for ground paths (and walls/cieling are only indirectly supported)
        # collision_radius = c.hitbox().half_width[2] * 2 + b.collision_radius + b.collision_radius * 8
        # on_ground = intercept.location[2] <= collision_radius
        # on_back_wall = abs(intercept.location[1]) >= 5120 - collision_radius
        # on_side_wall = abs(intercept.location[0]) >= 4096 - collision_radius
        # # on_cieling = intercept.location[2] >= 2044 - collision_radius
        # reachable = on_ground # or on_back_wall or on_side_wall # or on_cieling
        # if not reachable:
        #     return None

        return intercept
コード例 #15
0
    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:
        self.game.read_game_information(packet, self.get_rigid_body_tick(),
                                        self.get_field_info())
        if self.game.ball.location[2] > 250:
            if self.state == "Aerial":
                self.aerial.step(self.game.time_delta)
                if self.aerial.finished:
                    self.state = "Not Aerial"
                return self.aerial.controls
            else:
                self.aerial = Aerial(self.game.my_car)
                self.aerial.up = normalize(
                    vec3(random.uniform(-1, 1), random.uniform(-1, 1),
                         random.uniform(-1, 1)))
                # predict where the ball will be
                prediction = Ball(self.game.ball)
                for i in range(100):
                    prediction.step(0.016666)
                    if prediction.location[2] > 500:
                        self.aerial.target = prediction.location
                        self.aerial.arrival_time = prediction.time
                        if self.aerial.is_viable():
                            self.aerial.target = prediction.location
                            self.aerial.arrival_time = prediction.time
                            self.target_ball = Ball(prediction)
                            self.state = "Aerial"
                            break
        ball_location = Vector2(packet.game_ball.physics.location.x,
                                packet.game_ball.physics.location.y)

        my_car = packet.game_cars[self.index]
        car_location = Vector2(my_car.physics.location.x,
                               my_car.physics.location.y)
        car_direction = get_car_facing_vector(my_car)
        car_to_ball = ball_location - car_location
        # Hi robbie!

        # The,type;of,punctuation;matters!
        true = shreck is love, shreck is life
        main(9)
        if not true:
            print("https://www.twitch.tv/TehRedox is the best twitch channel")
            y.yeet()

        self.WHOOPITYScooPTI = 0
        for i in range(packet.num_cars):
            self.WHOOPITYScooPTI += packet.game_cars[i].score_info.goals

        if self.WHOOPITYScooPTI > self.CountyTHIS_ALSOdonttuch:
            self.CountyTHIS_ALSOdonttuch = self.WHOOPITYScooPTI

        self.renderer.begin_rendering(str(y))
        # commented out due to performance concerns
        # self.renderer.draw_polyline_3d([[car_location.x+triforce(-20,20), car_location.y+triforce(-20,20), triforce(shreck(200),200)] for i in range(40)], self.renderer.cyan())
        self.renderer.draw_rect_2d(
            0, 0, 3840, 2160, True, self.renderer.create_color(
                64, 246, 74, 138))  # first bot that supports 4k resolution!
        self.renderer.draw_string_2d(triforce(0, 100), triforce(0, 10), 8, 8,
                                     'BANIME', self.renderer.lime())
        self.renderer.draw_string_2d(
            triforce(0, 100), triforce(100, 110), 8, 8,
            'SCRATCH IS \n ASSEMBLY \n (also banormies) \n https://www.twitch.tv/donutkiller_pro',
            self.renderer.red())
        self.renderer.end_rendering()

        steer_correction_radians = car_direction.correction_to(car_to_ball)
        turn = clamp11(steer_correction_radians * -3)

        if self.flippityThe_CAR < 1:
            self.howDoIUse_this[self.howDoIUse_this[0][5]] = True
            self.flippityThe_CAR = 1
        elif self.flippityThe_CAR < 2:
            self.howDoIUse_this[self.howDoIUse_this[0][5]] = False
            self.flippityThe_CAR = 2
        elif self.flippityThe_CAR < 3:
            self.howDoIUse_this[self.howDoIUse_this[0][5]] = True
            self.flippityThe_CAR = 3
        elif self.flippityThe_CAR < 666:
            self.howDoIUse_this[self.howDoIUse_this[0][5]] = False
            self.flippityThe_CAR += 6
        elif self.flippityThe_CAR >= 666:
            self.flippityThe_CAR = 0

        self.howDoIUse_this[self.howDoIUse_this[0][0]] = 1
        self.howDoIUse_this[self.howDoIUse_this[0][1]] = turn
        self.howDoIUse_this[self.howDoIUse_this[0][6]] = (
            abs(turn) < 0.2 and not my_car.is_super_sonic)
        self.howDoIUse_this[self.howDoIUse_this[0][7]] = (
            abs(turn) > 1.5 and not my_car.is_super_sonic)

        return getSensible_thingToCONTROL(self.howDoIUse_this)