def __init__(self, env, kb, print_): # Attributes self.env = env # Printing self.print = print_ # Communication attributes self.ip = '172.21.0.0' self.kb = kb self.comm = Comm(self.ip) # Process self.logging = self.env.process(self.logging()) # Initialize self.my_print("Logger: Started")
def __init__(self, env, kb, agv_fm_comm, agv_to_fm_comm, print_): # Simulation environment self.env = env # Printing self.print = print_ # Communication attributes self.ip = '172.21.0.0' self.kb = kb self.agv_fm_comm = agv_fm_comm self.agv_to_fm_comm = agv_to_fm_comm self.comm = Comm(self.ip) # Process self.main = self.env.process(self.main()) # Initialize self.my_print("Fleet manager: Started")
def __init__(self, env, kb, order_list, print_): # Simulation environment self.env = env # Printing self.print = print_ # Communication attributes self.ip = '172.21.0.0' self.kb = kb # Knowledge base self.comm = Comm(self.ip) # List of orders to spawn self.order_list = order_list # Process self.main = self.env.process(self.main()) # Initialize self.my_print("\nMES: Started")
class FleetManager: """ A class containing the intelligence of the Fleetmanager agent inheriting a simple task allocation, allocating the task to the closest available robot. Robots have no local task list. """ def __init__(self, env, kb, agv_fm_comm, agv_to_fm_comm, print_): # Simulation environment self.env = env # Printing self.print = print_ # Communication attributes self.ip = '172.21.0.0' self.kb = kb self.agv_fm_comm = agv_fm_comm self.agv_to_fm_comm = agv_to_fm_comm self.comm = Comm(self.ip) # Process self.main = self.env.process(self.main()) # Initialize self.my_print("Fleet manager: Started") def main(self): self.my_print("\n") while True: # Timeout yield self.env.timeout(1) # Sample time # Define current status idle_robots = self.get_idle_robots() tasks_to_assign = self.get_tasks_to_assign() # If there are idle robots and tasks to execute, assign closest task if not len(tasks_to_assign) == 0 and not len(idle_robots) == 0: # Pick first task task = tasks_to_assign[0] # Get closest robot robot = self.get_closest_robot(task, idle_robots) # Assign task to agv task lists task.message = 'push' self.comm.tcp_write(self.agv_fm_comm[robot.ID], task) # Remove task from global task list self.comm.sql_remove_task(self.kb['global_task_list'], task.order_number) def get_idle_robots(self): robots = np.copy(self.comm.sql_read(self.kb['global_robot_list'])) robots = list(filter(lambda robot: robot.status == 'IDLE', robots)) robots = sorted(robots, key=lambda robot_: robot_.ID) return robots def get_tasks_to_assign(self): tasks = np.copy(self.comm.sql_read(self.kb['global_task_list'])) return tasks def get_closest_robot(self, task, idle_robots): return min(idle_robots, key=lambda robot: calculate_astar_distance( self.kb['graph'], robot.robot_node, task.pos_A)) def my_print(self, msg): if self.print: print(msg)
def __init__(self, env, agv_params, kb, fm_to_agv_comm, agv_to_fm_comm, print_): # Simulation environment self.env = env # Printing self.print = print_ # Communication attributes self.ip = '172.21.0.0' self.kb = kb # Knwoledge base (SQL database) self.fm_to_agv_comm = fm_to_agv_comm self.agv_to_fm_comm = agv_to_fm_comm self.comm = Comm(self.ip) # agv attributes self.ID = agv_params['ID'] # Each agv has an unique ID number self.robot_speed = agv_params['robot_speed'] # Constant robot speed self.task_execution_time = agv_params['task_execution_time'] self.depot_locations = agv_params['depot_locations'] self.battery_threshold = agv_params[ 'battery_threshold'] # Battery threshold when the agv needs to charge self.collision_threshold = agv_params[ 'collision_threshold'] # Collision threshold self.max_charging_time = agv_params[ 'max_charging_time'] # One hour to charge fully self.epsilon = agv_params['epsilon'] # Objective parameter self.max_tasks_in_task_list = agv_params['max_tasks_in_task_list'] self.initial_resources = agv_params['initial_resources'] # Local task list self.kb['local_task_list_R' + str(self.ID)] = simpy.FilterStore( self.env) # Updated attributes self.robot_location = self.kb['graph'].nodes[ agv_params['start_location']].pos self.robot_node = agv_params['start_location'] self.status = 'IDLE' self.battery_status = self.initial_resources self.travelled_time = 0 self.charged_time = 0 self.heading_direction = 0 self.task_executing = None self.path = [] self.slots = [] self.congestions = 0 self.total_path = [] # AGV tasks self.task_allocation = TaskAllocation(self) self.resource_management = ResourceManagement(self) self.action = Action(self) # Processes self.main = self.env.process(self.main()) # Initialize self.my_print("agv " + str(self.ID) + ": Started") self.robot = Robot(self.ID, self.robot_location, self.robot_node, self.heading_direction, self.path, self.status, self.battery_status, self.travelled_time, self.charged_time, self.congestions, self.task_executing) self.comm.sql_write(self.kb['global_robot_list'], self.robot)
class AGV: """ A class containing the intelligence of the AGV agent """ def __init__(self, env, agv_params, kb, fm_to_agv_comm, agv_to_fm_comm, print_): # Simulation environment self.env = env # Printing self.print = print_ # Communication attributes self.ip = '172.21.0.0' self.kb = kb # Knwoledge base (SQL database) self.fm_to_agv_comm = fm_to_agv_comm self.agv_to_fm_comm = agv_to_fm_comm self.comm = Comm(self.ip) # agv attributes self.ID = agv_params['ID'] # Each agv has an unique ID number self.robot_speed = agv_params['robot_speed'] # Constant robot speed self.task_execution_time = agv_params['task_execution_time'] self.depot_locations = agv_params['depot_locations'] self.battery_threshold = agv_params[ 'battery_threshold'] # Battery threshold when the agv needs to charge self.collision_threshold = agv_params[ 'collision_threshold'] # Collision threshold self.max_charging_time = agv_params[ 'max_charging_time'] # One hour to charge fully self.epsilon = agv_params['epsilon'] # Objective parameter self.max_tasks_in_task_list = agv_params['max_tasks_in_task_list'] self.initial_resources = agv_params['initial_resources'] # Local task list self.kb['local_task_list_R' + str(self.ID)] = simpy.FilterStore( self.env) # Updated attributes self.robot_location = self.kb['graph'].nodes[ agv_params['start_location']].pos self.robot_node = agv_params['start_location'] self.status = 'IDLE' self.battery_status = self.initial_resources self.travelled_time = 0 self.charged_time = 0 self.heading_direction = 0 self.task_executing = None self.path = [] self.slots = [] self.congestions = 0 self.total_path = [] # AGV tasks self.task_allocation = TaskAllocation(self) self.resource_management = ResourceManagement(self) self.action = Action(self) # Processes self.main = self.env.process(self.main()) # Initialize self.my_print("agv " + str(self.ID) + ": Started") self.robot = Robot(self.ID, self.robot_location, self.robot_node, self.heading_direction, self.path, self.status, self.battery_status, self.travelled_time, self.charged_time, self.congestions, self.task_executing) self.comm.sql_write(self.kb['global_robot_list'], self.robot) def main(self): while True: # Wait for an assigned task self.my_print("AGV " + str(self.ID) + ": Waiting for tasks..." + " at " + str(self.env.now)) self.task_executing = yield self.kb['local_task_list_R' + str(self.ID)].get() # Start task self.my_print("AGV " + str(self.ID) + ": Start executing task " + str(self.task_executing.to_string()) + " at " + str(self.env.now)) if self.status is not 'EMPTY': self.status = 'BUSY' self.update_global_robot_list() # Remove task from global task list and add to executing list self.comm.sql_remove_task(self.kb['global_task_list'], self.task_executing.order_number) self.task_executing.robot = self.ID self.comm.sql_write(self.kb['tasks_executing'], self.task_executing) # Go to task A yield self.env.process(self.execute_task(self.task_executing)) # Perform task A yield self.env.process(self.action.pick()) self.task_executing.picked = True self.my_print("AGV " + str(self.ID) + ": Picked item of task " + str(self.task_executing.order_number) + " at " + str(self.env.now)) # Task executed self.comm.sql_remove_task(self.kb['tasks_executing'], self.task_executing.order_number) self.task_executing = None # Set status to IDLE when task is done or when done charging if self.status is not 'EMPTY': self.status = 'IDLE' self.update_global_robot_list() # Calculates shortest path with Astar and executes def execute_task(self, task): # Compute astar path self.path, _ = find_shortest_path(self.kb['graph'], self.robot_node, task.pos_A) # Update state self.update_global_robot_list() # Move from node to node while len(self.path) > 0: yield self.env.process(self.action.move_to_node(self.path[0])) # Check if task is charging task if task.order_number == '000': # Compute charging time charging_time = (100 - self.battery_status ) / self.resource_management.charging_factor # Update status self.my_print("agv " + str(self.ID) + ": Is charging for " + str(charging_time) + " seconds at " + str(self.env.now)) self.status = 'CHARGING' self.update_global_robot_list() # Charging yield self.env.timeout(charging_time) # Update robot status self.battery_status = self.battery_status + charging_time * self.resource_management.charging_factor self.status = 'IDLE' self.charged_time += int( charging_time) + calculate_path_traveltime( self.kb['graph'], self.path, self.robot_speed) self.update_global_robot_list() def update_global_robot_list(self): self.comm.sql_remove_robot(self.kb['global_robot_list'], self.ID) self.robot = Robot(self.ID, self.robot_location, self.robot_node, self.heading_direction, self.path, self.status, self.battery_status, self.travelled_time, self.charged_time, self.congestions, self.task_executing, self.total_path) self.comm.sql_write(self.kb['global_robot_list'], self.robot) def my_print(self, msg): if self.print: print(msg)
class MES: """ A class containing the intelligence of the MES agent """ def __init__(self, env, kb, order_list, print_): # Simulation environment self.env = env # Printing self.print = print_ # Communication attributes self.ip = '172.21.0.0' self.kb = kb # Knowledge base self.comm = Comm(self.ip) # List of orders to spawn self.order_list = order_list # Process self.main = self.env.process(self.main()) # Initialize self.my_print("\nMES: Started") def main(self): # Open file file = open(self.order_list, "r") # Read order line = file.readline() order = line.split(',') prev_time = 0 while line != "": # Calculate spawn time and wait for this time execution_time = int(order[0]) timeout = execution_time - prev_time prev_time = execution_time yield self.env.timeout(timeout) # Create new task order_number = int(order[1]) priority = int(order[2]) pos_a = order[3] new_task = Task(order_number, pos_a, priority) # Put the new task in the global task list self.comm.sql_write(self.kb['global_task_list'], new_task) self.my_print('MES: New task ' + new_task.to_string() + ' arrived at ' + str(self.env.now)) # Read order line = file.readline() order = line.split(',') # Close file file.close() # Wait till all tasks are executed while True: # Sample time yield self.env.timeout(2) # Check amount of tasks in local task list amount_of_tasks_in_local_task_lists = 0 for key in self.kb.keys(): if 'local_task_list_R' in key: amount_of_tasks_in_local_task_lists += len( self.kb[key].items) # Check amount of tasks in executing task list amount_of_executing_tasks = len(self.kb['tasks_executing'].items) # Check amount af tasks in global task list amount_of_global_tasks = len(self.kb['global_task_list'].items) # End criterium if amount_of_executing_tasks == 0 and amount_of_tasks_in_local_task_lists == 0 \ and amount_of_global_tasks == 0: break def my_print(self, msg): if self.print: print(msg)
class Logger: def __init__(self, env, kb, print_): # Attributes self.env = env # Printing self.print = print_ # Communication attributes self.ip = '172.21.0.0' self.kb = kb self.comm = Comm(self.ip) # Process self.logging = self.env.process(self.logging()) # Initialize self.my_print("Logger: Started") def logging(self): # Create loggers log_filename_1 = '../logfiles/global_task_list.txt' log_filename_2 = '../logfiles/local_task_list.txt' log_filename_3 = '../logfiles/tasks_executing.txt' log_filename_4 = '../logfiles/global_robot_list.txt' log1 = logging.getLogger('MyLogger1') log1.setLevel(logging.DEBUG) handler1 = logging.handlers.RotatingFileHandler( log_filename_1, backupCount=1, mode='w') log1.addHandler(handler1) log2 = logging.getLogger('MyLogger2') log2.setLevel(logging.DEBUG) handler2 = logging.handlers.RotatingFileHandler( log_filename_2, backupCount=1, mode='w') log2.addHandler(handler2) log3 = logging.getLogger('MyLogger3') log3.setLevel(logging.DEBUG) handler3 = logging.handlers.RotatingFileHandler( log_filename_3, backupCount=1, mode='w') log3.addHandler(handler3) log4 = logging.getLogger('MyLogger4') log4.setLevel(logging.DEBUG) handler4 = logging.handlers.RotatingFileHandler( log_filename_4, backupCount=1, mode='w') log4.addHandler(handler4) while True: yield self.env.timeout(1) # Global tasks list global_task_list_string = "" global_task_list = self.comm.sql_read(self.kb['global_task_list']) for task in global_task_list: global_task_list_string += task.to_log() + "|" # Local task lists local_task_list_string = "" for key in self.kb.keys(): if "local_task_list_R" in key: local_task_list_string += "[" local_task_list = self.comm.sql_read(self.kb[key]) for task in local_task_list: local_task_list_string += str(task.to_log()) + ':' local_task_list_string = local_task_list_string local_task_list_string += "]|" # Task executing tasks_executing_string = "" tasks_executing = self.comm.sql_read(self.kb['tasks_executing']) for task in tasks_executing: tasks_executing_string += task.to_log() + "|" # Global robot list global_robot_list_string = "" global_robot_list = self.comm.sql_read(self.kb['global_robot_list']) robots = np.copy(global_robot_list) robots = sorted(robots, key=lambda robot_: robot_.ID) for robot in robots: global_robot_list_string += robot.to_log() + "|" # Logging log1.debug(str(self.env.now) + "|" + str(global_task_list_string)) log2.debug(str(self.env.now) + "|" + str(local_task_list_string)) log3.debug(str(self.env.now) + "|" + str(tasks_executing_string)) log4.debug(str(self.env.now) + "|" + str(global_robot_list_string)) def my_print(self, msg): if self.print: print(msg)