SI_InteligentnyWozekWidlowy/GameModel.py
2022-06-02 11:11:57 +02:00

202 lines
7.3 KiB
Python

import copy
from enum import Enum
from typing import List, Tuple
from mesa import Model
from mesa.space import MultiGrid
from mesa.time import RandomActivation
from AgentBase import AgentBase
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
from data.enum.ItemType import ItemType
from decision.Action import Action
from decision.ActionType import ActionType
from pathfinding.PathfinderOnStates import PathFinderOnStates, PathFinderState
from util.PathByEnum import PathByEnum
from util.PathDefinitions import GridLocation, GridWithWeights
class Phase(Enum):
INIT = 1
ITEM_RECOGNITION = 2
CLIENT_SORTING = 3
PLAN_MOVEMENT = 4
EXECUTION = 5
class GameModel(Model):
def __init__(self, width, height, graph: GridWithWeights, items: int, orders: int, classificator):
# self.num_agents = 5
self.first = True
self.item_recognised = False
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
self.graph = graph
self.game_constants = GameConstants(
width,
height,
graph.walls,
graph.puddles
)
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)
# INITIALIZATION #
print("############## INITIALIZATION ##############")
self.phase = Phase.INIT
self.initialize_grid(graph)
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.classificator = classificator
print("############## RECOGNISE ITEMS ##############")
self.phase = Phase.ITEM_RECOGNITION
self.provided_items = InitialStateFactory.generate_item_list(items)
self.items_for_recognization = copy.deepcopy(self.provided_items)
self.recognised_items: List[Item] = []
print("Relocate forklift agent to loading area for item recognition")
pathFinder = PathFinderOnStates(
self.game_constants,
self.drop_off.location,
PathFinderState(self.forklift_agent.current_position, self.forklift_agent.current_rotation, 0,
Action(ActionType.NONE), [])
)
actions = pathFinder.get_action_list()
print("PATHFINDING")
print(actions)
self.forklift_agent.queue_movement_actions(actions)
def initialize_grid(self, graph: GridWithWeights):
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)
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)
self.grid.place_agent(agent, agent.location)
self.agents.append(agent)
self.client_delivery = agent
self.forklift_agent.client_delivery = self.client_delivery
agent = PatchAgent(self, (0, int(self.grid.height / 2)), PatchType.dropOff)
self.grid.place_agent(agent, agent.location)
self.agents.append(agent)
self.drop_off = agent
self.forklift_agent.drop_off = self.drop_off
def place_walls_agents(self, walls: List[GridLocation]):
for w in walls:
agent = PatchAgent(self, w, PatchType.wall)
self.agents.append(agent)
self.grid.place_agent(agent, w)
def place_puddles(self, puddles: List[GridLocation]):
for p in puddles:
agent = PatchAgent(self, p, PatchType.diffTerrain)
self.agents.append(agent)
self.grid.place_agent(agent, p)
def place_packing_stations(self, packing_stations: List[Tuple[PatchType, GridLocation]]):
for p in packing_stations:
agent = PatchAgent(self, p[1], p[0])
self.agents.append(agent)
self.grid.place_agent(agent, p[1])
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)
if self.phase == Phase.ITEM_RECOGNITION:
if not self.item_recognised and self.forklift_agent.current_position == self.drop_off.location:
if len(self.items_for_recognization) == 0:
print("FINISHED ITEM RECOGNITION")
self.item_recognised = True
self.phase = Phase.CLIENT_SORTING
self.forklift_agent.ready_for_execution = True
else:
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)
recognised = self.recognise_item(item_to_recognise)
self.recognised_items.append(recognised)
if self.phase == Phase.CLIENT_SORTING:
# TODO GENERICS SORTING
sorted(self.orderList, key=lambda x: len(x.items))
print("FINISHED CLIENT ORDER SORTING")
self.phase = Phase.EXECUTION
if self.phase == Phase.EXECUTION:
print("Execution")
def recognise_item(self, item: Item):
# TODO IMAGE PROCESSING
val = self.classificator.image_clasification(self.picture_visualization.img)
print("VAL: {}".format(val))
if val == ItemType.DOOR:
item.guessed_type = ItemType.DOOR
elif val == ItemType.FRIDGE:
item.guessed_type = ItemType.FRIDGE
elif val == ItemType.SHELF:
item.guessed_type = ItemType.SHELF
return item