FAS_reproduce/try4.py

218 lines
7.3 KiB
Python
Raw Normal View History

2023-01-30 15:48:45 +08:00
import salabim as sim
from numpy.random import normal
from math import exp
import numpy as np
def delay(duration, percentage_variation):
stdev = percentage_variation / 100.0 * duration
random_additive_noise = normal(0, stdev)
return max(0, int(duration + random_additive_noise))
class Crane(sim.Component):
def __init__(self, name, duration, env, debug=True,*args, **kwargs):
sim.Component.__init__(self, *args, **kwargs)
self.name=name
self.duration = duration
self.debug = debug
self.env = env
def process(self):
if self.debug:
print(self.name + ": input")
self.enter(pl)
if self.debug:
print(self.name + ": go_forward")
#self.logger.addMessage(self.name + " FORWARD");
self.state = "running"
yield self.hold(delay(self.duration, 1))
if self.debug:
print(self.name + ": wait")
self.state = "waiting"
if self.debug:
print(self.name + ": item_taken")
print(self.name + ": go_back")
#self.logger.addMessage(self.name + " BACKWARD");
yield self.hold(delay(self.duration, 1))
if self.debug:
print(self.name + ": stop")
self.leave(pl)
#self.logger.addMessage(self.name + " STOP");
class BowlFeeder(sim.Component):
def __init__(self, name, duration, env, debug=True,*args, **kwargs):
sim.Component.__init__(self, *args, **kwargs)
self.debug = debug
self.duration = duration
self.name = name
self.state = "waiting"
self.env = env
self.faults = []
def add_fault(self, fault):
yield self.hold(0)
self.faults.append(fault)
def process(self):
if self.debug:
print(self.name + ": give")
self.enter(pl)
self.state = "giving"
yield self.hold(delay(self.duration, 1))
for fault in self.faults:
print('FAULT')
if self.debug:
print(self.name + ": given")
self.leave(pl)
self.state = "waiting"
class Conveyor(sim.Component):
def __init__(self, name, duration, env, debug=True,*args, **kwargs):
sim.Component.__init__(self, *args, **kwargs)
self.debug = debug
self.duration = duration
self.name = name
self.env = env
self.faults = []
def add_fault(self, fault):
self.faults.append(fault)
def process(self):
if self.debug:
print(self.name + ": input")
self.enter(pl)
yield self.hold(delay(self.duration, 1))
for fault in self.faults:
print('FAULT')
if self.debug:
print(self.name + ": to_next_step")
self.leave(pl)
class ManualStep(sim.Component):
def __init__(self, name, duration, env, debug=True,*args, **kwargs):
sim.Component.__init__(self, *args, **kwargs)
self.debug = debug
self.duration = duration
self.state = "waiting"
self.name = name
self.env = env
self.queue = 0
def process(self):
if self.debug:
print(self.name + ": input")
self.enter(pl)
self.queue = self.queue + 1
if (self.queue >= 5):
print("QUEUE_ALARM");
if self.debug:
print(self.name + ": process")
self.queue = self.queue - 1
self.state = "running"
yield self.hold(delay(self.duration, 5))
if self.debug:
print(self.name + ": ok")
if self.debug:
print(self.name + ": wait")
self.leave(pl)
self.state = "waiting"
class RetryDelay(sim.Component):
def __init__(self, env, debug=True,*args, **kwargs):
sim.Component.__init__(self, *args, **kwargs)
self.debug = debug
self.t = 0
self.env = env
def process(self):
self.t = self.t + 1
delay_factor = np.random.poisson((exp(self.t/5)-1)/4) * 0.2
if self.debug:
print("FAULT: RETRY_DELAY: ", delay_factor)
yield self.hold(self.add_delay(2, delay_factor))
def add_delay(self, delay, delay_factor):
return delay * delay_factor
class ProductionLine():
def __init__(self,env):
self.env = env
self.crane1 = Crane("CRANE1", 3, env)
self.manual_inspection = ManualStep("MANUAL_INSPECTION", 3, env)
self.conveyor1 = Conveyor("CONVEYOR1", 3, env)
self.bowl1 = BowlFeeder("BOWL1", 5, env)
self.manual_add_components1 = ManualStep("MANUAL_ADD_COMPONENTS1", 2.1, env)
self.conveyor2 = Conveyor("CONVEYOR2", 3, env)
self.bowl2 = BowlFeeder("BOWL2", 1, env)
self.bowl2.add_fault(RetryDelay(env,self.bowl2))
self.manual_add_components2 = ManualStep("MANUAL_ADD_COMPONENTS2", 3, env)
self.conveyor3 = Conveyor("CONVEYOR3", 3, env)
self.crane_input_subassembly_a = Crane("CRANE_INPUT_SUBASSEMBLY_A", 1, env)
self.manual_combine_subassembly_a = ManualStep("MANUAL_COMBINE_SUBASSEMBLY_A", 3.4, env)
self.conveyor4 = Conveyor("CONVEYOR4", 3, env)
self.conveyor_input_subassembly_b = Conveyor("CONVEYOR_INPUT_SUBASSEMBLY_B", 1, env)
self.manual_combine_subassembly_b = ManualStep("MANUAL_COMBINE_SUBASSEMBLY_B", 3.5, env)
self.conveyor5 = Conveyor("CONVEYOR5", 3, env)
self.bowl3 = BowlFeeder("BOWL3", 5, env)
self.conveyor6 = Conveyor("CONVEYOR6", 1, env)
self.manual_add_cover_and_bolts = ManualStep("MANUAL_ADD_COVER_AND_BOLTS", 7, env)
self.conveyor7 = Conveyor("CONVEYOR7", 3, env)
self.manual_tighten_bolts1 = ManualStep("MANUAL_TIGHTEN_BOLTS1", 2, env)
self.conveyor8 = Conveyor("CONVEYOR8", 3, env)
self.conveyor_input_subassembly_c = Conveyor("CONVEYOR_INPUT_SUBASSEMBLY_C", 1, env)
self.manual_combine_subassembly_c = ManualStep("MANUAL_COMBINE_SUBASSEMBLY_C", 6, env)
self.conveyor9 = Conveyor("CONVEYOR9", 2, env)
self.manual_tighten_bolts2 = ManualStep("MANUAL_TIGHTEN_BOLTS2", 1, env)
self.conveyor10 = Conveyor("CONVEYOR10", 2, env)
self.bowl4 = BowlFeeder("BOWL4", 5, env)
self.manual_add_components3 = ManualStep("MANUAL_ADD_COMPONENTS3", 1, env)
self.conveyor11 = Conveyor("CONVEYOR11", 2, env)
self.manual_tighten_bolts3 = ManualStep("MANUAL_TIGHTEN_BOLTS3", 3, env)
env = sim.Environment()
production_line = ProductionLine(env)
pl = sim.Queue('pl')
env.background_color('20%gray')
env.modelname('FAS queue animation')
pl1 = sim.AnimateQueue(pl, x=100, y=300, title='queue, normal', direction='e')
pl2 = sim.AnimateQueue(pl, x=100, y=220, title='queue, maximum 6 components', direction='e', max_length=6)
pl3 = sim.AnimateQueue(pl, x=100, y=140, title='queue, reversed', direction='e', reverse=True)
sim.AnimateMonitor(pl.length, x=10, y=450, width=480, height=100, horizontal_scale=5, vertical_scale=5)
sim.AnimateMonitor(pl.length_of_stay, x=10, y=570, width=480, height=100, horizontal_scale=5, vertical_scale=5)
sim.AnimateText(text=lambda: pl.length.print_histogram(as_str=True), x=500, y=700,text_anchor='nw', font='narrow', fontsize=10)
#sim.AnimateText(text=lambda: pl.print_info(as_str=True), x=500, y=340,text_anchor='nw', font='narrow', fontsize=10)
env.animate(True)
env.run(till=20)
print("Done.")
#pl.print_statistics()
pl.length_of_stay.print_statistics()