Ejemplo n.º 1
0
 def initialize_agent(self):
     # Initialize the rlgym GameState object now that the game is active and the info is available
     self.game_state = GameState(self.get_field_info())
     self.ticks = self.tick_skip  # So we take an action the first tick
     self.prev_time = 0
     self.controls = SimpleControllerState()
     self.action = np.zeros(8)
     self.update_action = True
Ejemplo n.º 2
0
class RLGymExampleBot(BaseAgent):
    def __init__(self, name, team, index):
        super().__init__(name, team, index)
        self.obs_builder = AdvancedStacker()
        self.agent = Agent()
        self.tick_skip = 8

        self.game_state: GameState = None
        self.controls = None
        self.prev_action = None
        self.ticks = 0
        self.prev_time = 0
        print(f"{name} loaded and ready!")

    def initialize_agent(self):
        self.game_state = GameState(self.get_field_info())
        self.ticks = self.tick_skip
        self.prev_time = 0
        self.controls = SimpleControllerState()
        self.prev_action = np.zeros(8)

    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:
        cur_time = packet.game_info.seconds_elapsed
        delta = cur_time - self.prev_time
        self.prev_time = cur_time

        self.ticks += delta // 0.008

        if self.ticks >= self.tick_skip:
            self.ticks = 0

            self.game_state.decode(packet)
            player = self.game_state.players[self.index]
            opponents = [
                p for p in self.game_state.players if p.team_num != self.team
            ]
            closest_op = min(
                opponents,
                key=lambda p: np.linalg.norm(self.game_state.ball.position - p.
                                             car_data.position))

            self.game_state.players = [player, closest_op]

            obs = self.obs_builder.build_obs(player, self.game_state,
                                             self.prev_action)
            action, discrete = self.agent.act(obs)
            self.update_controls(action, discrete_action=discrete)

        return self.controls

    def update_controls(self, action, discrete_action=None):
        if discrete_action == None:
            self.prev_action[:] = action[:]
        else:
            self.prev_action = discrete_action

        self.controls.throttle = action[0]
        self.controls.steer = action[1]
        self.controls.pitch = action[2]
        self.controls.yaw = action[3]
        self.controls.roll = action[4]
        self.controls.jump = action[5] > 0
        self.controls.boost = action[6] > 0
        self.controls.handbrake = action[7] > 0
