def add_free_robot(robot_ip): with free_list_lock, pending_lock: i = 0 while i < len(pending_tasks): task = pending_tasks[i] if task.type == TaskType.FOR_CONTAINER: (container_id, row, col, slot, level, status) = db_manager.get_container_info(task.dest_container_id) # if the task is a FETCHING job where the requested container is TO_SHELF, # re-assign task to that robot TO_PACKING if status == "TO_SHELF": carrier_robot_ip = db_manager.get_container_carrier(task.dest_container_id) robot_perform_task(carrier_robot_ip, Task(TaskType.TO_DOCK, task.dest_dock_id, 0)) # update bookkeeping db_manager.set_container_status(container_id, "TO_PACKING") pending_tasks.pop(i) continue # if the task is a FETCHING job where the requested container is TO_IMPORT, # re-assign task to that robot TO_PACKING # and let this newly added robot to the TO_IMPORT instead elif status == "TO_IMPORT": carrier_robot_ip = db_manager.get_container_carrier(task.dest_container_id) destined_import_dock_id = db_manager.get_robot_dest_dock(carrier_robot_ip) robot_perform_task(carrier_robot_ip, Task(TaskType.TO_DOCK, task.dest_dock_id, 0)) db_manager.set_container_status(container_id, "TO_PACKING") pending_tasks.pop(i) return Task(TaskType.TO_DOCK, destined_import_dock_id, 0) # if the task is a FETCHING job where the requested container is RESERVED or TO_PACKING, # it cannot be done now, skip, try the next task elif status == "RESERVED" or status == "TO_PACKING": i += 1 continue # otherwise, the task is do-able, assign it to this newly added robot pending_tasks.pop(i) return task # if there's no task can be done, add the robot to free list free_robots.append(robot_ip) return None
def request_item(conn, addr): worker_ip = addr[0] dock_id = db_manager.get_dock_id_by_ip(worker_ip) # receive the rest of the message data = receive_message(conn, 1) item_id = unpack("B", data)[0] print("Please fetch me item #" + str(item_id)) # get info about the container result = db_manager.locate_item(item_id) if not result: # the item does not exist, reply to the app [6] send_message(worker_sockets[dock_id], pack("B", 6)) return (container_id, row, col, slot, level, status) = result # tell the worker app in which container the requested item is send_message(worker_sockets[dock_id], pack("BB", 4, container_id)) # if the container is going to PACKING dock or has been reserved, we can't do it now if status == "TO_PACKING" or status == "RESERVED": planning.pend_fetching_task_to(container_id, dock_id) # if the container is on shelf, try to find the nearest robot to fetch it and carry to the dock elif status == "ON_SHELF": responsible_robot_ip = planning.nearest_free_robot_to_shelf(ShelfLoc(row, col, slot, level), container_id, dock_id) if responsible_robot_ip != "": planning.robot_perform_task(responsible_robot_ip, planning.Task(planning.TaskType.FOR_CONTAINER, dock_id, container_id)) # if the container is to IMPORT dock or is TO_SHELF, call the robot over elif status == "TO_SHELF": responsible_robot_ip = db_manager.get_container_carrier(container_id) planning.robot_perform_task(responsible_robot_ip, planning.Task(planning.TaskType.TO_DOCK, dock_id, 0)) # update bookkeeping db_manager.set_container_status(container_id, "TO_PACKING") # TODO: if called over TO_IMPORT, need to call someone else to that IMPORT dock # TODO: or maybe not, because for the moment there can be no container being carried TO_IMPORT anyway else: raise Exception("request_item: item cannot possibly TO_IMPORT")