예제 #1
0
    def scout_rooms(self, state: State):
        if not self.navigator_running:
            self.navigator_running = True
            # Find closest new room that is traversable
            target_location = None
            target_room_name = None
            dist = None
            for room_name in state.get_all_room_names():
                if room_name != 'world_bounds':
                    door = state.get_closest_room_door(room_name)[0]
                    # If new
                    try:
                        self.traversed_rooms[room_name]
                    except:
                        # If can get in distance of 1
                        loc = find_traversable_location_adjacent(
                            state.get_traverse_map(), door['location'])
                        if loc is not None:
                            # If closer than current
                            if dist is None or state.get_distance_map(
                            )[loc] < dist:
                                target_location = loc
                                target_room_name = room_name
                                dist = state.get_distance_map()[loc]

            self.room_name_to_enter = target_room_name
            self.navigator.add_waypoint(target_location)
        elif self.navigator.is_done:
            # We have reached loc
            self.navigator_running = False
            self.navigator.reset_full()
            self.goal = 1

        return self.navigator.get_move_action(self.state_tracker), {}
예제 #2
0
    def process(self, map_state: MapState, state: State):
        super().process(map_state, state)

        # if we tried to grab a block previous tick, check if we have actually received it from god.
        if self.pending_goal is not None:
            res = state.get_with_property({'carried_by': map_state.agent_id})
            if res is not None and self.pending_goal['filled']['id'] in [
                    x['obj_id'] for x in res['is_carrying']
            ]:
                goal_id = self.pending_goal['filled']['id']
                self.agent.grab_block([
                    self.pending_goal['priority'],  # priority(order)
                    self.pending_goal['location'],
                    self.pending_goal['filled'],
                    True
                    if goal_id in map_state.carried_blocks.keys() else False
                ])
                map_state.pop_block(goal_id)
            else:
                self.remaining.insert(0, self.pending_goal)
            self.pending_goal = None

        # pickup all blocks and redeliver them
        if self.remaining is None:
            self.remaining = [
                goal_block.copy() for goal_block in map_state.goal_blocks
                if goal_block['filled'] is not None
            ]
            self.remaining.sort(key=lambda goal_block: utils.get_distance(
                map_state.get_agent_location(), goal_block['location']))
            for i, goal_block in enumerate(self.remaining):
                self.remaining[i]['filled'] = map_state.blocks.get(
                    goal_block['filled'])

        # pickup all blocks
        while len(self.remaining) > 0:
            goal_block = self.remaining[0]

            # if we're too far away, temporarily set new destination to get closer to the block and pick it up
            # TODO extract hardcoded distance
            if utils.get_distance(map_state.get_agent_location(),
                                  goal_block['location']) > 1:
                if len(self.navigator.get_all_waypoints()
                       ) == 0 or self.navigator.is_done:
                    self.navigator.reset_full()
                    self.navigator.add_waypoint(goal_block['location'])
                return self.navigator.get_move_action(self.state_tracker), {}

            # otherwise grab this block
            self.pending_goal = goal_block
            self.remaining.remove(goal_block)
            return GrabObject.__name__, {
                'object_id': goal_block['filled']['id']
            }

        next_state = DeliveringState(self.strategy, self.navigator,
                                     self.state_tracker)
        self.agent.change_state(next_state)
        return next_state.process(map_state, state)
예제 #3
0
    def filter_observations(self, state: State) -> State:
        newstate = state
        if self.__settings['colorblind']:
            newstate = state.state_update(
                {id: self.__filterColor(vals)
                 for id, vals in state.items()})
        if self.__settings['shapeblind']:
            newstate = state.state_update(
                {id: self.__filterShape(vals)
                 for id, vals in state.items()})

        try:
            res = self.filter_bw4t_observations(newstate)
        except:
            print("IGNORING ERROR FROM AGENT ")
            traceback.print_exc()
            res = newstate

        self.__previous_tick_sent_messages = self.messages_to_send.copy()
        return res
예제 #4
0
    def explore_room(self, state: State):
        # If we haven't opened the door yet
        if not state.get_closest_room_door(
                self.room_name_to_enter)[0]['is_open']:
            return OpenDoorAction.__name__, \
                   {'object_id': state.get_closest_room_door(self.room_name_to_enter)[0]['obj_id']}

        # Move through the room
        if not self.navigator_running:
            self.navigator_running = True
            self.navigator.add_waypoints([
                x['location']
                for x in state.get_room_objects(self.room_name_to_enter)
            ])
            self.traversed_rooms[self.room_name_to_enter] = True
        elif self.navigator.is_done:
            self.navigator_running = False
            self.navigator.reset_full()
            self.goal = 2
        return self.navigator.get_move_action(self.state_tracker), {}