Ejemplo n.º 3
0
class RLGymExampleBot(BaseAgent):
    def __init__(self, name, team, index):
        super().__init__(name, team, index)

        # FIXME Hey, botmaker. Start here:
        # Swap the obs builder if you are using a different one, RLGym's AdvancedObs is also available
        self.obs_builder = AdvancedObs()
        # Your neural network logic goes inside the Agent class, go take a look inside src/agent.py
        self.agent = Agent()
        # Adjust the tickskip if your agent was trained with a different value
        self.tick_skip = 8

        self.game_state: GameState = None
        self.controls = None
        self.action = None
        self.update_action = True
        self.ticks = 0
        self.prev_time = 0
        self.expected_teammates = 0
        self.expected_opponents = 1
        print(f'{self.name} Ready - Index:', index)

    def initialize_agent(self):
        # Initialize the rlgym GameState object now that the game is active and the info is available
        self.game_state = GameState(self.get_field_info())
        self.ticks = self.tick_skip  # So we take an action the first tick
        self.prev_time = 0
        self.controls = SimpleControllerState()
        self.action = np.zeros(8)
        self.update_action = True

    def reshape_state(self, gamestate, player, opponents, allies):
        """ TODO - replace me with code that handles different sized teams
        - converting to 1v1 currently """
        closest_op = min(
            opponents,
            key=lambda p: np.linalg.norm(self.game_state.ball.position - p.
                                         car_data.position))
        self.game_state.players = [player, closest_op]

    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:
        cur_time = packet.game_info.seconds_elapsed
        delta = cur_time - self.prev_time
        self.prev_time = cur_time

        ticks_elapsed = delta * 120
        self.ticks += ticks_elapsed
        self.game_state.decode(packet, ticks_elapsed)

        if self.update_action:
            self.update_action = False
            player = self.game_state.players[self.index]
            opponents = [
                p for p in self.game_state.players if p.team_num != self.team
            ]
            allies = [
                p for p in self.game_state.players
                if p.team_num == self.team and p.car_id != self.index
            ]

            if len(opponents) != self.expected_opponents or len(
                    allies) != self.expected_teammates:
                self.reshape_state(self.game_state, player, opponents, allies)

            obs = self.obs_builder.build_obs(player, self.game_state,
                                             self.action)
            self.action = self.agent.act(obs)

        if self.ticks >= self.tick_skip:
            self.ticks = 0
            self.update_controls(self.action)
            self.update_action = True

        self.maybe_do_kickoff(packet, ticks_elapsed)
        return self.controls

    def maybe_do_kickoff(self, packet, ticks_elapsed):
        y = packet.game_ball.physics.location.y
        x = packet.game_ball.physics.location.x
        my_car = packet.game_cars[self.index]
        car_location = Vec3(my_car.physics.location)
        ball_location = Vec3(packet.game_ball.physics.location)

        y_car = packet.game_cars[0].physics.location.y
        x_car = packet.game_cars[0].physics.location.x

        if packet.game_info.is_kickoff_pause:
            if x == 0 and y == 0 and car_location.dist(ball_location) > 2000:
                if car_location.dist(ball_location) > 3350:
                    if x_car > 0:
                        self.kickoff_index = 3
                    elif x_car < 0:
                        self.kickoff_index = 2
                    elif x_car == 0:
                        self.kickoff_index = -1
                else:
                    self.kickoff_index = 1
            else:
                if car_location.dist(ball_location) < 600:
                    self.kickoff_index = 4
                else:
                    self.kickoff_index = -1

            if 1 == self.kickoff_index and packet.game_ball.physics.location.y == 0:
                action = KICKOFF_NUMPY1[self.kickoff_index]
                self.action = action
                self.update_controls(self.action)
            elif 2 == self.kickoff_index and packet.game_ball.physics.location.y == 0:
                action = KICKOFF_NUMPY2[self.kickoff_index]
                self.action = action
                self.update_controls(self.action)
            elif 3 == self.kickoff_index and packet.game_ball.physics.location.y == 0:
                action = KICKOFF_NUMPY3[self.kickoff_index]
                self.action = action
                self.update_controls(self.action)
            elif 4 == self.kickoff_index and packet.game_ball.physics.location.y == 0:
                action = FRONT_FLIP[self.kickoff_index]
                self.action = action
                self.update_controls(self.action)
        else:
            self.kickoff_index = -1

    def update_controls(self, action):
        self.controls.throttle = action[0]
        self.controls.steer = action[1]
        self.controls.pitch = action[2]
        self.controls.yaw = action[3]
        self.controls.roll = action[4]
        self.controls.jump = action[5] > 0
        self.controls.boost = action[6] > 0
        self.controls.handbrake = action[7] > 0
Ejemplo n.º 4
0
 def initialize_agent(self):
     self.game_state = GameState(self.get_field_info())
     self.ticks = self.tick_skip
     self.prev_time = 0
     self.controls = SimpleControllerState()
     self.prev_action = np.zeros(8)
