diff --git a/ForkliftAgent.py b/ForkliftAgent.py index 6ed6278..8dee11e 100644 --- a/ForkliftAgent.py +++ b/ForkliftAgent.py @@ -100,11 +100,11 @@ class ForkliftAgent(AgentBase): packing_station: GridLocation = None stations = dict(self.graph.packingStations) - if i.real_type == ItemType.PASTA: + if i.real_type == ItemType.SHELF: packing_station = stations[PatchType.packingA] elif i.real_type == ItemType.EGG: packing_station = stations[PatchType.packingB] - elif i.real_type == ItemType.PIZZA: + elif i.real_type == ItemType.DOOR: packing_station = stations[PatchType.packingC] pathFinder = PathFinderOnStates( diff --git a/GameModel.py b/GameModel.py index 64d0ea7..45999f5 100644 --- a/GameModel.py +++ b/GameModel.py @@ -10,6 +10,7 @@ from ForkliftAgent import ForkliftAgent from InitialStateFactory import InitialStateFactory from PatchAgent import PatchAgent from PatchType import PatchType +from PictureVisualizationAgent import PictureVisualizationAgent from data.GameConstants import GameConstants from data.Item import Item from data.Order import Order @@ -36,6 +37,7 @@ class GameModel(Model): self.running = True self.grid = MultiGrid(height, width, True) self.schedule = RandomActivation(self) + self.current_item_recognition = None self.client_delivery: PatchAgent = None self.drop_off: PatchAgent = None @@ -97,11 +99,27 @@ class GameModel(Model): self.grid.place_agent(self.forklift_agent, (x, y)) self.forklift_agent.current_position = (x, y) + self.picture_visualization = PictureVisualizationAgent( + self, + (1, 11), + ) + self.schedule.add(self.picture_visualization) + self.grid.place_agent(self.picture_visualization, self.picture_visualization.location) + self.agents.append(self.picture_visualization) + self.place_logistics() + self.place_dividers() self.place_walls_agents(graph.walls) self.place_puddles(graph.puddles) self.place_packing_stations(graph.packingStations) + def place_dividers(self): + for i in range(0, 10): + for j in range(10,13): + agent = PatchAgent(self, (i, j), PatchType.divider) + self.agents.append(agent) + self.grid.place_agent(agent, (i, j)) + def place_logistics(self): agent = PatchAgent(self, (self.grid.width - 1, int(self.grid.height / 2)), PatchType.pickUp) self.schedule.add(agent) @@ -149,6 +167,7 @@ class GameModel(Model): else: print("BEGIN ITEM RECOGNITION, left: {}".format(len(self.provided_items))) item_to_recognise = self.provided_items.pop() + self.picture_visualization.img = "item_images/door/drzwi1.jpg" recognised = self.recognise_item(item_to_recognise) self.recognised_items.append(recognised) diff --git a/PatchType.py b/PatchType.py index bae60de..289107d 100644 --- a/PatchType.py +++ b/PatchType.py @@ -10,3 +10,4 @@ class PatchType(enum.Enum): packingA = 6 packingB = 7 packingC = 8 + divider = 9 diff --git a/PictureVisualizationAgent.py b/PictureVisualizationAgent.py new file mode 100644 index 0000000..7e09113 --- /dev/null +++ b/PictureVisualizationAgent.py @@ -0,0 +1,13 @@ +from AgentBase import AgentBase +from util.PathDefinitions import GridLocation + + +class PictureVisualizationAgent(AgentBase): + + def __init__(self, model, location: GridLocation): + self.location = location + self.img = "" + super().__init__(model) + + def creation_log(self): + print("Created Patch Agent [id: {} ,img: {}]".format(self.unique_id, self.img)) diff --git a/data/enum/ItemType.py b/data/enum/ItemType.py index edb4e4b..f15e785 100644 --- a/data/enum/ItemType.py +++ b/data/enum/ItemType.py @@ -2,6 +2,6 @@ from enum import Enum class ItemType(Enum): - PIZZA = 1 - PASTA = 2 + DOOR = 1 + SHELF = 2 EGG = 3 \ No newline at end of file diff --git a/item_images/door/drzwi1.jpg b/item_images/door/drzwi1.jpg new file mode 100644 index 0000000..f239f2a Binary files /dev/null and b/item_images/door/drzwi1.jpg differ diff --git a/item_images/door/drzwi2.png b/item_images/door/drzwi2.png new file mode 100644 index 0000000..f9563e1 Binary files /dev/null and b/item_images/door/drzwi2.png differ diff --git a/main.py b/main.py index 1235ae6..0574917 100644 --- a/main.py +++ b/main.py @@ -7,9 +7,13 @@ from ForkliftAgent import ForkliftAgent from GameModel import GameModel from PatchAgent import PatchAgent from PatchType import PatchType +from PictureVisualizationAgent import PictureVisualizationAgent from data.enum.Direction import Direction from util.PathDefinitions import GridWithWeights from visualization.DisplayAttributeElement import DisplayAttributeElement +from visualization.DisplayItemListAttribute import DisplayItemListAttributeElement +from visualization.DisplayOrderList import DisplayOrderList +from visualization.DisplayPictureElement import DisplayPictureElement colors = [ 'blue', 'cyan', 'orange', 'yellow', 'magenta', 'purple', '#103d3e', '#9fc86c', @@ -41,6 +45,14 @@ def agent_portrayal(agent): portrayal = {"Shape": "img/okB00mer.png", "scale": 1.0, "Layer": 0} elif agent.patch_type == PatchType.diffTerrain: portrayal = {"Shape": "img/puddle.png", "scale": 1.0, "Layer": 0} + elif agent.patch_type == PatchType.divider: + portrayal = \ + {"Shape": "rect", + "Filled": "true", + "Layer": 0, + "Color": "black", + "w": 1, + "h": 1} else: color = colors[random.randrange(13) + 3] portrayal = {"Shape": "rect", @@ -49,13 +61,17 @@ def agent_portrayal(agent): "Color": color, "w": 1, "h": 1} + + if isinstance(agent, PictureVisualizationAgent): + portrayal = {"Shape": f"{agent.img}", "scale": 3.0, "Layer": 0} + return portrayal if __name__ == '__main__': base = 512 gridWidth = 10 - gridHeight = 10 + gridHeight = 13 scale = base / gridWidth diagram = GridWithWeights(gridWidth, gridHeight) @@ -66,13 +82,15 @@ if __name__ == '__main__': grid = CanvasGrid(agent_portrayal, gridWidth, gridHeight, scale * gridWidth, scale * gridHeight) readyText = DisplayAttributeElement("phase") - provided_itesm = DisplayAttributeElement("provided_items") - recognised_items = DisplayAttributeElement("recognised_items") - ordersText = DisplayAttributeElement("orderList") - fulfilled_orders = DisplayAttributeElement("fulfilled_orders") + # current_item = DisplayPictureElement("current_item_recognition") + provided_itesm = DisplayItemListAttributeElement("provided_items") + recognised_items = DisplayItemListAttributeElement("recognised_items") + ordersText = DisplayOrderList("orderList") + fulfilled_orders = DisplayOrderList("fulfilled_orders") server = ModularServer(GameModel, - [grid, readyText, provided_itesm, recognised_items, ordersText, fulfilled_orders], + [grid, readyText, provided_itesm, recognised_items, ordersText, + fulfilled_orders], "Automatyczny Wózek Widłowy", {"width": gridHeight, "height": gridWidth, "graph": diagram}, ) diff --git a/visualization/DisplayItemListAttribute.py b/visualization/DisplayItemListAttribute.py new file mode 100644 index 0000000..82b2029 --- /dev/null +++ b/visualization/DisplayItemListAttribute.py @@ -0,0 +1,48 @@ +from collections import Counter +from typing import List + +from mesa.visualization.modules import TextElement + +from data.Item import Item +from data.enum.ItemType import ItemType + + +class DisplayItemListAttributeElement(TextElement): + def __init__(self, attr_name): + ''' + Create a new text attribute element. + + Args: + attr_name: The name of the attribute to extract from the model. + + Example return: "happy: 10" + ''' + self.attr_name = attr_name + + def render(self, model): + val = getattr(model, self.attr_name) + + itemList: List[Item] = val + + itemList = map(lambda x: x.real_type, itemList) + + itemCounter = Counter(itemList) + + # return self.attr_name + ":" + pprint.pformat(itemCounter) + res = self.attr_name + ":" + "" + + return res diff --git a/visualization/DisplayOrderList.py b/visualization/DisplayOrderList.py new file mode 100644 index 0000000..9b06d35 --- /dev/null +++ b/visualization/DisplayOrderList.py @@ -0,0 +1,55 @@ +from collections import Counter +from typing import List + +from mesa.visualization.modules import TextElement + +from data.Order import Order +from data.enum.ItemType import ItemType + + +class DisplayOrderList(TextElement): + def __init__(self, attr_name): + ''' + Create a new text attribute element. + + Args: + attr_name: The name of the attribute to extract from the model. + + Example return: "happy: 10" + ''' + self.attr_name = attr_name + + def render(self, model): + val = getattr(model, self.attr_name) + + orderList: List[Order] = val + + res = self.attr_name + ":
    " + + for o in orderList: + if o is None: + continue + + itemList = map(lambda x: x.real_type, o.items) + itemCounter = Counter(itemList) + + item_str = "" + + res += f"
  1. items: {item_str} priority: {o.priority}
    Client: {vars(o.client_params)}
  2. " + + res += "
" + + return res diff --git a/visualization/DisplayPictureElement.py b/visualization/DisplayPictureElement.py new file mode 100644 index 0000000..6220692 --- /dev/null +++ b/visualization/DisplayPictureElement.py @@ -0,0 +1,21 @@ +from mesa.visualization.modules import TextElement + + +class DisplayPictureElement(TextElement): + def __init__(self, attr_name): + ''' + Create a new text attribute element. + + Args: + attr_name: The name of the attribute to extract from the model. + + Example return: "happy: 10" + ''' + self.attr_name = attr_name + + def render(self, model): + val = getattr(model, self.attr_name) + if val is not None: + return self.attr_name + ': {}'.format(val, self.attr_name) + else: + return ""