def truck_controllers(env: simpy.Environment, truck_q: simpy.Store):

    for i in range(100):
        truck = Truck(truck_id=f"truck_{i}", env=env)
        truck.start_wait()
        truck_q.put(truck)
        wait_time = 5
        yield env.timeout(wait_time)
def generate_item(env, last_q: simpy.Store, item_num: int = 100):
    """模拟物件的到达"""

    for i in range(item_num):
        print(f'{round(env.now, 2)} - item: item_{i} - created创建')
        last_q.put(f'item_{i}')
        t = random.expovariate(1 / MEAN_TIME)
        yield env.timeout(round(t, 1))
示例#3
0
def run_load_generator(env: simpy.Environment, queue: simpy.Store, pod_synth: PodSynthesizer,
                       ia_sampler: Generator[float, float, None], log: List[LoggingRow]):
    """
    :param env: simpy environment
    :param queue: the work queue
    :param pod_synth: fake Pod generator
    :param ia_sampler: arrival profile
    :param log: simple array to append log messages
    :return:
    """
    while True:
        ia = next(ia_sampler)  # inter-arrival
        ia = round(ia, 3)  # millisecond accuracy
        yield env.timeout(ia)

        pod = next(pod_synth)
        queue.put(pod)

        logging.debug('pod arrived at %.2f seconds' % env.now)
        log.append(LoggingRow(env.now, EventType.POD_QUEUED, pod.name, {'queue_length': len(queue.items)}))
class Connection:
    """This class represents the propagation through a Connection."""
    def __init__(self, env, origin_node, destination_node):
        self.env = env
        self.store = Store(env)
        self.origin_node = origin_node
        self.destination_node = destination_node

    def latency(self, envelope):
        latency_delay = get_latency_delay(self.env, self.origin_node.location,
                                          self.destination_node.location)
        yield self.env.timeout(latency_delay)
        self.store.put(envelope)

    def put(self, envelope):
        print(
            f'{envelope.origin.address} at {envelope.timestamp}: Message (ID: {envelope.msg["id"]}) sent with {envelope.msg["size"]} MB with a destination: {envelope.destination.address}'
        )
        self.env.process(self.latency(envelope))

    def get(self):
        return self.store.get()
示例#5
0
class Comm(Component):
    def __init__(self, nname, env):
        super().__init__(nname)
        conf = Configuration()
        self.queue = Store(env)
        self.tcomm = conf.get('[comm]t_comm')
        self.perr = conf.get('[comm]p_err')
        self.unavail = conf.get('[comm]unavail')

    def put(self, msg):
        guess = uniform(0, 1)
        if (guess > self.unavail):
            yield self.env.timeout(self.tcomm)
            while (random() < self.perr):
                self.debug('errorInMessage;;')
                yield self.env.timeout(self.tcomm)
            self.queue.put(msg)
        else:
            self.debug('unavailabilityOfCommunication;;')

    def get(self):
        msg = yield self.queue.get()
        return msg
示例#6
0
class Storage:
    def __init__(self, sim, buffer_params):
        """Returns a buffer object for a Buffer object in MOCA

        :param sim: Reference to DES simulation object
        :param buffer_params: Dictionary of parameters
        """
        # Name and size of the buffer object
        self.name = buffer_params['name']
        self.size = buffer_params['size']

        # The parent simulation object
        self.procflow_sim = sim

        # References to upstream and downstream processes
        self.upstream_process = None
        self.downstream_process = None

        # Internal buffer
        self.buffer = Store(self.procflow_sim.simpy_env, capacity=self.size)

        # Buffer state variables
        self.buffer_metrics = {'usage': 0}

    def store(self, part):
        """Stores the given part in the buffer

        :param part: Part object to be stored
        :return: The event of the buffer
        """
        yield self.buffer.put(part)

    def retrieve(self):
        """Retrieves the first part from the buffer

        :return: The part from the buffer (or waits for the buffer till a part arrives)
        """
        yield self.buffer.get()