Ejemplo n.º 5
0
class RLGymExampleBot(BaseAgent):
    def __init__(self, name, team, index):
        super().__init__(name, team, index)

        # FIXME Hey, botmaker. Start here:
        # Swap the obs builder if you are using a different one, RLGym's AdvancedObs is also available
        self.obs_builder = AdvancedObs()
        # Swap the action parser if you are using a different one, RLGym's Discrete and Continuous are also available
        self.act_parser = DiscreteAction()
        # Your neural network logic goes inside the Agent class, go take a look inside src/agent.py
        self.agent = Agent()
        # Adjust the tickskip if your agent was trained with a different value
        self.tick_skip = 8

        self.game_state: GameState = None
        self.controls = None
        self.action = None
        self.update_action = True
        self.ticks = 0
        self.prev_time = 0
        # self.prev_time_pause = 0
        # self.game_on = True
        print('RLGymExampleBot Ready - Index:', index)

    def initialize_agent(self):
        # Initialize the rlgym GameState object now that the game is active and the info is available
        self.game_state = GameState(self.get_field_info())
        self.ticks = self.tick_skip  # So we take an action the first tick
        self.prev_time = 0
        self.controls = SimpleControllerState()
        self.action = np.zeros(8)
        self.update_action = True

    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:
        cur_time = packet.game_info.seconds_elapsed
        delta = cur_time - self.prev_time
        self.prev_time = cur_time

        ticks_elapsed = round(delta * 120)
        self.ticks += ticks_elapsed
        self.game_state.decode(packet, ticks_elapsed)

        if self.update_action:
            self.update_action = False

            # FIXME Hey, botmaker. Verify that this is what you need for your agent
            # By default we treat every match as a 1v1 against a fixed opponent,
            # by doing this your bot can participate in 2v2 or 3v3 matches. Feel free to change this
            player = self.game_state.players[self.index]
            teammates = [
                p for p in self.game_state.players if p.team_num == self.team
            ]
            opponents = [
                p for p in self.game_state.players if p.team_num != self.team
            ]

            if len(opponents) == 0:
                # There's no opponent, we assume this model is 1v0
                self.game_state.players = [player]
            else:
                # Sort by distance to ball
                teammates.sort(key=lambda p: np.linalg.norm(
                    self.game_state.ball.position - p.car_data.position))
                opponents.sort(key=lambda p: np.linalg.norm(
                    self.game_state.ball.position - p.car_data.position))

                # Grab opponent in same "position" relative to it's teammates
                opponent = opponents[min(teammates.index(player),
                                         len(opponents) - 1)]

                self.game_state.players = [player, opponent]

            obs = self.obs_builder.build_obs(player, self.game_state,
                                             self.action)
            self.action = self.act_parser.parse_actions(
                self.agent.act(obs), self.game_state)[0]  # Dim is (N, 8)

        if self.ticks >= self.tick_skip - 1:  #  and self.game_on == True:
            self.update_controls(self.action)

        # omus_position = packet.game_cars[self.index].physics.location

        # if (np.round(np.abs(np.array([omus_position.x,omus_position.y,omus_position.z]))) == np.array([0, 1000, 17])).all() and cur_time - self.prev_time_pause > 1:
        #     self.prev_time_pause = cur_time
        #     self.action = np.zeros(8)
        #     self.update_controls(self.action)
        #     self.game_on = False

        # # Wait till game is on (default from minigame is 0.5s pause)
        # if cur_time - self.prev_time_pause >= 59.5/120 and self.game_on == False:
        #     #ticks_elapsed = self.tick_skip # So we take an action straight after restart
        #     self.game_on = True

        if self.ticks >= self.tick_skip:
            self.ticks = 0
            self.update_action = True

        return self.controls

    def update_controls(self, action):
        self.controls.throttle = action[0]
        self.controls.steer = action[1]
        self.controls.pitch = action[2]
        self.controls.yaw = 0 if action[5] > 0 else action[3]
        self.controls.roll = action[4]
        self.controls.jump = action[5] > 0
        self.controls.boost = action[6] > 0
        self.controls.handbrake = action[7] > 0
