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")
Esempio n. 2
0
    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")
Esempio n. 3
0
    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")
Esempio n. 4
0
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)
Esempio n. 7
0
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)