pythonsimpy

How to start consecutive processes of different classes


I am making a code in Pytohn using Simpy, and for the simulation I want to have all the elements in separate classes, e.g. machines, transport, warehouses... I'm making the code, and I don't know how to make that a process is followed by another one: I want the arrival of material to be independent, that every "8.8" minutes a material is generated and enters in the first machine "Cut". At the end of the cutting process, I want it to be picked up in transport, and go to another machine. As the processes are in different classes, I don't know how to call them? I attach the code:

import numpy as np
import simpy
import math
import random

ARR_RATE_403=8.88
MACHINES_CUT=1
WORKERS_T_1_2=1
MACHINES_WEL=1
T_CUT_403=0.92 # mins
DIST_1_2= 80 # meters
SPEED=30
T_WEL_403=2.197
T_SIM=100
cables=0
unit=0
viajes_1to2=0

class Cut_403:
    def __init__(self, env, arrival_rate_403, cut_time_403, num_cut_machines):
        self.env=env
        self.arrival_rate=arrival_rate_403
        self.cut_time=cut_time_403
        self.cut_machines=simpy.Resource(env, num_cut_machines)
        self.access_done=self.env.event()
        self.cut_done=self.env.event()
        self.action = env.process(self.generate_403())
        self.unit=0
        
    def generate_403(self):
        while True:
            yield self.env.timeout(self.arrival_rate)
            self.unit += 1
            self.env.process(self.cutting())
    
    def cutting(self):
        global wait_1, pasa_1, arrive_1
        #pasa_1=0
        #wait_1=0
        print('(C) ---> Unit {} of 403 arrives to cutting at {:.2f} min'.format(self.unit, self.env.now))
        arrive_1=self.env.now
        with self.cut_machines.request() as req:
            yield req
            pasa_1=env.now
            wait_1=pasa_1-arrive_1
            print('(C) *** Unit {} of 403 having waited {:.2f} min, pass to cutting machine at {:.2f} minute'.format(self.unit, wait_1, self.env.now))
            #yield self.access_done.succeed() 
            yield self.env.timeout(self.cut_time)
            #yield self.access_done
            #yield self.cut_done
            print('(C) \O/ Unit {} cutted in {} min, at {:.2f}'.format(self.unit, self.cut_time, self.env.now))
            
#%%
class Transport_1to2_403:
    def __init__(self, env, workers_1to2, distance, speed, unit):
        self.env=env
        self.workers=simpy.Resource(env, workers_1to2)
        self.transp_time=distance/speed
        self.unit=unit
    def moving(self):
        global wait_t, pasa_t, arrive_t
        #wait_t=0
        #pasa_t=0
        print('(T) ... Unit {} of 403 having waited {:.2f} min, is taken for transport in cutting at {:.2f}'.format(self.unit, wait_t, self.env.now))
        arrive_t=self.env.now
        with self.workers.request() as req:
            yield req
            pasa_t=self.env.now
            wait_t=pasa_t-arrive_t
            yield self.env.timeout(self.transp_time)
            #viajes_1to2 += 1
            print('(T) ... Unit {} moved from cutting to welding in {:.2f} min, at {:.2f}'.format(self.unit, self.transp_time, self.env.now))
            yield self.env.timeout(self.transp_time)
            #viajes_1to2 += 1
            print('(T) ... Worker come back to cutting from welding in {:.2f} min, at {:.2f}'.format(self.transp_time, self.env.now))

env = simpy.Environment()  # Unique environment defined
cut=Cut_403(env, ARR_RATE_403, T_CUT_403, MACHINES_CUT)
trans=Transport_1to2_403(env, WORKERS_T_1_2, DIST_1_2, SPEED, unit) #doubt
env.run(until=T_SIM)  

Thanks!

My desired output is a process where every 8.8 minutes a material input is generated, it goes to the cutting machine (if it is free), and when it is finished it goes to transport (if the operator is free, as he goes back and forth), and if not it waits in the transport room (if the operator is free, as he goes back and forth), and if not it waits in the transport room (if the operator is free).


Solution

  • I would suggest taking a close look at the carwash example. It sounds like you have material with an inter arrival time, that is then processed by 'cut' and then 'transport' with resources attached to each. I don't see it here but I would recommend creating a second class for transport.

    Also, I'd also recommend a function for the material analogous to the 'car' in the carwash example. That way 'material' can interact with both 'cut' and 'transport' and should be passed to the object similarly. https://simpy.readthedocs.io/en/latest/examples/carwash.html