Ejemplo n.º 6
0
class RLGymExampleBot(BaseAgent):
    def __init__(self, name, team, index):
        super().__init__(name, team, index)

        # FIXME Hey, botmaker. Start here:
        # Swap the obs builder if you are using a different one, RLGym's AdvancedObs is also available
        self.obs_builder = AdvancedObs()
        # Your neural network logic goes inside the Agent class, go take a look inside src/agent.py
        self.agent = Agent()
        # Adjust the tickskip if your agent was trained with a different value
        self.tick_skip = 4
        self.game_state: GameState = None
        self.controls = None
        self.action = None
        self.ticks = 0
        self.prev_time = 0
        self.observed = False
        self.acted = False
        self.expected_teammates = 0
        self.expected_opponents = 1
        self.current_obs = None
        self.kickoff_index = -1
        print(f'{self.name} Ready - Index:', index)

    def initialize_agent(self):
        # Initialize the rlgym GameState object now that the game is active and the info is available
        self.game_state = GameState(self.get_field_info())
        self.ticks = self.tick_skip  # So we take an action the first tick
        self.prev_time = 0
        self.controls = SimpleControllerState()
        self.action = np.zeros(8)
        self.tick_multi = 120
        self.kickoff_index = -1

    def reshape_state(self, gamestate, player, opponents, allies):
        """ TODO - replace me with code that handles different sized teams
        - converting to 1v1 currently """
        closest_op = min(opponents, key=lambda p: np.linalg.norm(self.game_state.ball.position - p.car_data.position))
        self.game_state.players = [player, closest_op]

    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:
        cur_time = packet.game_info.seconds_elapsed
        delta = cur_time - self.prev_time
        self.prev_time = cur_time
        ticks_elapsed = self.ticks * self.tick_multi
        self.ticks += delta

        if not self.observed:
            self.game_state.decode(packet, ticks_elapsed)
            if packet.game_info.is_kickoff_pause and not packet.game_info.is_round_active:
                ''' This would be a good time to reset the obs/action if you're using a stacking obs
                    otherwise it shouldn't really matter'''
                #self.obs_builder.reset(self.game_state)
                #self.action = np.zeros(8)
                #self.update_controls(self.action)
                pass
            player = self.game_state.players[self.index]
            opponents = [p for p in self.game_state.players if p.team_num != self.team]
            allies = [p for p in self.game_state.players if p.team_num == self.team and p.car_id != self.index]

            if len(opponents) != self.expected_opponents or len(allies) != self.expected_teammates:
                self.reshape_state(self.game_state, player, opponents, allies)

            self.current_obs = self.obs_builder.build_obs(player, self.game_state, self.action)
            self.observed = True

        elif ticks_elapsed >= self.tick_skip-2:
            if not self.acted:
                self.action = self.agent.act(self.current_obs)
                self.update_controls(self.action)
                self.acted = True

        if ticks_elapsed >= self.tick_skip-1:
            self.ticks = 0
            self.observed = False
            self.acted = False

        self.maybe_do_kickoff(packet, ticks_elapsed)

        return self.controls

    def maybe_do_kickoff(self, packet, ticks_elapsed):
        if packet.game_info.is_kickoff_pause:
            if self.kickoff_index >= 0:
                self.kickoff_index += round(ticks_elapsed)
            elif self.kickoff_index == -1:
                is_kickoff_taker = False
                ball_pos = np.array([packet.game_ball.physics.location.x, packet.game_ball.physics.location.y])
                positions = np.array([[car.physics.location.x, car.physics.location.y]
                                      for car in packet.game_cars[:packet.num_cars]])
                distances = np.linalg.norm(positions - ball_pos, axis=1)
                if abs(distances.min() - distances[self.index]) <= 10:
                    is_kickoff_taker = True
                    indices = np.argsort(distances)
                    for index in indices:
                        if abs(distances[index] - distances[self.index]) <= 10 \
                                and packet.game_cars[index].team == self.team \
                                and index != self.index:
                            if self.team == 0:
                                is_left = positions[index, 0] < positions[self.index, 0]
                            else:
                                is_left = positions[index, 0] > positions[self.index, 0]
                            if not is_left:
                                is_kickoff_taker = False  # Left goes

                self.kickoff_index = 0 if is_kickoff_taker else -2

            if 0 <= self.kickoff_index < len(KICKOFF_NUMPY) \
                    and packet.game_ball.physics.location.y == 0:
                action = KICKOFF_NUMPY[self.kickoff_index]
                self.action = action
                self.update_controls(self.action)
        else:
            self.kickoff_index = -1

    def update_controls(self, action):
        self.controls.throttle = action[0]
        self.controls.steer = action[1]
        self.controls.pitch = action[2]
        self.controls.yaw = action[3]
        self.controls.roll = action[4]
        self.controls.jump = action[5] > 0
        self.controls.boost = action[6] > 0
        self.controls.handbrake = action[7] > 0
