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))
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()
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
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()
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()
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)