waiter recognizes images, checks prediction, serves dish with correlated table

This commit is contained in:
= 2020-05-17 02:22:51 +02:00
parent 723568cf31
commit 23b85d2549
8 changed files with 167 additions and 97 deletions

View File

@ -34,7 +34,6 @@ load_model_thread.start()
# joining this thread to main thread. Man thread will be started after this finish # joining this thread to main thread. Man thread will be started after this finish
load_model_thread.join() load_model_thread.join()
# initialize drawable objects manager # initialize drawable objects manager
drawableManager = DrawableCollection() drawableManager = DrawableCollection()

View File

@ -5,7 +5,6 @@ import numpy as np
import kelner.src.settings as settings import kelner.src.settings as settings
class Predictor: class Predictor:
def __init__(self, food_list): def __init__(self, food_list):
self._food_list = food_list self._food_list = food_list
@ -26,7 +25,6 @@ class Predictor:
print("THIS IS A:{}".format(pred_value)) print("THIS IS A:{}".format(pred_value))
def predict_class(self, img): def predict_class(self, img):
img = image.load_img(img, target_size=(224, 224)) img = image.load_img(img, target_size=(224, 224))
img = image.img_to_array(img) img = image.img_to_array(img)
img = np.expand_dims(img, axis=0) img = np.expand_dims(img, axis=0)
@ -38,3 +36,4 @@ class Predictor:
pred_value = self._food_list[index] pred_value = self._food_list[index]
# print("Pred: {}, index: {}, pred_value:{}".format(pred, index, pred_value)) # print("Pred: {}, index: {}, pred_value:{}".format(pred, index, pred_value))
print("THIS IS A:{}".format(pred_value)) print("THIS IS A:{}".format(pred_value))
return pred_value

View File

@ -11,7 +11,7 @@ class Drawable:
self.__x = x self.__x = x
self.__y = y self.__y = y
self.__cellSize = cellSize # cell size in pixels self.__cellSize = cellSize # cell size in pixels
self.__offset = offset # paint offset in pixels self.__offset = offset # paint offset in pixels
def setX(self, x): def setX(self, x):
if x < self.__minX or self.__maxX < x: if x < self.__minX or self.__maxX < x:
@ -36,6 +36,9 @@ class Drawable:
def getY(self): def getY(self):
return self.__y return self.__y
def get_posistion(self):
return self.getX(), self.getY()
def getMinX(self): def getMinX(self):
return self.__minX return self.__minX

View File

@ -5,12 +5,13 @@ from kelner.src.components.Drawable import Drawable
from kelner.src.managers.ImageCache import ImageCache, Images from kelner.src.managers.ImageCache import ImageCache, Images
from kelner.src.algorithms.DecisionTree import Tree_Builder from kelner.src.algorithms.DecisionTree import Tree_Builder
# status of the table # status of the table
class Status(Enum): class Status(Enum):
NotReady = 0 NotReady = 0
Ready = 1 Ready = 1
Waiting = 2 Waiting = 2
Served = 3 Served = 3
class Table(Drawable): class Table(Drawable):
@ -24,17 +25,16 @@ class Table(Drawable):
self.__tableLock = Lock() self.__tableLock = Lock()
self.__zainteresowania = [] self.__zainteresowania = []
# Build a Decision Tree # Build a Decision Tree
self.Decision_Tree = Tree_Builder.build_tree(Tree_Builder.training_db) self.Decision_Tree = Tree_Builder.build_tree(Tree_Builder.training_db)
#Generates Hobbys # Generates Hobbys
for a in range(len(self.__guests)): for a in range(len(self.__guests)):
sport = random.randint(0,1) sport = random.randint(0, 1)
czytanie = random.randint(0,1) czytanie = random.randint(0, 1)
lucznictwo = random.randint(0,1) lucznictwo = random.randint(0, 1)
boks = random.randint(0,1) boks = random.randint(0, 1)
self.__zainteresowania.append([sport,czytanie,lucznictwo,boks, "A"]) self.__zainteresowania.append([sport, czytanie, lucznictwo, boks, "A"])
##def getOrder(self): ##def getOrder(self):
## # Generates order ## # Generates order
@ -54,7 +54,7 @@ class Table(Drawable):
return guests return guests
# waiter collects orders from table # waiter collects orders from table
#def getOrder(self): # def getOrder(self):
# order = None # order = None
# if self.__tableLock.acquire(False): # if self.__tableLock.acquire(False):
# try: # try:
@ -87,9 +87,7 @@ class Table(Drawable):
def get_order(self): def get_order(self):
return self.__order return self.__order
# def getOrder(self):
#def getOrder(self):
# order = None # order = None
# if self.__tableLock.acquire(False): # if self.__tableLock.acquire(False):
# try: # try:

View File

@ -4,14 +4,14 @@ from kelner.src.managers.ImageCache import ImageCache, Images
class Direction: class Direction:
LeftUp = (-1,-1) LeftUp = (-1, -1)
Up = ( 0,-1) Up = (0, -1)
RightUp = ( 1,-1) RightUp = (1, -1)
Right = ( 1, 0) Right = (1, 0)
RightDown = ( 1, 1) RightDown = (1, 1)
Down = ( 0, 1) Down = (0, 1)
LeftDown = (-1, 1) LeftDown = (-1, 1)
Left = (-1, 0) Left = (-1, 0)
class Waiter(Drawable): class Waiter(Drawable):
@ -25,6 +25,8 @@ class Waiter(Drawable):
self.__currentPath = [] self.__currentPath = []
self._ready = True self._ready = True
self._target = 'table' self._target = 'table'
self._remaining_targets = []
self._remaining_positions = []
def moveUp(self): def moveUp(self):
if self.getY() > self.getMinY(): if self.getY() > self.getMinY():
@ -77,7 +79,6 @@ class Waiter(Drawable):
def getDirection(self): def getDirection(self):
return self.__dx, self.__dy return self.__dx, self.__dy
def setDirection(self, dx, dy): def setDirection(self, dx, dy):
self.__dx = dx self.__dx = dx
self.__dy = dy self.__dy = dy
@ -135,7 +136,6 @@ class Waiter(Drawable):
def clear_accepted_orders(self): def clear_accepted_orders(self):
self.__acceptedOrders.clear() self.__acceptedOrders.clear()
def draw(self, screen): def draw(self, screen):
direction = self.getDirection() direction = self.getDirection()
imageKind = None imageKind = None
@ -186,3 +186,15 @@ class Waiter(Drawable):
def set_target(self, target): def set_target(self, target):
self._target = target self._target = target
def add_remaining_target(self, target):
self._remaining_targets.append(target)
def get_remaining_targets(self):
return self._remaining_targets
def add_remaining_position(self, target):
self._remaining_positions.append(target)
def get_remaining_positions(self):
return self._remaining_positions

View File

@ -101,8 +101,8 @@ class DrawableCollection:
nearestTables = [] nearestTables = []
tables = self.getTables(tableStatus) tables = self.getTables(tableStatus)
for table in tables: for table in tables:
if (table.getX() == waiter.getX() and abs(table.getY() - waiter.getY()) == 1) or\ if (table.getX() == waiter.getX() and abs(table.getY() - waiter.getY()) == 1) or \
(table.getY() == waiter.getY() and abs(table.getX() - waiter.getX()) == 1): (table.getY() == waiter.getY() and abs(table.getX() - waiter.getX()) == 1):
nearestTables.append(table) nearestTables.append(table)
return nearestTables return nearestTables

View File

@ -12,21 +12,31 @@ class TableManager(threading.Thread):
self.__drawableManager = drawableManager self.__drawableManager = drawableManager
self.__menuManager = menuManager self.__menuManager = menuManager
self.__runThread = True self.__runThread = True
self._active = True
# changes the status of a random table from NotReady to Ready # changes the status of a random table from NotReady to Ready
def run(self): def run(self):
while self.__runThread: while self.__runThread:
tables = self.__drawableManager.getTables(Status.NotReady) tables = self.__drawableManager.getTables(Status.NotReady)
if tables: if not self._active:
tableIndex = random.randint(0, len(tables) - 1)
table = tables[tableIndex]
time.sleep(5) time.sleep(5)
table.setOrder(self.__menuManager.generateOrder()) else:
table.setStatus(Status.Ready) if tables:
self.__drawableManager.forceRepaint() tableIndex = random.randint(0, len(tables) - 1)
table = tables[tableIndex]
time.sleep(7)
table.setOrder(self.__menuManager.generateOrder())
table.setStatus(Status.Ready)
self.__drawableManager.forceRepaint()
def stop(self): def get_table(self, position):
self.__runThread = False tables = self.__drawableManager.getTables(Status.Waiting)
for table in tables:
if (table.getX(), table.getY()) == position:
return table
def pause(self):
self._active = False
def resume(self): def resume(self):
self.__runThread = True self._active = True