Ejemplo n.º 7
0
class Nexto(BaseAgent):
    def __init__(self,
                 name,
                 team,
                 index,
                 beta=1,
                 render=False,
                 hardcoded_kickoffs=True):
        super().__init__(name, team, index)

        self.obs_builder = None
        self.agent = Agent()
        self.tick_skip = 8

        # Beta controls randomness:
        # 1=best action, 0.5=sampling from probability, 0=random, -1=worst action, or anywhere inbetween
        self.beta = beta
        self.render = render
        self.hardcoded_kickoffs = hardcoded_kickoffs

        self.game_state: GameState = None
        self.controls = None
        self.action = None
        self.update_action = True
        self.ticks = 0
        self.prev_time = 0
        self.kickoff_index = -1
        print('Nexto Ready - Index:', index)

    def initialize_agent(self):
        # Initialize the rlgym GameState object now that the game is active and the info is available
        field_info = self.get_field_info()
        self.obs_builder = NextoObsBuilder(field_info=field_info)
        self.game_state = GameState(field_info)
        self.ticks = self.tick_skip  # So we take an action the first tick
        self.prev_time = 0
        self.controls = SimpleControllerState()
        self.action = np.zeros(8)
        self.update_action = True
        self.kickoff_index = -1

    def render_attention_weights(self, weights, obs):
        mean_weights = torch.mean(torch.stack(weights), dim=0).numpy()[0][0]

        top = sorted(range(len(mean_weights)),
                     key=lambda i: mean_weights[i],
                     reverse=True)
        top.remove(1)  # Self

        self.renderer.begin_rendering('attention_weights')

        invert = np.array([-1, -1, 1]) if self.team == 1 else np.ones(3)
        loc = obs[0][0, 0, 5:8] * 2300 * invert
        mx = mean_weights[~(np.arange(len(mean_weights)) == 1)].max()
        c = 1
        for i in top[:3]:
            weight = mean_weights[i] / mx
            # print(i, weight)
            dest = loc + obs[1][0, i, 5:8] * 2300 * invert
            color = self.renderer.create_color(255, round(255 * (1 - weight)),
                                               round(255),
                                               round(255 * (1 - weight)))
            self.renderer.draw_string_3d(dest, 2, 2, str(c), color)
            c += 1
            self.renderer.draw_line_3d(loc, dest, color)
        self.renderer.end_rendering()

    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:
        cur_time = packet.game_info.seconds_elapsed
        delta = cur_time - self.prev_time
        self.prev_time = cur_time

        ticks_elapsed = round(delta * 120)
        self.ticks += ticks_elapsed
        self.game_state.decode(packet, ticks_elapsed)

        if self.update_action and len(self.game_state.players) > self.index:
            self.update_action = False

            player = self.game_state.players[self.index]
            teammates = [
                p for p in self.game_state.players
                if p.team_num == self.team and p != player
            ]
            opponents = [
                p for p in self.game_state.players if p.team_num != self.team
            ]

            self.game_state.players = [player] + teammates + opponents

            obs = self.obs_builder.build_obs(player, self.game_state,
                                             self.action)

            beta = self.beta
            if packet.game_info.is_match_ended:
                # or not (packet.game_info.is_kickoff_pause or packet.game_info.is_round_active): Removed due to kickoff
                beta = 0  # Celebrate with random actions
            self.action = self.agent.act(obs, beta)

            # self.render_attention_weights(weights, obs)

        if self.ticks >= self.tick_skip - 1:
            self.update_controls(self.action)

        if self.ticks >= self.tick_skip:
            self.ticks = 0
            self.update_action = True

        if self.hardcoded_kickoffs:
            self.maybe_do_kickoff(packet, ticks_elapsed)

        return self.controls

    def maybe_do_kickoff(self, packet, ticks_elapsed):
        if packet.game_info.is_kickoff_pause:
            if self.kickoff_index >= 0:
                self.kickoff_index += round(ticks_elapsed)
            elif self.kickoff_index == -1:
                is_kickoff_taker = False
                ball_pos = np.array([
                    packet.game_ball.physics.location.x,
                    packet.game_ball.physics.location.y
                ])
                positions = np.array(
                    [[car.physics.location.x, car.physics.location.y]
                     for car in packet.game_cars[:packet.num_cars]])
                distances = np.linalg.norm(positions - ball_pos, axis=1)
                if abs(distances.min() - distances[self.index]) <= 10:
                    is_kickoff_taker = True
                    indices = np.argsort(distances)
                    for index in indices:
                        if abs(distances[index] - distances[self.index]) <= 10 \
                                and packet.game_cars[index].team == self.team \
                                and index != self.index:
                            if self.team == 0:
                                is_left = positions[index,
                                                    0] < positions[self.index,
                                                                   0]
                            else:
                                is_left = positions[index,
                                                    0] > positions[self.index,
                                                                   0]
                            if not is_left:
                                is_kickoff_taker = False  # Left goes

                self.kickoff_index = 0 if is_kickoff_taker else -2

            if 0 <= self.kickoff_index < len(KICKOFF_NUMPY) \
                    and packet.game_ball.physics.location.y == 0:
                action = KICKOFF_NUMPY[self.kickoff_index]
                self.action = action
                self.update_controls(self.action)
        else:
            self.kickoff_index = -1

    def update_controls(self, action):
        self.controls.throttle = action[0]
        self.controls.steer = action[1]
        self.controls.pitch = action[2]
        self.controls.yaw = action[3]
        self.controls.roll = action[4]
        self.controls.jump = action[5] > 0
        self.controls.boost = action[6] > 0
        self.controls.handbrake = action[7] > 0
