mirror of
https://github.com/illiumst/marl-factory-grid.git
synced 2025-07-05 09:01:36 +02:00
Documentation
This commit is contained in:

committed by
Steffen Illium

parent
604c0c6f57
commit
855f53b406
@ -3,18 +3,38 @@ from typing import Union
|
||||
from marl_factory_grid.environment.actions import Action
|
||||
from marl_factory_grid.utils.results import ActionResult
|
||||
|
||||
from marl_factory_grid.modules.items import constants as i, rewards as r
|
||||
from marl_factory_grid.modules.items import constants as i
|
||||
from marl_factory_grid.environment import constants as c
|
||||
|
||||
|
||||
class ItemAction(Action):
|
||||
|
||||
def __init__(self, failed_dropoff_reward: float | None = None, valid_dropoff_reward: float | None = None, **kwargs):
|
||||
super().__init__(i.ITEM_ACTION, r.PICK_UP_FAIL, r.PICK_UP_VALID, **kwargs)
|
||||
self.failed_drop_off_reward = failed_dropoff_reward if failed_dropoff_reward is not None else r.DROP_OFF_FAIL
|
||||
self.valid_drop_off_reward = valid_dropoff_reward if valid_dropoff_reward is not None else r.DROP_OFF_FAIL
|
||||
"""
|
||||
Allows an entity to pick up or drop off items in the environment.
|
||||
|
||||
def get_dropoff_result(self, validity, entity):
|
||||
:param failed_drop_off_reward: The reward assigned when a drop-off action fails. Default is None.
|
||||
:type failed_dropoff_reward: float | None
|
||||
:param valid_drop_off_reward: The reward assigned when a drop-off action is successful. Default is None.
|
||||
:type valid_dropoff_reward: float | None
|
||||
"""
|
||||
super().__init__(i.ITEM_ACTION, i.REWARD_PICK_UP_FAIL, i.REWARD_PICK_UP_VALID, **kwargs)
|
||||
self.failed_drop_off_reward = failed_dropoff_reward if failed_dropoff_reward is not None else i.REWARD_DROP_OFF_FAIL
|
||||
self.valid_drop_off_reward = valid_dropoff_reward if valid_dropoff_reward is not None else i.REWARD_DROP_OFF_VALID
|
||||
|
||||
def get_dropoff_result(self, validity, entity) -> ActionResult:
|
||||
"""
|
||||
Generates an ActionResult for a drop-off action based on its validity.
|
||||
|
||||
:param validity: Whether the drop-off action is valid.
|
||||
:type validity: bool
|
||||
|
||||
:param entity: The entity performing the action.
|
||||
:type entity: Entity
|
||||
|
||||
:return: ActionResult for the drop-off action.
|
||||
:rtype: ActionResult
|
||||
"""
|
||||
reward = self.valid_drop_off_reward if validity else self.failed_drop_off_reward
|
||||
return ActionResult(self.__name__, validity, reward=reward, entity=entity)
|
||||
|
||||
|
@ -6,3 +6,9 @@ INVENTORY = 'Inventories'
|
||||
DROP_OFF = 'DropOffLocations'
|
||||
|
||||
ITEM_ACTION = 'ITEMACTION'
|
||||
|
||||
# Rewards
|
||||
REWARD_DROP_OFF_VALID: float = 0.1
|
||||
REWARD_DROP_OFF_FAIL: float = -0.1
|
||||
REWARD_PICK_UP_FAIL: float = -0.1
|
||||
REWARD_PICK_UP_VALID: float = 0.1
|
||||
|
@ -8,39 +8,52 @@ from marl_factory_grid.modules.items import constants as i
|
||||
|
||||
class Item(Entity):
|
||||
|
||||
@property
|
||||
def encoding(self):
|
||||
return 1
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""
|
||||
An item that can be picked up or dropped by agents. If picked up, it enters the agents inventory.
|
||||
"""
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def render(self):
|
||||
return RenderEntity(i.ITEM, self.pos) if self.pos != c.VALUE_NO_POS else None
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@property
|
||||
def encoding(self):
|
||||
# Edit this if you want items to be drawn in the ops differently
|
||||
return 1
|
||||
|
||||
|
||||
class DropOffLocation(Entity):
|
||||
|
||||
def render(self):
|
||||
return RenderEntity(i.DROP_OFF, self.pos)
|
||||
|
||||
@property
|
||||
def encoding(self):
|
||||
return i.SYMBOL_DROP_OFF
|
||||
|
||||
def __init__(self, *args, storage_size_until_full: int = 5, **kwargs):
|
||||
@property
|
||||
def is_full(self) -> bool:
|
||||
"""
|
||||
Checks whether the drop-off location is full or whether another item can be dropped here.
|
||||
"""
|
||||
return False if not self.storage.maxlen else self.storage.maxlen == len(self.storage)
|
||||
|
||||
def __init__(self, *args, storage_size_until_full=5, **kwargs):
|
||||
"""
|
||||
Represents a drop-off location in the environment that agents aim to drop items at.
|
||||
|
||||
:param storage_size_until_full: The number of items that can be dropped here until it is considered full.
|
||||
:type storage_size_until_full: int
|
||||
"""
|
||||
super(DropOffLocation, self).__init__(*args, **kwargs)
|
||||
self.storage = deque(maxlen=storage_size_until_full or None)
|
||||
|
||||
def place_item(self, item: Item):
|
||||
def place_item(self, item: Item) -> bool:
|
||||
"""
|
||||
If the storage of the drop-off location is not full, the item is placed. Otherwise, a RuntimeWarning is raised.
|
||||
"""
|
||||
if self.is_full:
|
||||
raise RuntimeWarning("There is currently no way to clear the storage or make it unfull.")
|
||||
return bc.NOT_VALID
|
||||
return c.NOT_VALID
|
||||
else:
|
||||
self.storage.append(item)
|
||||
return c.VALID
|
||||
|
||||
@property
|
||||
def is_full(self):
|
||||
return False if not self.storage.maxlen else self.storage.maxlen == len(self.storage)
|
||||
def render(self):
|
||||
return RenderEntity(i.DROP_OFF, self.pos)
|
||||
|
@ -1,3 +1,5 @@
|
||||
from typing import Dict, Any
|
||||
|
||||
from marl_factory_grid.environment import constants as c
|
||||
from marl_factory_grid.environment.entity.agent import Agent
|
||||
from marl_factory_grid.environment.groups.collection import Collection
|
||||
@ -16,14 +18,17 @@ class Items(Collection):
|
||||
return True
|
||||
|
||||
@property
|
||||
def is_blocking_light(self):
|
||||
def var_is_blocking_light(self):
|
||||
return False
|
||||
|
||||
@property
|
||||
def can_collide(self):
|
||||
def var_can_collide(self):
|
||||
return False
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""
|
||||
A collection of items that triggers their spawn.
|
||||
"""
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def trigger_spawn(self, state, *entity_args, coords_or_quantity=None, **entity_kwargs) -> [Result]:
|
||||
@ -55,7 +60,13 @@ class Inventory(IsBoundMixin, Collection):
|
||||
def name(self):
|
||||
return f'{self.__class__.__name__}[{self._bound_entity.name}]'
|
||||
|
||||
def __init__(self, agent: Agent, *args, **kwargs):
|
||||
def __init__(self, agent, *args, **kwargs):
|
||||
"""
|
||||
An inventory that can hold items picked up by the agent this is bound to.
|
||||
|
||||
:param agent: The agent this inventory is bound to and belongs to.
|
||||
:type agent: Agent
|
||||
"""
|
||||
super(Inventory, self).__init__(*args, **kwargs)
|
||||
self._collection = None
|
||||
self.bind(agent)
|
||||
@ -69,38 +80,57 @@ class Inventory(IsBoundMixin, Collection):
|
||||
attr_dict.update(dict(name=self.name, belongs_to=self._bound_entity.name))
|
||||
return attr_dict
|
||||
|
||||
def pop(self):
|
||||
def pop(self) -> Item:
|
||||
"""
|
||||
Removes and returns the first item in the inventory.
|
||||
"""
|
||||
item_to_pop = self[0]
|
||||
self.delete_env_object(item_to_pop)
|
||||
return item_to_pop
|
||||
|
||||
def set_collection(self, collection):
|
||||
"""
|
||||
No usage
|
||||
"""
|
||||
self._collection = collection
|
||||
|
||||
def clear_temp_state(self):
|
||||
# Entites need this, but inventories have no state....
|
||||
"""
|
||||
Entites need this, but inventories have no state.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class Inventories(Objects):
|
||||
_entity = Inventory
|
||||
|
||||
var_can_move = False
|
||||
var_has_position = False
|
||||
|
||||
symbol = None
|
||||
|
||||
@property
|
||||
def spawn_rule(self):
|
||||
def var_can_move(self):
|
||||
return False
|
||||
|
||||
@property
|
||||
def var_has_position(self):
|
||||
return False
|
||||
|
||||
@property
|
||||
def spawn_rule(self) -> dict[Any, dict[str, Any]]:
|
||||
"""
|
||||
:returns: a dict containing the specified spawn rule and its arguments.
|
||||
:rtype: dict(dict(collection=self, coords_or_quantity=None))
|
||||
"""
|
||||
return {c.SPAWN_ENTITY_RULE: dict(collection=self, coords_or_quantity=None)}
|
||||
|
||||
def __init__(self, size: int, *args, **kwargs):
|
||||
"""
|
||||
TODO
|
||||
"""
|
||||
super(Inventories, self).__init__(*args, **kwargs)
|
||||
self.size = size
|
||||
self._obs = None
|
||||
self._lazy_eval_transforms = []
|
||||
|
||||
def spawn(self, agents, *args, **kwargs):
|
||||
def spawn(self, agents, *args, **kwargs) -> [Result]:
|
||||
self.add_items([self._entity(agent, self.size, *args, **kwargs) for _, agent in enumerate(agents)])
|
||||
return [Result(identifier=f'{self.name}_spawn', validity=c.VALID, value=len(self))]
|
||||
|
||||
@ -137,6 +167,9 @@ class DropOffLocations(Collection):
|
||||
return True
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""
|
||||
A Collection of Drop-off locations that can trigger their spawn.
|
||||
"""
|
||||
super(DropOffLocations, self).__init__(*args, **kwargs)
|
||||
|
||||
@staticmethod
|
||||
|
@ -1,4 +0,0 @@
|
||||
DROP_OFF_VALID: float = 0.1
|
||||
DROP_OFF_FAIL: float = -0.1
|
||||
PICK_UP_FAIL: float = -0.1
|
||||
PICK_UP_VALID: float = 0.1
|
@ -9,6 +9,16 @@ from marl_factory_grid.modules.items import constants as i
|
||||
class RespawnItems(Rule):
|
||||
|
||||
def __init__(self, n_items: int = 5, respawn_freq: int = 15, n_locations: int = 5):
|
||||
"""
|
||||
Defines the respawning behaviour of items.
|
||||
|
||||
:param n_items: Specifies how many items should respawn.
|
||||
:type n_items: int
|
||||
:param respawn_freq: Specifies how often items should respawn.
|
||||
:type respawn_freq: int
|
||||
:param n_locations: Specifies at how many locations items should be able to respawn.
|
||||
:type: int
|
||||
"""
|
||||
super().__init__()
|
||||
self.spawn_frequency = respawn_freq
|
||||
self._next_item_spawn = respawn_freq
|
||||
|
Reference in New Issue
Block a user