SI_InteligentnyWozekWidlowy/GameModel.py

302 lines
11 KiB
Python
Raw Normal View History

2022-05-27 00:03:24 +02:00
import copy
2022-05-22 16:27:36 +02:00
from enum import Enum
2022-05-27 00:18:58 +02:00
from typing import List, Tuple
2022-04-16 14:55:25 +02:00
2022-04-28 01:50:56 +02:00
from mesa import Model
2022-04-08 00:43:25 +02:00
from mesa.space import MultiGrid
from mesa.time import RandomActivation
2022-04-16 14:55:25 +02:00
from AgentBase import AgentBase
2022-04-08 00:43:25 +02:00
from ForkliftAgent import ForkliftAgent
2022-04-28 01:50:56 +02:00
from InitialStateFactory import InitialStateFactory
2022-06-09 21:54:00 +02:00
from ItemDisplayAgent import ItemDisplayAgent
2022-04-08 00:43:25 +02:00
from PatchAgent import PatchAgent
from PatchType import PatchType
2022-05-25 23:51:29 +02:00
from PictureVisualizationAgent import PictureVisualizationAgent
2022-04-28 01:50:56 +02:00
from data.GameConstants import GameConstants
2022-05-22 16:27:36 +02:00
from data.Item import Item
from data.Order import Order
2022-05-27 00:03:24 +02:00
from data.enum.ItemType import ItemType
2022-05-22 16:27:36 +02:00
from decision.Action import Action
2022-04-28 01:50:56 +02:00
from decision.ActionType import ActionType
from genetic_order.GeneticOrder import GeneticOrder
2022-06-02 11:13:21 +02:00
from imageClasification.Classificator import image_classification
2022-04-28 21:22:19 +02:00
from pathfinding.PathfinderOnStates import PathFinderOnStates, PathFinderState
from tree.DecisionTree import DecisionTree
2022-05-27 00:03:24 +02:00
from util.PathByEnum import PathByEnum
2022-04-28 01:50:56 +02:00
from util.PathDefinitions import GridLocation, GridWithWeights
2022-04-08 00:43:25 +02:00
2022-05-22 16:27:36 +02:00
class Phase(Enum):
INIT = 1
ITEM_RECOGNITION = 2
CLIENT_SORTING = 3
PLAN_MOVEMENT = 4
EXECUTION = 5
2022-04-08 00:43:25 +02:00
class GameModel(Model):
2022-06-09 21:54:00 +02:00
def __init__(self, width, height, graph: GridWithWeights, items: int, orders: int, classificator,
item_display_pos: List[GridLocation]):
2022-04-08 00:43:25 +02:00
# self.num_agents = 5
2022-05-22 16:27:36 +02:00
self.first = True
self.item_recognised = False
2022-04-08 00:43:25 +02:00
self.running = True
self.grid = MultiGrid(height, width, True)
self.schedule = RandomActivation(self)
2022-05-25 23:51:29 +02:00
self.current_item_recognition = None
2022-06-10 01:16:43 +02:00
self.current_item = None
2022-04-08 00:43:25 +02:00
2022-05-22 16:27:36 +02:00
self.client_delivery: PatchAgent = None
self.drop_off: PatchAgent = None
self.graph = graph
2022-06-10 01:28:40 +02:00
self.cut_orders : List[Order] = []
2022-04-28 01:50:56 +02:00
self.game_constants = GameConstants(
width,
height,
2022-04-28 14:03:53 +02:00
graph.walls,
2022-05-22 16:27:36 +02:00
graph.puddles
2022-04-28 01:50:56 +02:00
)
2022-05-25 14:33:37 +02:00
self.agents = [AgentBase]
self.forklift_agent = ForkliftAgent(
self,
self.game_constants,
self.client_delivery,
self.drop_off,
self.graph
)
self.schedule.add(self.forklift_agent)
self.agents.append(self.forklift_agent)
2022-06-09 22:36:19 +02:00
self.item_display_agents: List[ItemDisplayAgent] = []
2022-05-25 14:33:37 +02:00
2022-05-22 16:27:36 +02:00
# INITIALIZATION #
print("############## INITIALIZATION ##############")
self.phase = Phase.INIT
2022-06-09 22:36:19 +02:00
self.initialize_grid(graph, item_display_pos)
2022-05-27 00:03:24 +02:00
self.orderList: List[Order] = InitialStateFactory.generate_order_list(orders)
2022-05-25 14:33:37 +02:00
self.fulfilled_orders: List[Order] = []
self.forklift_agent.fulfilled_orders = self.fulfilled_orders
2022-06-10 01:16:43 +02:00
self.forklift_agent.set_base(self.drop_off)
2022-05-27 00:03:24 +02:00
self.classificator = classificator
2022-04-08 00:43:25 +02:00
2022-05-22 16:27:36 +02:00
print("############## RECOGNISE ITEMS ##############")
self.phase = Phase.ITEM_RECOGNITION
2022-05-27 00:03:24 +02:00
self.provided_items = InitialStateFactory.generate_item_list(items)
self.items_for_recognization = copy.deepcopy(self.provided_items)
2022-05-22 16:27:36 +02:00
self.recognised_items: List[Item] = []
2022-06-09 21:33:57 +02:00
self.current_order_delivered_items = self.forklift_agent.current_order_delivered_items
2022-05-22 16:27:36 +02:00
print("Relocate forklift agent to loading area for item recognition")
2022-04-28 01:50:56 +02:00
pathFinder = PathFinderOnStates(
self.game_constants,
2022-05-22 16:27:36 +02:00
self.drop_off.location,
2022-04-28 01:50:56 +02:00
PathFinderState(self.forklift_agent.current_position, self.forklift_agent.current_rotation, 0,
2022-05-22 16:27:36 +02:00
Action(ActionType.NONE), [])
2022-04-28 01:50:56 +02:00
)
2022-04-28 21:22:19 +02:00
actions = pathFinder.get_action_list()
2022-04-28 01:50:56 +02:00
print("PATHFINDING")
print(actions)
2022-04-28 02:09:41 +02:00
self.forklift_agent.queue_movement_actions(actions)
2022-06-10 01:16:43 +02:00
self.current_order = self.forklift_agent.current_order
2022-04-28 01:50:56 +02:00
2022-06-09 22:36:19 +02:00
def initialize_grid(self, graph: GridWithWeights, item_display_pos):
2022-05-22 16:27:36 +02:00
print("INITIALIZING GRID")
# Add the agent to a random grid cell
x = 5
y = 5
self.grid.place_agent(self.forklift_agent, (x, y))
self.forklift_agent.current_position = (x, y)
2022-05-25 23:51:29 +02:00
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)
2022-05-22 16:27:36 +02:00
self.place_logistics()
2022-05-25 23:51:29 +02:00
self.place_dividers()
2022-05-22 16:27:36 +02:00
self.place_walls_agents(graph.walls)
self.place_puddles(graph.puddles)
self.place_packing_stations(graph.packingStations)
2022-06-09 22:36:19 +02:00
self.place_order_items_display(item_display_pos)
2022-05-22 16:27:36 +02:00
2022-05-25 23:51:29 +02:00
def place_dividers(self):
for i in range(0, 10):
2022-05-27 00:03:24 +02:00
for j in range(10, 13):
2022-05-25 23:51:29 +02:00
agent = PatchAgent(self, (i, j), PatchType.divider)
self.agents.append(agent)
self.grid.place_agent(agent, (i, j))
2022-05-22 16:27:36 +02:00
def place_logistics(self):
agent = PatchAgent(self, (self.grid.width - 1, int(self.grid.height / 2)), PatchType.pickUp)
2022-04-16 14:55:25 +02:00
self.schedule.add(agent)
2022-05-22 16:27:36 +02:00
self.grid.place_agent(agent, agent.location)
2022-04-08 00:43:25 +02:00
self.agents.append(agent)
2022-05-22 16:27:36 +02:00
self.client_delivery = agent
2022-05-25 14:33:37 +02:00
self.forklift_agent.client_delivery = self.client_delivery
2022-04-08 00:43:25 +02:00
2022-05-22 16:27:36 +02:00
agent = PatchAgent(self, (0, int(self.grid.height / 2)), PatchType.dropOff)
self.grid.place_agent(agent, agent.location)
2022-04-08 00:43:25 +02:00
self.agents.append(agent)
2022-05-22 16:27:36 +02:00
self.drop_off = agent
2022-05-25 14:33:37 +02:00
self.forklift_agent.drop_off = self.drop_off
2022-04-08 00:43:25 +02:00
2022-04-16 14:55:25 +02:00
def place_walls_agents(self, walls: List[GridLocation]):
for w in walls:
2022-05-22 16:27:36 +02:00
agent = PatchAgent(self, w, PatchType.wall)
2022-04-16 14:55:25 +02:00
self.agents.append(agent)
self.grid.place_agent(agent, w)
2022-04-28 14:03:53 +02:00
def place_puddles(self, puddles: List[GridLocation]):
for p in puddles:
2022-05-22 16:27:36 +02:00
agent = PatchAgent(self, p, PatchType.diffTerrain)
2022-04-28 14:03:53 +02:00
self.agents.append(agent)
self.grid.place_agent(agent, p)
2022-05-27 00:18:58 +02:00
def place_packing_stations(self, packing_stations: List[Tuple[PatchType, GridLocation]]):
2022-05-22 16:27:36 +02:00
for p in packing_stations:
agent = PatchAgent(self, p[1], p[0])
self.agents.append(agent)
self.grid.place_agent(agent, p[1])
2022-06-09 21:54:00 +02:00
def place_order_items_display(self, item_positions: List[GridLocation]):
for p in item_positions:
agent = ItemDisplayAgent(self, p)
2022-06-09 22:36:19 +02:00
self.item_display_agents.append(agent)
2022-06-09 21:54:00 +02:00
self.grid.place_agent(agent, p)
2022-06-09 22:36:19 +02:00
def update_item_display(self):
2022-06-10 01:16:43 +02:00
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
2022-06-09 22:36:19 +02:00
2022-04-08 00:43:25 +02:00
def step(self):
self.schedule.step()
self.grid.remove_agent(self.forklift_agent)
self.grid.place_agent(self.forklift_agent, self.forklift_agent.current_position)
2022-06-09 22:36:19 +02:00
self.update_item_display()
2022-05-22 16:27:36 +02:00
if self.phase == Phase.ITEM_RECOGNITION:
if not self.item_recognised and self.forklift_agent.current_position == self.drop_off.location:
2022-05-27 00:03:24 +02:00
if len(self.items_for_recognization) == 0:
2022-05-22 16:27:36 +02:00
print("FINISHED ITEM RECOGNITION")
self.item_recognised = True
self.phase = Phase.CLIENT_SORTING
2022-05-27 00:03:24 +02:00
self.forklift_agent.ready_for_execution = True
2022-05-22 16:27:36 +02:00
else:
2022-05-27 00:03:24 +02:00
print("BEGIN ITEM RECOGNITION, left: {}".format(len(self.items_for_recognization)))
item_to_recognise = self.items_for_recognization.pop()
self.picture_visualization.img = PathByEnum.get_random_path(item_to_recognise.real_type)
2022-05-22 16:27:36 +02:00
recognised = self.recognise_item(item_to_recognise)
self.recognised_items.append(recognised)
if self.phase == Phase.CLIENT_SORTING:
orders: [Order] = self.orderList
tree: DecisionTree = DecisionTree()
# CLIENT RECOGNITION
orders_with_prio = tree.get_data_good(orders)
# print("before:" )
# for i in range(len(orders_with_prio)):
# print("ORDER {}, PRIO: {}".format(orders_with_prio[i].id, orders_with_prio[i].priority))
# GENERICS SORTING
genericOrder: GeneticOrder = GeneticOrder(orders_with_prio)
new_orders = genericOrder.get_orders_sorted(orders)
# print("after:" )
# for i in range(len(new_orders)):
# print("ORDER {}, PRIO: {}".format(new_orders[i].id, new_orders[i].priority))
self.orderList = new_orders
self.count_recognised_items()
self.sort_orders()
2022-06-10 01:16:43 +02:00
self.forklift_agent.orderList = self.orderList
2022-05-22 16:27:36 +02:00
print("FINISHED CLIENT ORDER SORTING")
2022-05-25 14:33:37 +02:00
self.phase = Phase.EXECUTION
2022-05-22 16:27:36 +02:00
if self.phase == Phase.EXECUTION:
2022-06-10 01:16:43 +02:00
self.current_order = self.forklift_agent.current_order
pass
# print("Execution")
2022-05-22 16:27:36 +02:00
def sort_orders(self):
orders_to_fill: [Order] = []
cut_orders: [Order] = []
for i in range(len(self.orderList)):
o: Order = self.orderList[i]
refrige = self.count_item_type(o, ItemType.REFRIGERATOR)
shelf = self.count_item_type(o, ItemType.SHELF)
door = self.count_item_type(o, ItemType.DOOR)
if self.count_shelf - shelf >= 0 and self.count_refrige - refrige >= 0 and self.count_door - door >= 0:
self.count_shelf -= shelf
self.count_door -= door
self.count_refrige -= refrige
orders_to_fill.append(o)
else:
cut_orders.append(o)
self.cut_orders = cut_orders
self.orderList = orders_to_fill
self.forklift_agent.orderList = orders_to_fill
def count_item_type(self, o: Order, itemType: ItemType) -> int:
res = 0
for i in range(len(o.items)):
it: Item = o.items[i]
if it.guessed_type == itemType:
res += 1
return res
def count_recognised_items(self):
count_refrige: int = 0
count_door: int = 0
count_shelf: int = 0
for i in range(len(self.recognised_items)):
item: Item = self.recognised_items[i]
if item.guessed_type == ItemType.DOOR:
count_door += 1
elif item.guessed_type == ItemType.SHELF:
count_shelf += 1
else:
count_refrige += 1
self.count_door = count_door
self.count_shelf = count_shelf
self.count_refrige = count_refrige
2022-05-22 16:27:36 +02:00
def recognise_item(self, item: Item):
2022-06-02 11:13:21 +02:00
val = image_classification(self.picture_visualization.img, self.classificator)
2022-05-27 00:03:24 +02:00
print("VAL: {}".format(val))
if val == ItemType.DOOR:
item.guessed_type = ItemType.DOOR
2022-06-02 11:13:21 +02:00
elif val == ItemType.REFRIGERATOR:
item.guessed_type = ItemType.REFRIGERATOR
2022-05-27 00:03:24 +02:00
elif val == ItemType.SHELF:
item.guessed_type = ItemType.SHELF
2022-05-22 16:27:36 +02:00
return item