예제 #5
0
 def _nearbyDoors(self, state: State):
     # copy from humanagent
     # Get all doors from the perceived objects
     objects = list(state.keys())
     doors = [obj for obj in objects if 'is_open' in state[obj]]
     doors_in_range = []
     for object_id in doors:
         # Select range as just enough to grab that object
         dist = int(
             np.ceil(
                 np.linalg.norm(
                     np.array(state[object_id]['location']) -
                     np.array(state[self.agent_id]['location']))))
         if dist <= self._door_range:
             doors_in_range.append(object_id)
     return doors_in_range
예제 #6
0
    def get_nearby_blocks(self, state: State):
        """
        Checks what blocks can be seen from our position.
        Excludes block that can be seen through walls.
        """
        objects = list(state.keys())
        blocks = []

        for obj in objects:
            if "class_inheritance" in state[obj]:
                if state[obj]["class_inheritance"][
                        0] == "CollectableBlock":  # does this cover all blocks??
                    if self.is_reachable(state, state[obj]['location']):
                        blocks.append(state[obj])

        return blocks
예제 #7
0
    def process(self, map_state: MapState, state: State):
        super().process(map_state, state)

        # if we tried to grab a block previous tick, check if we have actually received it from god.
        if self.pending_block is not None:
            res = state.get_with_property({'carried_by': map_state.agent_id})
            if res is not None and self.pending_block[2]['id'] in [
                    x['obj_id'] for x in res['is_carrying']
            ]:
                self.agent.grab_block(self.pending_block)
                map_state.pop_block(self.pending_block[2])
            self.pending_block = None

        if self.strategy.is_all_blocks_found(map_state):
            next_state = DeliveringState(self.strategy, self.navigator,
                                         self.state_tracker)
            self.agent.change_state(next_state)
            return next_state.process(map_state, state)

        room = map_state.get_room(self.room_id)

        # if just started exploring the room, then initialise the unvisited squares and go towards one of those squares
        if self.unvisited_squares is None:
            self.unvisited_squares = set(room['indoor_area'])

        if len(self.navigator.get_all_waypoints()) == 0:
            self.navigator.add_waypoint(next(iter(self.unvisited_squares)))

        # check if any of the blocks match the goal blocks
        matching_blocks = self.strategy.get_matching_blocks_nearby(map_state)

        # check if the blocks in the room has been visited if so change traverse strategy
        if map_state.are_nearby_blocks_visited():
            map_state.visit_room(self.room_id)
            nearby_agents = map_state.get_nearby_agent(state)
            ability = map_state.agent_ability

            def switch_traverse_order(self):
                next_state = WalkingState(self.strategy, self.navigator,
                                          self.state_tracker)
                next_state.strategy.switch_traverse_order()
                self.agent.change_state(next_state)
                return next_state.process(map_state, state)

            if len(nearby_agents) == 0:
                return switch_traverse_order(self)
            else:
                num_agents_same_ability = sum(
                    [1 for i in nearby_agents if i['ability'] == ability])
                if num_agents_same_ability == 0 and map_state.agent_ability == 3:
                    return switch_traverse_order(self)
                random.seed(map_state.agent_id, version=2)
                if num_agents_same_ability != 0 and random.randint(
                        1, 10) > (10 / num_agents_same_ability):
                    return switch_traverse_order(self)

        for block in filter(lambda b: not b[3], matching_blocks):
            # if we're too far away, temporarily set new destination to get closer to the block and pick it up
            # TODO extract hardcoded distance
            if utils.get_distance(map_state.get_agent_location(),
                                  block[2]['location']) > 1:
                self.navigator.reset_full()
                self.navigator.add_waypoint(block[2]['location'])
                return self.navigator.get_move_action(self.state_tracker), {}

            # otherwise grab this block
            self.navigator.is_done = True
            self.pending_block = block
            return GrabObject.__name__, {'object_id': block[2]['id']}

        # # if full capacity, start delivering
        # # TODO make this smarter by cooperating with other agents
        # if self.strategy.is_all_blocks_found:
        #     self.agent.change_state(DeliveringState(self.strategy, self.navigator, self.state_tracker))
        #     return None, {}

        # update the unvisited squares
        self.__update_visited_squares(map_state.get_agent_location())

        # if we visited all squares in this room, we can go back to walking
        if len(self.unvisited_squares) == 0:
            self.navigator.reset_full()
            map_state.visit_room(self.room_id)
            next_state = WalkingState(self.strategy, self.navigator,
                                      self.state_tracker)
            self.agent.change_state(next_state)
            return next_state.process(map_state, state)

        # if we have already arrived to our destination, choose a new destination from the unvisited squares in the room
        if self.navigator.is_done:
            self.navigator.reset_full()
            self.navigator.add_waypoint(next(iter(self.unvisited_squares)))

        return self.navigator.get_move_action(self.state_tracker), {}