Ejemplo n.º 8
0
class Necto(BaseAgent):
    def __init__(self, name, team, index):
        super().__init__(name, team, index)

        self.obs_builder = NectoObsBuilder()
        self.agent = Agent()
        self.tick_skip = 8

        self.game_state: GameState = None
        self.controls = None
        self.action = None
        self.update_action = True
        self.ticks = 0
        self.prev_time = 0
        print('RLGymExampleBot Ready - Index:', index)

    def initialize_agent(self):
        # Initialize the rlgym GameState object now that the game is active and the info is available
        self.game_state = GameState(self.get_field_info())
        self.ticks = self.tick_skip  # So we take an action the first tick
        self.prev_time = 0
        self.controls = SimpleControllerState()
        self.action = np.zeros(8)
        self.update_action = True

    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:
        cur_time = time.perf_counter()
        delta = cur_time - self.prev_time
        self.prev_time = cur_time

        ticks_elapsed = delta * 120  # Smaller than 1/120 on purpose
        self.ticks += ticks_elapsed
        self.game_state.decode(packet, ticks_elapsed)

        if self.update_action and len(self.game_state.players) > self.index:
            self.update_action = False

            player = self.game_state.players[self.index]
            teammates = [p for p in self.game_state.players if p.team_num == self.team and p != player]
            opponents = [p for p in self.game_state.players if p.team_num != self.team]

            # TODO Maybe draw some stuff based on attention scores?
            # self.renderer.draw_string_3d(closest_op.car_data.position, 2, 2, "CLOSEST", self.renderer.white())

            self.game_state.players = [player] + teammates + opponents

            obs = self.obs_builder.build_obs(player, self.game_state, self.action)
            self.action = self.agent.act(obs)

        if self.ticks >= self.tick_skip:
            self.ticks = 0
            self.update_controls(self.action)
            self.update_action = True

        return self.controls

    def update_controls(self, action):
        self.controls.throttle = action[0]
        self.controls.steer = action[1]
        self.controls.pitch = action[2]
        self.controls.yaw = action[3]
        self.controls.roll = action[4]
        self.controls.jump = action[5] > 0
        self.controls.boost = action[6] > 0
        self.controls.handbrake = action[7] > 0