示例#7
0
class MainController(Behaviour):
    def __init__(self, nname, agvcommchannel):
        super().__init__(nname)
        b = Blackboard()
        self.rbs = RuleBasedSystem(b.get('[RBS]maxattempts'))
        envy = b.get('enviro')
        self.accuracyParameter = b.get('[vision]accuracy')
        self.toagv = agvcommchannel
        #robot
        self.robotcomm = Store(envy)
        self.robot = Robot('robot', self.robotcomm)
        # stations
        ninputs = b.get('[stations]inumber')
        noutputs = b.get('[stations]onumber')
        nspas = b.get('[stations]spa')
        self.stations = dict()
        b.put('[Shared]packages', dict())
        b.put('[Shared]packages.dirtybit', dict())
        for sindex in range(0, ninputs):
            sname, stat = self.makeStation(sindex, envy)
            self.stations[sname] = (stat, StationDir.INPUT)
        for sindex in range(0, noutputs):
            sname, stat = self.makeStation(sindex + ninputs, envy)
            self.stations[sname] = (stat, StationDir.OUTPUT)

    def makeStation(self, index, envy):
        name = 'STAT_' + str(index)
        cin = Store(envy)
        cout = Store(envy)
        v = Vision('VIS_' + str(index), self.accuracyParameter)
        s = Station(name, cin, cout)
        s.setVision(v)
        Blackboard().get('[Shared]packages')[name] = None
        Blackboard().get('[Shared]packages.dirtybit')[name] = True
        return name, s

    def boot(self):
        for name in self.stations.keys():
            self.load(name)

    def load(self, sname):
        (stat, dir) = self.stations[sname]
        order = MovementOrder.INBD if (dir == StationDir.INPUT) else (
            MovementOrder.OUTD)
        msg = (order, stat.channelIN, stat.channelOUT)
        self.toagv.put(msg)

    def reload(self, sname):
        (stat, dir) = self.stations[sname]
        order = MovementOrder.DRPI if (dir == StationDir.INPUT) else (
            MovementOrder.DRPO)
        msg = (order, stat.channelIN, stat.channelOUT)
        self.toagv.put(msg)

    def checkFullEmptyPallets(self):
        for name in self.stations:
            stat, dir = self.stations[name]
            if stat.operative():
                p = stat.getPallet()
                flag = (dir == StationDir.INPUT) and (p.isEmpty())
                flagout = ((dir == StationDir.OUTPUT) and (p.isSatisfied()))
                flag = flag or flagout
                if flag == True:
                    stat.dirt()
                    if (flagout):
                        self.log('vault;' + str(p.lenght()) + ';', 2)
                        Recorder().add('hit', p.lenght())
                    self.reload(name)

    def do(self):
        if (self.onrun == True):
            action = None
            while (action == None):
                action, resetcondition, stationtoreset = self.rbs.computeNextStep(
                    self.stations)
                if (action == None):
                    if resetcondition == False:
                        yield self.env.timeout(10)
                    else:
                        stationtoreset.dirt()
                        p = stationtoreset.getPallet()
                        pname = stationtoreset.getName()
                        l = p.lenght()
                        self.log(
                            'MISS;' + stationtoreset.getName() + ',' + str(l) +
                            ';', 2)
                        Recorder().add('miss', l)
                        self.reload(pname)
                yield self.env.timeout(1)
            self.robotcomm.put(action)
            yield self.robotcomm.get()
            self.checkFullEmptyPallets()
示例#8
0
class Component:
    def __init__(self, env, cp_params):
        self.env = env
        self.in_pipe = Store(self.env) # TODO: define capacity in cp_params
        self.pending_jobs = {}
        self.response_times = []
        self.interarrivals = []
        self.queue_times = []
        self.num_cores = cp_params['num_cores']
        self.used_cores = 0
        self.core_speed = random_number(cp_params['core_speed'])
        self.cores = Resource(self.num_cores)
        self.name = cp_params['name']
        self.jobs_completed = 0
        self.sim_components = None
        self.data_res = []
        self.idle_time = 0
        self.time_last_arrival = None

    def __str__(self):
        return f'[{self.name}]'

    def logger(self, message, job_id):
        #print(f'{self} {message} {job_id} time_{self.env.now}')
        pass

    def run(self):

        while True:
            if len(self.in_pipe.items) < 1 or self.used_cores >= self.num_cores:
                yield self.env.timeout(1)
                self.idle_time += 1
                continue
            self.used_cores += 1
            job = yield self.in_pipe.get()
            job.stats[self.name]
            enqueue_time = job.stats[self.name]['enqueue_time']
            queue_time = self.env.now - enqueue_time
            self.queue_times.append(queue_time)
            self.env.process(self.process_job(job))

    def get_stats(self):
        stats = dict(
            avg_response_time =  9999 if len(self.response_times) == 0 else mean(self.response_times),
            avg_queue_time = 9999 if len(self.queue_times) == 0 else mean(self.queue_times),
            avg_interarrival_time = 9999 if len(self.interarrivals) == 0 else mean(self.interarrivals),
            queue_size=len(self.in_pipe.items),
            idle_time = self.idle_time,
            used_cores = self.used_cores,
            jobs_completed = self.jobs_completed,
            name = self.name,
            sim_time = self.env.now
        )
        
        return stats

    def init_job_stats(self, job):
        job.stats[self.name] = {}
        job.stats[self.name]['arrival_time'] = self.env.now
        if self.time_last_arrival is None:
            self.time_last_arrival = self.env.now
        else:
            interarrival = self.env.now - self.time_last_arrival 
            self.interarrivals.append(interarrival)

    def receive_request(self, job):
        self.init_job_stats(job)
        self.logger("received", job.id)
        yield self.env.process(self.enqueue_job(job))
        
    def make_request(self, job, component):
        job.response_method = self.receive_response
        self.env.process(component.receive_request(job))
        yield self.env.timeout(0) # NOTE: make request delay
        self.pending_jobs[job.id] = job

    def receive_response(self, response_job, type_of_response='response'):
        self.logger(f'received_{type_of_response}_for', response_job.id)
        if response_job.id in list(self.pending_jobs.keys()):
            self.env.process(self.enqueue_job(self.pending_jobs[response_job.id]))
            del self.pending_jobs[response_job.id]
            yield self.env.timeout(0)
            return "OK"
        return "INVALID JOB"

    def process_job(self,job):
        self.logger('processing', job.id)
        processing_time = ceil(job.size / self.core_speed)
        yield self.env.timeout(processing_time)
        self.used_cores -= 1
        self.complete_job(job)
        
    def complete_job(self,job):
        job.stats[self.name]['finish_time'] = self.env.now
        self.jobs_completed += 1
        response_time = self.env.now - job.stats[self.name]['arrival_time']
        self.response_times.append(response_time)

    def enqueue_job(self, job):
        job_stats = {}
        try:
            job_stats['arrival_time'] = self.env.now
            job_stats['estimated_processing_time'] = job.size / self.core_speed
            job_stats['enqueue_time'] = self.env.now
            yield self.in_pipe.put(job)
            job.stats[self.name] = job_stats
        except Exception as e:
            self.logger("error_at_enqueue", job.id)