View File

@ -23,29 +23,41 @@ class WaiterManager(threading.Thread):
def __getNearestTargetPath(self, waiter, target): def __getNearestTargetPath(self, waiter, target):
distance = sys.maxsize distance = sys.maxsize
nearestTargetPath = None nearestTargetPath = None
reservedPlaces = self.__drawableManager.getReservedPlaces(waiter)
tables = self.__drawableManager.getTables(Status.Ready) tables = self.__drawableManager.getTables(Status.Ready)
finder = Finder(reservedPlaces)
origin = (waiter.getX(), waiter.getY())
if target == 'kitchen':
path = finder.getPath(origin, (14, 1), True)
path2 = finder.getPath(origin, (13, 0), True)
path = path2 if len(path) > len(path2) else path
return path
if tables: if tables:
reservedPlaces = self.__drawableManager.getReservedPlaces(waiter) for table in tables:
finder = Finder(reservedPlaces) if table.hasOrder():
origin = (waiter.getX(), waiter.getY()) targets = finder.getNeighbours((table.getX(), table.getY()), False)
if target == 'kitchen': for target in targets:
path = finder.getPath(origin, (14, 1), True) if target is not None:
path2 = finder.getPath(origin, (13, 0), True) path = finder.getPath(origin, target, True)
path = path2 if len(path) > len(path2) else path if path:
else: result = len(path)
for table in tables: if result < distance:
if table.hasOrder(): distance = result
targets = finder.getNeighbours((table.getX(), table.getY()), False) nearestTargetPath = path
for target in targets:
if target is not None:
path = finder.getPath(origin, target, True)
if path:
result = len(path)
if result < distance:
distance = result
nearestTargetPath = path
return nearestTargetPath return nearestTargetPath
def get_specified_path(self, waiter, table):
reserved_places = self.__drawableManager.getReservedPlaces(waiter)
finder = Finder(reserved_places)
origin = (waiter.getX(), waiter.getY())
targets = finder.getNeighbours((table[0], table[1]), False)
for target in targets:
if target is not None:
path = finder.getPath(origin, target, True)
if path:
return path
def __changeWaiterDirection(self, waiter, x, y): def __changeWaiterDirection(self, waiter, x, y):
targetDirection = x - waiter.getX(), y - waiter.getY() targetDirection = x - waiter.getX(), y - waiter.getY()
originDirection = waiter.getDirection() originDirection = waiter.getDirection()
@ -107,22 +119,74 @@ class WaiterManager(threading.Thread):
print("Ready to go") print("Ready to go")
return ready_orders return ready_orders
def predict_orders(self, orders, waiter): def predict_order(self, order, kitchen):
pass food_list = self._menu_manager.get_menu()
image_predictor = Predictor(food_list)
paths = self._kitchen_manager.draw_single_order(order, kitchen)
predicted_dishes = []
self._kitchen_manager.run()
self._table_manager.pause()
# print("Printed images paths: {}".format(paths))
if paths is not None:
for img_path in paths:
predicted_dish = image_predictor.predict_class(img_path)
predicted_dishes.append(predicted_dish)
self.__drawableManager.forceRepaint()
return predicted_dishes
def match_predicted_orders(self, predicted_orders):
all_tables = self.__drawableManager.getTables(Status.Waiting)
located_orders = dict()
for p_order in predicted_orders:
p_order.sort()
for table in all_tables:
table_dishes = table.get_order()
table_dishes.sort()
if p_order == table_dishes:
located_orders[table] = p_order
return located_orders
def get_order_targets(self, orders):
targets = dict()
for table, dishes in orders.items():
targets[table.get_posistion()] = dishes
return targets
def set_next_waiter_targets(self, waiter, matched_targets):
for table in matched_targets.keys():
path = self.get_specified_path(waiter, table)
waiter.add_remaining_target(path)
def set_next_waiter_positions(self, waiter, matched_positions):
for position in matched_positions.keys():
waiter.add_remaining_position(position)
# changes the status of a random table from NotReady to Ready # changes the status of a random table from NotReady to Ready
def run(self): def run(self):
while self.__runThread: while self.__runThread:
if self.__waiters: if self.__waiters:
for waiter in self.__waiters: for waiter in self.__waiters:
if len(waiter.getAcceptedOrders()) > 0:
if len(waiter.getAcceptedOrders()) > 1:
waiter.set_target('kitchen') waiter.set_target('kitchen')
path = self.__getNearestTargetPath(waiter, target=waiter.get_target()) path = self.__getNearestTargetPath(waiter, target=waiter.get_target())
waiter.make_busy() waiter.make_busy()
else: else:
path = self.__getNearestTargetPath(waiter, target='table') if waiter.get_target() == 'return_order' and waiter.isPathEmpty():
print("Order returned")
table = self._table_manager.get_table(waiter.get_remaining_positions()[0])
table.setStatus(Status.Served)
waiter.get_remaining_positions().pop(0)
if not waiter.get_remaining_positions() == []:
waiter.set_target('return_order')
path = self.get_specified_path(waiter, waiter.get_remaining_positions()[0])
else:
waiter.set_target('table')
path = self.__getNearestTargetPath(waiter, target='table')
waiter.setPath([] if path is None else path) waiter.setPath([] if path is None else path)
if not waiter.isPathEmpty(): if not waiter.isPathEmpty():
@ -133,51 +197,36 @@ class WaiterManager(threading.Thread):
# check if waiter is near kitchen # check if waiter is near kitchen
if (waiter.getX(), waiter.getY()) == (14, 1) or (waiter.getX(), waiter.getY()) == (13, 0): if (waiter.getX(), waiter.getY()) == (14, 1) or (waiter.getX(), waiter.getY()) == (13, 0):
if waiter.get_target() == 'kitchen': if waiter.get_target() == 'kitchen':
self._table_manager.pause()
kitchen = self.__drawableManager.get_kitchen() kitchen = self.__drawableManager.get_kitchen()
waiter_orders = waiter.getAcceptedOrders() waiter_orders = waiter.getAcceptedOrders()
print("Waiter near kitchen. Collected orders: {}".format(waiter_orders)) # print("Waiter near kitchen. Collected orders: {}".format(waiter_orders))
kitchen.add_orders(waiter_orders) kitchen.add_orders(waiter_orders)
received_orders = kitchen.get_ready_orders() received_orders = kitchen.get_ready_orders()
waiter.clear_accepted_orders() waiter.clear_accepted_orders()
if received_orders: if received_orders:
# self._kitchen_manager.draw_orders(received_orders) predicted_orders = []
# paths = self._kitchen_manager.draw_orders(received_orders, kitchen)
food_list = self._menu_manager.get_menu()
ImagePredictor = Predictor(food_list)
for order in received_orders: for order in received_orders:
paths = self._kitchen_manager.draw_single_order(order, kitchen) # get predicted dishes
self._kitchen_manager.run() predicted_dishes = self.predict_order(order, kitchen)
self._table_manager.stop() predicted_orders.append(predicted_dishes)
# print("Printed images paths: {}".format(paths))
if paths is not None: # check if all predicted orders were really ordered
for img_path in paths: matched_targets = self.match_predicted_orders(predicted_orders)
ImagePredictor.predict_class(img_path) # get positions to matched orders (X,Y): dish
self.__drawableManager.forceRepaint() order_positions = self.get_order_targets(matched_targets)
self.set_next_waiter_positions(waiter, order_positions)
# set new ready paths to waiter
# self.set_next_waiter_targets(waiter, matched_targets)
self._kitchen_manager.stop() self._kitchen_manager.stop()
self._table_manager.resume() self._table_manager.resume()
self._table_manager.join()
# TODO: recognize images
all_tables = self.__drawableManager.getTables(Status.Waiting)
for table in all_tables:
# order = table.get_order()
# print("Table: {}\norder: {}".format(table, order))
pass
# TODO: choose proper tableo
# TODO: set path to tables, another target
time.sleep(5)
self._kitchen_manager.stop()
kitchen.clear_orders() kitchen.clear_orders()
waiter.make_ready() waiter.make_ready()
waiter.set_target('table') waiter.set_target('table')
else: elif waiter.get_target() not in ['return_order', 'check']:
self.__collectOrder(waiter) self.__collectOrder(waiter)
def stop(self): def stop(self):