rework of forklift agent loop

This commit is contained in:
Aleksander Szamałek 2022-06-10 01:16:43 +02:00
parent b37847b304
commit 5004058725
5 changed files with 148 additions and 115 deletions

View File

@ -1,8 +1,10 @@
from copy import deepcopy
from typing import Tuple, List
from AgentBase import AgentBase
from PatchAgent import PatchAgent
from PatchType import PatchType
from data.GameConstants import GameConstants
from data.Item import Item
from data.Order import Order
from data.enum.Direction import Direction
@ -16,7 +18,7 @@ from util.PathDefinitions import GridLocation, GridWithWeights
class ForkliftAgent(AgentBase):
def __init__(self, model, game_constants, client_delivery: PatchAgent, drop_off: PatchAgent,
def __init__(self, model, game_constants: GameConstants, client_delivery: PatchAgent, drop_off: PatchAgent,
graph: GridWithWeights):
super().__init__(model)
self.action_queue: List[Action] = []
@ -28,11 +30,20 @@ class ForkliftAgent(AgentBase):
self.drop_off: PatchAgent = drop_off
self.graph = graph
self.game_constants = game_constants
self.current_order: Order = None
self.current_item = None
self.item_station_completed = False
self.current_order_delivered_items: List[Item] = []
self.ready_for_execution = False
self.last_delviered_item = None
self.current_item: Item = None
self.current_order = None
self.base: GridLocation = None
self.goal: GridLocation = None
def set_base(self, drop_off: PatchAgent):
self.drop_off = drop_off
self.base = self.drop_off.location
self.goal = self.base
def queue_movement_actions(self, movement_actions: List[Action]):
self.action_queue.extend(movement_actions)
@ -43,120 +54,94 @@ class ForkliftAgent(AgentBase):
action_type = action.action_type
if action_type == ActionType.ROTATE_UP:
print("rotate {} --> {}".format(self.current_rotation, action_type))
# print("rotate {} --> {}".format(self.current_rotation, action_type))
self.current_rotation = Direction.top
elif action_type == ActionType.ROTATE_RIGHT:
print("rotate {} --> {}".format(self.current_rotation, action_type))
# print("rotate {} --> {}".format(self.current_rotation, action_type))
self.current_rotation = Direction.right
elif action_type == ActionType.ROTATE_DOWN:
print("rotate {} --> {}".format(self.current_rotation, action_type))
# print("rotate {} --> {}".format(self.current_rotation, action_type))
self.current_rotation = Direction.down
elif action_type == ActionType.ROTATE_LEFT:
print("rotate {} --> {}".format(self.current_rotation, action_type))
# print("rotate {} --> {}".format(self.current_rotation, action_type))
self.current_rotation = Direction.left
elif action_type == ActionType.MOVE:
if self.current_rotation == Direction.top:
print("move {} --> {}".format(self.current_position, action_type))
# print("move {} --> {}".format(self.current_position, action_type))
self.current_position = (self.current_position[0], self.current_position[1] + 1)
elif self.current_rotation == Direction.down:
print("move {} --> {}".format(self.current_position, action_type))
# print("move {} --> {}".format(self.current_position, action_type))
self.current_position = (self.current_position[0], self.current_position[1] - 1)
elif self.current_rotation == Direction.right:
print("move {} --> {}".format(self.current_position, action_type))
# print("move {} --> {}".format(self.current_position, action_type))
self.current_position = (self.current_position[0] + 1, self.current_position[1])
elif self.current_rotation == Direction.left:
print("move {} --> {}".format(self.current_position, action_type))
# print("move {} --> {}".format(self.current_position, action_type))
self.current_position = (self.current_position[0] - 1, self.current_position[1])
def plan_actions(self):
if len(self.current_order.items) > 0:
i = self.current_order.items.pop(0)
if self.current_item is None:
self.current_order_delivered_items.clear()
self.current_item = i
print("PLAN MOVEMENT")
# get item
def step(self) -> None:
if len(self.action_queue) > 0:
self.move()
elif self.ready_for_execution:
if self.current_position != self.goal:
pathFinder = PathFinderOnStates(
self.game_constants,
self.drop_off.location,
PathFinderState(self.current_position,
self.current_rotation,
0,
Action(ActionType.NONE),
[])
)
actions = pathFinder.get_action_list()
self.queue_movement_actions(actions)
elif not self.item_station_completed:
# go through station
packing_station: GridLocation = None
stations = dict(self.graph.packingStations)
if i.real_type == ItemType.SHELF:
packing_station = stations[PatchType.packingShelf]
elif i.real_type == ItemType.REFRIGERATOR:
packing_station = stations[PatchType.packingRefrigerator]
elif i.real_type == ItemType.DOOR:
packing_station = stations[PatchType.packingC]
pathFinder = PathFinderOnStates(
self.game_constants,
packing_station,
self.goal,
PathFinderState(self.current_position,
self.current_rotation,
0,
Action(
desired_item=i,
desired_item=None,
action_type=ActionType.PICK_ITEM
),
[])
)
actions = pathFinder.get_action_list()
self.queue_movement_actions(actions)
self.item_station_completed = True
else:
# go to client delivery area
pathFinder = PathFinderOnStates(
self.game_constants,
self.client_delivery.location,
PathFinderState(self.current_position,
self.current_rotation,
0,
Action(ActionType.NONE),
[])
)
actions = pathFinder.get_action_list()
self.queue_movement_actions(actions)
self.queue_movement_actions(
[Action(ActionType.DROP_ITEM)]
)
if self.current_order is not None and self.goal == self.base:
self.current_item = self.current_order.items.pop(0)
packing_station: GridLocation = None
stations = dict(self.graph.packingStations)
self.current_order_delivered_items.append(self.current_item)
self.current_item = None
self.item_station_completed = False
if self.current_item.real_type == ItemType.SHELF:
packing_station = stations[PatchType.packingShelf]
elif self.current_item.real_type == ItemType.REFRIGERATOR:
packing_station = stations[PatchType.packingRefrigerator]
elif self.current_item.real_type == ItemType.DOOR:
packing_station = stations[PatchType.packingDoor]
def step(self) -> None:
if len(self.action_queue) > 0:
self.move()
elif self.ready_for_execution and len(self.orderList) > 0:
if (self.current_order is not None and len(self.current_order.items)) == 0:
self.fulfilled_orders.append(self.current_order)
self.current_order = None
self.goal = packing_station
if self.current_order is None:
self.current_order = self.orderList.pop(0)
elif self.goal in [i[1] for i in self.graph.packingStations]:
self.goal = self.client_delivery.location
self.plan_actions()
elif self.goal == self.client_delivery.location:
if self.current_order is not None and len(self.current_order.items) == 0:
self.current_order_delivered_items.append(self.current_item)
self.current_order.items = deepcopy(self.current_order_delivered_items)
self.fulfilled_orders.append(self.current_order)
self.current_item = None
self.current_order = None
self.goal = self.base
else:
self.current_order_delivered_items.append(self.current_item)
self.goal = self.base
self.current_item = None
elif self.goal == self.base and self.current_order is None:
self.current_order_delivered_items.clear()
self.current_order = self.orderList.pop(0)
def creation_log(self):
print("Created Forklift Agent [id: {}]".format(self.unique_id))

View File

@ -47,6 +47,7 @@ class GameModel(Model):
self.grid = MultiGrid(height, width, True)
self.schedule = RandomActivation(self)
self.current_item_recognition = None
self.current_item = None
self.client_delivery: PatchAgent = None
self.drop_off: PatchAgent = None
@ -79,8 +80,8 @@ class GameModel(Model):
self.initialize_grid(graph, item_display_pos)
self.orderList: List[Order] = InitialStateFactory.generate_order_list(orders)
self.fulfilled_orders: List[Order] = []
self.forklift_agent.orderList = self.orderList
self.forklift_agent.fulfilled_orders = self.fulfilled_orders
self.forklift_agent.set_base(self.drop_off)
self.classificator = classificator
print("############## RECOGNISE ITEMS ##############")
@ -104,6 +105,7 @@ class GameModel(Model):
print("PATHFINDING")
print(actions)
self.forklift_agent.queue_movement_actions(actions)
self.current_order = self.forklift_agent.current_order
def initialize_grid(self, graph: GridWithWeights, item_display_pos):
print("INITIALIZING GRID")
@ -174,9 +176,11 @@ class GameModel(Model):
self.grid.place_agent(agent, p)
def update_item_display(self):
for index, item in enumerate(self.forklift_agent.current_order_delivered_items):
if item is not None:
self.item_display_agents[index].image = item.image
self.current_item = self.forklift_agent.current_item
for i in range(4):
self.item_display_agents[i].image = None
if len(self.forklift_agent.current_order_delivered_items) > i:
self.item_display_agents[i].image = self.forklift_agent.current_order_delivered_items[i].image
def step(self):
self.schedule.step()
@ -219,12 +223,15 @@ class GameModel(Model):
# print("ORDER {}, PRIO: {}".format(new_orders[i].id, new_orders[i].priority))
self.orderList = new_orders
self.forklift_agent.orderList = self.orderList
print("FINISHED CLIENT ORDER SORTING")
self.phase = Phase.EXECUTION
if self.phase == Phase.EXECUTION:
print("Execution")
self.current_order = self.forklift_agent.current_order
pass
# print("Execution")
def recognise_item(self, item: Item):
val = image_classification(self.picture_visualization.img, self.classificator)

19
main.py
View File

@ -1,4 +1,3 @@
import math
import random
from mesa.visualization.ModularVisualization import ModularServer
@ -7,20 +6,15 @@ from tensorflow import keras
from ForkliftAgent import ForkliftAgent
from GameModel import GameModel
from InitialStateFactory import InitialStateFactory
from ItemDisplayAgent import ItemDisplayAgent
from PatchAgent import PatchAgent
from PatchType import PatchType
from PictureVisualizationAgent import PictureVisualizationAgent
from data.Order import Order
from data.enum.Direction import Direction
from tensorflow import keras
from data.enum.Priority import Priority
from genetic_order.GeneticOrder import GeneticOrder
from util.PathDefinitions import GridWithWeights
from visualization.DisplayAttributeElement import DisplayAttributeElement
from visualization.DisplayItemListAttribute import DisplayItemListAttributeElement
from visualization.DisplayOrder import DisplayOrder
from visualization.DisplayOrderList import DisplayOrderList
colors = [
@ -104,26 +98,27 @@ if __name__ == '__main__':
diagram = GridWithWeights(gridWidth, gridHeight)
diagram.walls = [(6, 5), (6, 6), (6, 7), (6, 8), (2, 3), (2, 4), (3, 4), (4, 4), (6, 4)]
diagram.puddles = [(2, 2), (2, 5), (2, 6), (5, 4)]
diagram.packingStations = [(PatchType.packingShelf, (4, 8)), (PatchType.packingRefrigerator, (4, 6)), (PatchType.packingDoor, (4, 2))]
diagram.packingStations = [(PatchType.packingShelf, (4, 8)), (PatchType.packingRefrigerator, (4, 6)),
(PatchType.packingDoor, (4, 2))]
grid = CanvasGrid(agent_portrayal, gridWidth, gridHeight, scale * gridWidth, scale * gridHeight)
display_items = [(6, 11), (7, 11), (8, 11), (9, 11)]
readyText = DisplayAttributeElement("phase")
# current_item = DisplayPictureElement("current_item_recognition")
provided_itesm = DisplayItemListAttributeElement("provided_items")
recognised_items = DisplayItemListAttributeElement("recognised_items")
current_order = DisplayOrder("current_order")
current_item = DisplayAttributeElement("current_item")
ordersText = DisplayOrderList("orderList")
fulfilled_orders = DisplayOrderList("fulfilled_orders")
model = keras.models.load_model("imageClasification/my_model")
server = ModularServer(GameModel,
[grid, readyText, provided_itesm, recognised_items, ordersText,
fulfilled_orders],
[grid, readyText, current_item, current_order, fulfilled_orders, ordersText],
"Automatyczny Wózek Widłowy",
dict(width=gridHeight, height=gridWidth, graph=diagram, items=50, orders=3,
dict(width=gridHeight, height=gridWidth, graph=diagram, items=60, orders=20,
classificator=model, item_display_pos=display_items))
server.port = 8888

View File

@ -0,0 +1,46 @@
from collections import Counter
from typing import List
from mesa.visualization.modules import TextElement
from data.Order import Order
class DisplayOrder(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)
res = self.attr_name
if val is not None:
o = val
itemList = map(lambda x: x.real_type, o.items)
itemCounter = Counter(itemList)
item_str = "<ul>"
for e in itemCounter:
key = e
val = itemCounter[key]
# key_str = ""
# if key == ItemType.DOOR:
# key_str = "Door"
# elif key == ItemType.SHELF:
# key_str = "Shelf"
item_str += f"<li>{str(key)}:{str(val)}</li>"
item_str += "</ul>"
res += f"<li> items: {item_str} priority: {o.priority} <br> Client: {vars(o.client_params)} </li>"
return res

View File

@ -4,7 +4,6 @@ from typing import List
from mesa.visualization.modules import TextElement
from data.Order import Order
from data.enum.ItemType import ItemType
class DisplayOrderList(TextElement):
@ -21,35 +20,36 @@ class DisplayOrderList(TextElement):
def render(self, model):
val = getattr(model, self.attr_name)
res = ""
if val is not None:
orderList: List[Order] = val
orderList: List[Order] = val
res = self.attr_name + ": <ol>"
res = self.attr_name + ": <ol>"
for o in orderList:
if o is None:
continue
for o in orderList:
if o is None:
continue
itemList = map(lambda x: x.real_type, o.items)
itemCounter = Counter(itemList)
itemList = map(lambda x: x.real_type, o.items)
itemCounter = Counter(itemList)
item_str = "<ul>"
for e in itemCounter:
key = e
val = itemCounter[key]
item_str = "<ul>"
for e in itemCounter:
key = e
val = itemCounter[key]
# key_str = ""
# if key == ItemType.DOOR:
# key_str = "Door"
# elif key == ItemType.SHELF:
# key_str = "Shelf"
# key_str = ""
# if key == ItemType.DOOR:
# key_str = "Door"
# elif key == ItemType.SHELF:
# key_str = "Shelf"
item_str += f"<li>{str(key)}:{str(val)}</li>"
item_str += f"<li>{str(key)}:{str(val)}</li>"
item_str += "</ul>"
item_str += "</ul>"
res += f"<li> items: {item_str} priority: {o.priority} <br> Client: {vars(o.client_params)} </li>"
res += f"<li> items: {item_str} priority: {o.priority} <br> Client: {vars(o.client_params)} </li>"
res += "</ol>"
res += "</ol>"
return res