diff --git a/kelner/main.py b/kelner/main.py index 21bac9e..2d731eb 100644 --- a/kelner/main.py +++ b/kelner/main.py @@ -34,7 +34,6 @@ load_model_thread.start() # joining this thread to main thread. Man thread will be started after this finish load_model_thread.join() - # initialize drawable objects manager drawableManager = DrawableCollection() diff --git a/kelner/src/algorithms/CNN/ModelPrediction.py b/kelner/src/algorithms/CNN/ModelPrediction.py index 45f8a38..bccc7a1 100644 --- a/kelner/src/algorithms/CNN/ModelPrediction.py +++ b/kelner/src/algorithms/CNN/ModelPrediction.py @@ -5,7 +5,6 @@ import numpy as np import kelner.src.settings as settings - class Predictor: def __init__(self, food_list): self._food_list = food_list @@ -26,7 +25,6 @@ class Predictor: print("THIS IS A:{}".format(pred_value)) def predict_class(self, img): - img = image.load_img(img, target_size=(224, 224)) img = image.img_to_array(img) img = np.expand_dims(img, axis=0) @@ -38,3 +36,4 @@ class Predictor: pred_value = self._food_list[index] # print("Pred: {}, index: {}, pred_value:{}".format(pred, index, pred_value)) print("THIS IS A:{}".format(pred_value)) + return pred_value diff --git a/kelner/src/components/Drawable.py b/kelner/src/components/Drawable.py index 50c8ba3..dd8fa7e 100644 --- a/kelner/src/components/Drawable.py +++ b/kelner/src/components/Drawable.py @@ -11,7 +11,7 @@ class Drawable: self.__x = x self.__y = y 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): if x < self.__minX or self.__maxX < x: @@ -36,6 +36,9 @@ class Drawable: def getY(self): return self.__y + def get_posistion(self): + return self.getX(), self.getY() + def getMinX(self): return self.__minX diff --git a/kelner/src/components/Table.py b/kelner/src/components/Table.py index ecc5a83..9e12681 100644 --- a/kelner/src/components/Table.py +++ b/kelner/src/components/Table.py @@ -5,12 +5,13 @@ from kelner.src.components.Drawable import Drawable from kelner.src.managers.ImageCache import ImageCache, Images from kelner.src.algorithms.DecisionTree import Tree_Builder + # status of the table class Status(Enum): NotReady = 0 - Ready = 1 - Waiting = 2 - Served = 3 + Ready = 1 + Waiting = 2 + Served = 3 class Table(Drawable): @@ -24,17 +25,16 @@ class Table(Drawable): self.__tableLock = Lock() self.__zainteresowania = [] - # Build a Decision Tree self.Decision_Tree = Tree_Builder.build_tree(Tree_Builder.training_db) - #Generates Hobbys + # Generates Hobbys for a in range(len(self.__guests)): - sport = random.randint(0,1) - czytanie = random.randint(0,1) - lucznictwo = random.randint(0,1) - boks = random.randint(0,1) - self.__zainteresowania.append([sport,czytanie,lucznictwo,boks, "A"]) + sport = random.randint(0, 1) + czytanie = random.randint(0, 1) + lucznictwo = random.randint(0, 1) + boks = random.randint(0, 1) + self.__zainteresowania.append([sport, czytanie, lucznictwo, boks, "A"]) ##def getOrder(self): ## # Generates order @@ -54,7 +54,7 @@ class Table(Drawable): return guests # waiter collects orders from table - #def getOrder(self): + # def getOrder(self): # order = None # if self.__tableLock.acquire(False): # try: @@ -87,9 +87,7 @@ class Table(Drawable): def get_order(self): return self.__order - - - #def getOrder(self): + # def getOrder(self): # order = None # if self.__tableLock.acquire(False): # try: diff --git a/kelner/src/components/Waiter.py b/kelner/src/components/Waiter.py index b9ed4b1..47e9d96 100644 --- a/kelner/src/components/Waiter.py +++ b/kelner/src/components/Waiter.py @@ -4,14 +4,14 @@ from kelner.src.managers.ImageCache import ImageCache, Images class Direction: - LeftUp = (-1,-1) - Up = ( 0,-1) - RightUp = ( 1,-1) - Right = ( 1, 0) - RightDown = ( 1, 1) - Down = ( 0, 1) - LeftDown = (-1, 1) - Left = (-1, 0) + LeftUp = (-1, -1) + Up = (0, -1) + RightUp = (1, -1) + Right = (1, 0) + RightDown = (1, 1) + Down = (0, 1) + LeftDown = (-1, 1) + Left = (-1, 0) class Waiter(Drawable): @@ -25,6 +25,8 @@ class Waiter(Drawable): self.__currentPath = [] self._ready = True self._target = 'table' + self._remaining_targets = [] + self._remaining_positions = [] def moveUp(self): if self.getY() > self.getMinY(): @@ -77,7 +79,6 @@ class Waiter(Drawable): def getDirection(self): return self.__dx, self.__dy - def setDirection(self, dx, dy): self.__dx = dx self.__dy = dy @@ -135,11 +136,10 @@ class Waiter(Drawable): def clear_accepted_orders(self): self.__acceptedOrders.clear() - def draw(self, screen): direction = self.getDirection() imageKind = None - if direction == Direction.LeftUp: + if direction == Direction.LeftUp: imageKind = Images.WaiterLeftUp elif direction == Direction.Up: imageKind = Images.WaiterUp @@ -185,4 +185,16 @@ class Waiter(Drawable): return self._target def set_target(self, target): - self._target = target \ No newline at end of file + 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 diff --git a/kelner/src/managers/DrawableCollection.py b/kelner/src/managers/DrawableCollection.py index 8046717..7339780 100644 --- a/kelner/src/managers/DrawableCollection.py +++ b/kelner/src/managers/DrawableCollection.py @@ -101,8 +101,8 @@ class DrawableCollection: nearestTables = [] tables = self.getTables(tableStatus) for table in tables: - if (table.getX() == waiter.getX() and abs(table.getY() - waiter.getY()) == 1) or\ - (table.getY() == waiter.getY() and abs(table.getX() - waiter.getX()) == 1): + if (table.getX() == waiter.getX() and abs(table.getY() - waiter.getY()) == 1) or \ + (table.getY() == waiter.getY() and abs(table.getX() - waiter.getX()) == 1): nearestTables.append(table) return nearestTables diff --git a/kelner/src/managers/TableManager.py b/kelner/src/managers/TableManager.py index 5d6b9ea..45bc3e7 100644 --- a/kelner/src/managers/TableManager.py +++ b/kelner/src/managers/TableManager.py @@ -12,21 +12,31 @@ class TableManager(threading.Thread): self.__drawableManager = drawableManager self.__menuManager = menuManager self.__runThread = True + self._active = True # changes the status of a random table from NotReady to Ready def run(self): while self.__runThread: tables = self.__drawableManager.getTables(Status.NotReady) - if tables: - tableIndex = random.randint(0, len(tables) - 1) - table = tables[tableIndex] + if not self._active: time.sleep(5) - table.setOrder(self.__menuManager.generateOrder()) - table.setStatus(Status.Ready) - self.__drawableManager.forceRepaint() + else: + if tables: + 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): - self.__runThread = False + def get_table(self, position): + 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): - self.__runThread = True + self._active = True diff --git a/kelner/src/managers/WaiterManager.py b/kelner/src/managers/WaiterManager.py index 5322e95..a43c56a 100644 --- a/kelner/src/managers/WaiterManager.py +++ b/kelner/src/managers/WaiterManager.py @@ -23,29 +23,41 @@ class WaiterManager(threading.Thread): def __getNearestTargetPath(self, waiter, target): distance = sys.maxsize nearestTargetPath = None + reservedPlaces = self.__drawableManager.getReservedPlaces(waiter) 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: - reservedPlaces = self.__drawableManager.getReservedPlaces(waiter) - 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 - else: - for table in tables: - if table.hasOrder(): - targets = finder.getNeighbours((table.getX(), table.getY()), False) - 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 + for table in tables: + if table.hasOrder(): + targets = finder.getNeighbours((table.getX(), table.getY()), False) + 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 + 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): targetDirection = x - waiter.getX(), y - waiter.getY() originDirection = waiter.getDirection() @@ -107,22 +119,74 @@ class WaiterManager(threading.Thread): print("Ready to go") return ready_orders - def predict_orders(self, orders, waiter): - pass + def predict_order(self, order, kitchen): + 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 def run(self): while self.__runThread: if self.__waiters: for waiter in self.__waiters: - if len(waiter.getAcceptedOrders()) > 0: + + if len(waiter.getAcceptedOrders()) > 1: waiter.set_target('kitchen') path = self.__getNearestTargetPath(waiter, target=waiter.get_target()) waiter.make_busy() - 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) if not waiter.isPathEmpty(): @@ -133,51 +197,36 @@ class WaiterManager(threading.Thread): # check if waiter is near kitchen if (waiter.getX(), waiter.getY()) == (14, 1) or (waiter.getX(), waiter.getY()) == (13, 0): if waiter.get_target() == 'kitchen': - + self._table_manager.pause() kitchen = self.__drawableManager.get_kitchen() 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) received_orders = kitchen.get_ready_orders() waiter.clear_accepted_orders() if received_orders: - # self._kitchen_manager.draw_orders(received_orders) - # paths = self._kitchen_manager.draw_orders(received_orders, kitchen) - food_list = self._menu_manager.get_menu() - ImagePredictor = Predictor(food_list) - + predicted_orders = [] for order in received_orders: - paths = self._kitchen_manager.draw_single_order(order, kitchen) - self._kitchen_manager.run() - self._table_manager.stop() - # print("Printed images paths: {}".format(paths)) - if paths is not None: - for img_path in paths: - ImagePredictor.predict_class(img_path) - self.__drawableManager.forceRepaint() + # get predicted dishes + predicted_dishes = self.predict_order(order, kitchen) + predicted_orders.append(predicted_dishes) + + # check if all predicted orders were really ordered + matched_targets = self.match_predicted_orders(predicted_orders) + # get positions to matched orders (X,Y): dish + 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._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() waiter.make_ready() waiter.set_target('table') - else: + elif waiter.get_target() not in ['return_order', 'check']: self.__collectOrder(waiter) def stop(self):