From 6c27aa8eaf967fe6a14a37a4efcdf869b3a4d9cf Mon Sep 17 00:00:00 2001 From: Steffen Illium Date: Thu, 16 Nov 2023 17:08:08 +0100 Subject: [PATCH] Movement printing and Results, state, state reset. --- marl_factory_grid/configs/default_config.yaml | 2 +- marl_factory_grid/environment/actions.py | 15 ++++++++++----- marl_factory_grid/environment/entity/agent.py | 12 ++---------- marl_factory_grid/environment/entity/entity.py | 7 +++++++ marl_factory_grid/environment/entity/object.py | 5 +++++ marl_factory_grid/environment/rules.py | 3 ++- marl_factory_grid/modules/destinations/actions.py | 2 +- marl_factory_grid/modules/items/groups.py | 4 ++++ marl_factory_grid/modules/maintenance/entities.py | 10 ++++++++-- marl_factory_grid/utils/states.py | 4 ++++ random_testrun.py | 2 +- 11 files changed, 45 insertions(+), 21 deletions(-) diff --git a/marl_factory_grid/configs/default_config.yaml b/marl_factory_grid/configs/default_config.yaml index 624e42b..1118704 100644 --- a/marl_factory_grid/configs/default_config.yaml +++ b/marl_factory_grid/configs/default_config.yaml @@ -79,7 +79,7 @@ Rules: done_at_collisions: false # Done Conditions - DoneAtDestinationReachAny: + DoneAtDestinationReach: DoneOnAllDirtCleaned: DoneAtBatteryDischarge: DoneAtMaintainerCollision: diff --git a/marl_factory_grid/environment/actions.py b/marl_factory_grid/environment/actions.py index c6616ae..385abea 100644 --- a/marl_factory_grid/environment/actions.py +++ b/marl_factory_grid/environment/actions.py @@ -51,13 +51,18 @@ class Move(Action, abc.ABC): def do(self, entity, state): new_pos = self._calc_new_pos(entity.pos) if state.check_move_validity(entity, new_pos): - # noinspection PyUnresolvedReferences - move_really_was_valid = entity.move(new_pos, state) - return self.get_result(move_really_was_valid, entity) - else: # There is no place to go, propably collision + valid = entity.move(new_pos, state) + + else: + # There is no place to go, propably collision # This is currently handeld by the WatchCollisions rule, so that it can be switched on and off by conf.yml # return ActionResult(entity=entity, identifier=self._identifier, validity=c.NOT_VALID, reward=r.COLLISION) - return self.get_result(c.NOT_VALID, entity) + valid = c.NOT_VALID + if valid: + state.print(f'{entity.name} just moved to {entity.pos}.') + else: + state.print(f'{entity.name} just tried to move to {new_pos} but either failed or hat a Collision.') + return self.get_result(valid, entity) def _calc_new_pos(self, pos): x_diff, y_diff = MOVEMAP[self._identifier] diff --git a/marl_factory_grid/environment/entity/agent.py b/marl_factory_grid/environment/entity/agent.py index 0920604..f4d9b3b 100644 --- a/marl_factory_grid/environment/entity/agent.py +++ b/marl_factory_grid/environment/entity/agent.py @@ -43,9 +43,6 @@ class Agent(Entity): def var_is_blocking_pos(self): return self._is_blocking_pos - @property - def state(self): - return self._state or ActionResult(entity=self, identifier=c.NOOP, validity=c.VALID) def __init__(self, actions: List[Action], observations: List[str], *args, is_blocking_pos=False, **kwargs): super(Agent, self).__init__(*args, **kwargs) @@ -53,21 +50,16 @@ class Agent(Entity): self.step_result = dict() self._actions = actions self._observations = observations - self._state: Union[Result, None] = None + self._status: Union[Result, None] = None self._is_blocking_pos = is_blocking_pos - # noinspection PyAttributeOutsideInit - def clear_temp_state(self): - self._state = None - return self - def summarize_state(self): state_dict = super().summarize_state() state_dict.update(valid=bool(self.state.validity), action=str(self.state.identifier)) return state_dict def set_state(self, action_result): - self._state = action_result + self._status = action_result def paralyze(self, reason): self._paralyzed.add(reason) diff --git a/marl_factory_grid/environment/entity/entity.py b/marl_factory_grid/environment/entity/entity.py index 999787b..86f3884 100644 --- a/marl_factory_grid/environment/entity/entity.py +++ b/marl_factory_grid/environment/entity/entity.py @@ -90,7 +90,14 @@ class Entity(Object, abc.ABC): self.set_pos(next_pos) for observer in self.observers: observer.notify_add_entity(self) + # Aftermath Collision Check + if len([x for x in state.entities.by_pos(next_pos) if x.var_can_collide]): + # The entity did move, but there was something to collide with... + # Is then reported as a non-valid move, which did work. + valid = False + return valid + # Bad naming... Was the same was the same pos, not moving.... return not_same_pos def __init__(self, pos, bind_to=None, **kwargs): diff --git a/marl_factory_grid/environment/entity/object.py b/marl_factory_grid/environment/entity/object.py index 1b5190d..fbb4f75 100644 --- a/marl_factory_grid/environment/entity/object.py +++ b/marl_factory_grid/environment/entity/object.py @@ -40,6 +40,7 @@ class Object: return True def __init__(self, str_ident: Union[str, None] = None, **kwargs): + self._status = None self._bound_entity = None self._observers = set() self._str_ident = str_ident @@ -84,6 +85,10 @@ class Object: def summarize_state(self): return dict() + def clear_temp_state(self): + self._status = None + return self + def bind_to(self, entity): # noinspection PyAttributeOutsideInit self._bound_entity = entity diff --git a/marl_factory_grid/environment/rules.py b/marl_factory_grid/environment/rules.py index 5c47df5..2e5f305 100644 --- a/marl_factory_grid/environment/rules.py +++ b/marl_factory_grid/environment/rules.py @@ -132,7 +132,8 @@ class WatchCollisions(Rule): for i, guest in enumerate(guests): try: guest.set_state(TickResult(identifier=c.COLLISION, reward=self.reward, - validity=c.NOT_VALID, entity=self)) + validity=c.NOT_VALID, entity=guest) + ) except AttributeError: pass results.append(TickResult(entity=guest, identifier=c.COLLISION, diff --git a/marl_factory_grid/modules/destinations/actions.py b/marl_factory_grid/modules/destinations/actions.py index 419ed69..3ec8743 100644 --- a/marl_factory_grid/modules/destinations/actions.py +++ b/marl_factory_grid/modules/destinations/actions.py @@ -19,5 +19,5 @@ class DestAction(Action): state.print(f'{entity.name} just waited at {entity.pos}') else: valid = c.NOT_VALID - state.print(f'{entity.name} just tried to do_wait_action do_wait_action at {entity.pos} but failed') + state.print(f'{entity.name} just tried to "do_wait_action" at {entity.pos} but failed') return self.get_result(valid, entity) diff --git a/marl_factory_grid/modules/items/groups.py b/marl_factory_grid/modules/items/groups.py index be5ca49..d69935f 100644 --- a/marl_factory_grid/modules/items/groups.py +++ b/marl_factory_grid/modules/items/groups.py @@ -70,6 +70,10 @@ class Inventory(IsBoundMixin, Collection): def set_collection(self, collection): self._collection = collection + def clear_temp_state(self): + # Entites need this, but inventories have no state.... + pass + class Inventories(Objects): _entity = Inventory diff --git a/marl_factory_grid/modules/maintenance/entities.py b/marl_factory_grid/modules/maintenance/entities.py index 479e4c8..459d70f 100644 --- a/marl_factory_grid/modules/maintenance/entities.py +++ b/marl_factory_grid/modules/maintenance/entities.py @@ -26,16 +26,22 @@ class Maintainer(Entity): self._last_serviced = 'None' def tick(self, state): + self.clear_temp_state if found_objective := h.get_first(state[self.objective].by_pos(self.pos)): if found_objective.name != self._last_serviced: self.action.do(self, state) self._last_serviced = found_objective.name else: action = self.get_move_action(state) - return action.do(self, state) + result = action.do(self, state) else: action = self.get_move_action(state) - return action.do(self, state) + result = action.do(self, state) + self.set_state(result) + return result + + def set_state(self, action_result): + self._status = action_result def get_move_action(self, state) -> Action: if self._path is None or not len(self._path): diff --git a/marl_factory_grid/utils/states.py b/marl_factory_grid/utils/states.py index ba2f534..523615a 100644 --- a/marl_factory_grid/utils/states.py +++ b/marl_factory_grid/utils/states.py @@ -152,6 +152,9 @@ class Gamestate(object): results = list() self.curr_step += 1 + for entity in self.entities.iter_entities(): + entity.clear_temp_state() + # Main Agent Step results.extend(self.rules.tick_pre_step_all(self)) @@ -210,6 +213,7 @@ class Gamestate(object): """ Whether it is safe to move to the target positions and moving entity does not introduce a blocking attribute, when position is allready occupied. + !!! Will still report true even though, there could be an enity, which var_can_collide == true !!! :param moving_entity: Entity :param target_position: pos diff --git a/random_testrun.py b/random_testrun.py index e727ea9..ae4d1ca 100644 --- a/random_testrun.py +++ b/random_testrun.py @@ -29,7 +29,7 @@ if __name__ == '__main__': ce.save_all(run_path / 'all_out.yaml') # Path to config File - path = Path('marl_factory_grid/configs/eight_puzzle.yaml') + path = Path('marl_factory_grid/configs/default_config.yaml') # Env Init factory = Factory(path)