def setup(self, job_generator): self.tasks = sim.Queue(fill=[ Task(job_generator=job_generator, job=self, name='Task ' + str(self.sequence_number()) + '.') for _ in range(job_generator.number_of_tasks_dist()) ], name='tasks.') self.task_in_execution = sim.Queue(name='task_in_execution.') self.slack = start_slack self.an_slack = sim.AnimateText( x=90, y=self.y, text=lambda job, t: '{:7.2f}'.format(job.slack_t(t)), textcolor=lambda job, t: 'white' if job.slack_t(t) < 0 else '50%gray', fontsize=12, text_anchor='se', arg=self) self.an_label = sim.AnimateText(text=str(self.sequence_number()), x=50, y=self.y, fontsize=12, text_anchor='se') self.an_execute = sim.AnimateRectangle( spec=(0, 0, 72, 12), x=100, y=self.y, fillcolor=lambda job, t: '' if job.tasks[ 0].start_execution is None else job.tasks[0].group.color, text=lambda job, t: '' if job.tasks[ 0].start_execution is None else job.tasks[0].machine.name(), textcolor='white', text_anchor='sw', arg=self) self.an_due = sim.AnimateLine( spec=(0, -1, 0, 13), x=lambda job, t: 200 + job.due_t(t) * scale_x, y=self.y, layer=-1, arg=self) self.an_tasks = sim.AnimateQueue(queue=self.tasks, x=200, y=self.y, direction='e', arg=self) self.enter(self.tasks[0].group.jobs) if self.tasks.head().group.idle_machines: self.tasks.head().group.idle_machines.head().activate() self.enter(plant)
def draw(self): fairway_arr = np.array([[Utilities.normalize(node.x, node.y)] for node in self.nodes]) # Make this a one-dimensional array (so we can generate a tuple easily) fairway_arr = fairway_arr.ravel() # Make a tuple (accepted by the 'AnimatePoints' function fairway_tuple = tuple(fairway_arr) # Draw all the fairway points on the map size = 3 / 4 sim.AnimateLine(spec=fairway_tuple, linewidth=size, linecolor='blue', layer=4) for node in self.nodes: node.draw()
def setup(self, restaurant, customer): self.restaurant = restaurant self.customer = customer self.driver = sim.Pdf(env.drivers, 1)() self.enter(self.driver.orders) self.enter(env.orders) self.pic_customer = sim.AnimateRectangle( (-10, -10, 10, 10), text=str(self.customer.sequence_number()), fillcolor='gray', x=self.customer.x, y=self.customer.y) self.pic_order = sim.AnimateLine((self.restaurant.x, self.restaurant.y, self.customer.x, self.customer.y), linecolor=self.driver.color, text=self.name(), textcolor=self.driver.color, linewidth=2) if self.driver.ispassive(): self.driver.activate()
def animation(): env.animation_parameters(synced=False, modelname='Job shop', background_color='20%gray') max_len = 0 for i, group in enumerate(groups): x = i * 70 + 100 + 2 y = env.height() - 140 + 20 sim.AnimateText(text=group.name(), x=x, y=y, text_anchor='sw', fontsize=12) for j, machine in enumerate(group.machines): sim.AnimateRectangle( spec=(0, 0, 60, 12), x=x, y=y - 20 - j * 15, fillcolor=lambda machine, t: machine.group.color if machine.task else (machine.group.color, 100), textcolor='white', text=lambda machine, t: machine.task.name() if machine.task else '', arg=machine) max_len = max(max_len, len(group.machines)) env.y_top = y - max_len * 15 - 15 sim.AnimateLine(spec=(0, env.y_top, 2000, env.y_top)) sim.AnimateText(text='job', x=50, y=env.y_top - 15, text_anchor='ne', fontsize=12) sim.AnimateText(text='slack', x=90, y=env.y_top - 15, text_anchor='ne', fontsize=12)
def do_animation(): global nphilosophers, eatingtime_mean, thinkingtime_mean global nphilosophers_last env.animation_parameters(x0=-50 * env.width() / env.height(), y0=-50, x1=+50 * env.width() / env.height(), modelname='Dining philosophers', speed=8) alpha = 360 / nphilosophers r1 = 25 r2 = r1 * sin(radians(alpha) / 4) for philosopher in philosophers: angle = philosopher.sequence_number() * alpha an = sim.AnimateCircle(x=r1 * cos(radians(angle)), y=r1 * sin(radians(angle)), radius=r2, linewidth=0, fillcolor=philosopher_fillcolor, screen_coordinates=False) an.philosopher = philosopher for fork in forks: angle = (fork.sequence_number() + 0.5) * alpha an = sim.AnimateLine(x=0, y=0, spec=(r1 - r2, 0, r1 + r2, 0), linewidth=r2 / 4, linecolor='green', angle=fork_angle) an.fork = fork an.left_philosopher = philosophers[fork.sequence_number()] an.angle_mid = angle an.angle_left = angle - 0.2 * alpha an.angle_right = angle + 0.2 * alpha # an.angle = forkangle sim.AnimateSlider(x=520, y=0, width=100, height=20, vmin=10, vmax=40, resolution=5, v=eatingtime_mean, label='eating time', action=set_eatingtime_mean, xy_anchor='nw') sim.AnimateSlider(x=660, y=0, width=100, height=20, vmin=10, vmax=40, resolution=5, v=thinkingtime_mean, label='thinking time', action=set_thinkingtime_mean, xy_anchor='nw') sim.AnimateSlider(x=520 + 50, y=-50, width=200, height=20, vmin=3, vmax=40, resolution=1, v=nphilosophers, label='# philosophers', action=set_nphilosophers, xy_anchor='nw') nphilosophers_last = nphilosophers
def do_animation(): global xvisitor_dim global yvisitor_dim global xcar global capacity_last, ncars_last, topfloor_last env.modelname("Elevator") env.speed(32) env.background_color("20%gray") if make_video: env.video("Elevator.mp4") xvisitor_dim = 30 yvisitor_dim = xvisitor_dim yfloor0 = 20 xcar = {} xled = {} x = env.width() for car in cars: x -= (capacity + 1) * xvisitor_dim xcar[car] = x x -= xvisitor_dim xsign = x x -= xvisitor_dim / 2 for direction in (up, down): x -= xvisitor_dim / 2 xled[direction] = x x -= xvisitor_dim xwait = x for floor in floors: y = yfloor0 + floor.n * yvisitor_dim floor.y = y for direction in (up, down): if (direction == up and floor.n < topfloor) or (direction == down and floor.n > 0): b = xvisitor_dim / 4 animate_led = sim.AnimatePolygon( spec=(-b, -b, b, -b, 0, b), x=xled[direction], y=y + 2 * b, angle=0 if direction == up else 180, fillcolor=direction_color(direction), visible=lambda arg, t: (arg.floor_direction) in requests, ) animate_led.floor_direction = (floor, direction) sim.AnimateLine(x=0, y=y, spec=(0, 0, xwait, 0)) sim.AnimateText(x=xsign, y=y + yvisitor_dim / 2, text=str(floor.n), fontsize=xvisitor_dim / 2) sim.AnimateQueue(queue=floor.visitors, x=xwait - xvisitor_dim, y=floor.y, direction="w", title="") for car in cars: x = xcar[car] car.pic = sim.AnimateRectangle(x=x, y=car.y, spec=(0, 0, capacity * xvisitor_dim, yvisitor_dim), fillcolor="lightblue", linewidth=0) sim.AnimateQueue(queue=car.visitors, x=xcar[car], y=car.y, direction="e", title="", arg=car) ncars_last = ncars sim.AnimateSlider( x=510, y=0, width=90, height=20, vmin=1, vmax=5, resolution=1, v=ncars, label="#elevators", action=set_ncars, xy_anchor="nw", ) topfloor_last = topfloor sim.AnimateSlider( x=610, y=0, width=90, height=20, vmin=5, vmax=20, resolution=1, v=topfloor, label="top floor", action=set_topfloor, xy_anchor="nw", ) capacity_last = capacity sim.AnimateSlider( x=710, y=0, width=90, height=20, vmin=2, vmax=6, resolution=1, v=capacity, label="capacity", action=set_capacity, xy_anchor="nw", ) sim.AnimateSlider( x=510, y=-50, width=90, height=25, vmin=0, vmax=400, resolution=25, v=load_0_n, label="Load 0->n", action=set_load_0_n, xy_anchor="nw", ) sim.AnimateSlider( x=610, y=-50, width=90, height=25, vmin=0, vmax=400, resolution=25, v=load_n_n, label="Load n->n", action=set_load_n_n, xy_anchor="nw", ) sim.AnimateSlider( x=710, y=-50, width=90, height=25, vmin=0, vmax=400, resolution=25, v=load_n_0, label="Load n->0", action=set_load_n_0, xy_anchor="nw", ) env.animate(True)
def do_animation(): # Animation initialisation is done in this function # In this example, the simulation code is completely separated from the animation code # Some global variables accesible from any classes and functions in the code global xvisitor_dim # x-dimension of the square representing a visitor global yvisitor_dim # y-dimension of the square representting a visitor global xcar # x-dimension of the elevator car/s global capacity_last, ncars_last, topfloor_last # Some general parameters about the simulation (See Reference: salabim.Environment) env.modelname("Elevator") env.speed(32) env.background_color("20%gray") if make_video: env.video("Elevator.mp4") # We assign values to some the global variables xvisitor_dim = 30 # x-dimension of the square representing a visitor yvisitor_dim = xvisitor_dim # y-dimension of the square representing a visitor yfloor0 = 20 # y-coordinate of floor 0 xcar = {} # This is a dictionary containing the x-coordinates of the cars xled = {} # This is a dictionary containing the x-coordinates of the leds x = env.width() # Width of the animation in screen coordinates (See Reference) # This is the width available to display all the elements on the screen # Now we assign x-coordinates, from the right to left of the screen for car in cars: # We assign x-coordinates to the elevator cars x -= (capacity + 1) * xvisitor_dim # Each car must contain visitors xcar[car] = x # We store the car x-coordinate in the dictionary x -= xvisitor_dim # Additional space (one square) xsign = x # Position of the text with the number of floor x -= xvisitor_dim / 2 # Additional space (half square) for direction in (up, down): # Position of the leds (red/green) x -= xvisitor_dim / 2 xled[direction] = x # We store the led x-coordinates in the dictionary x -= xvisitor_dim # Another square to the right xwait = x # Where to show the queues at different floors for floor in floors: # Components needed to display the floors y = yfloor0 + floor.n * yvisitor_dim # y-coordinate of the floors floor.y = y for direction in (up, down): # Led indicating the direction of the car if (direction == up and floor.n < topfloor) or (direction == down and floor.n > 0): b = xvisitor_dim / 4 # Dimension used to define the triangle animate_led = sim.AnimatePolygon( # See Reference AnimatePolygon spec=(-b, -b, b, -b, 0, b), # this is triangle x=xled[direction], y=y + 2 * b, angle=0 if direction == up else 180, # up points up, down points down fillcolor=direction_color(direction), # up is red, down is green visible=lambda arg, t: arg in requests, arg=(floor, direction), ) # if (floor, direction) in requests, show, otherwise do not show sim.AnimateLine(x=0, y=y, spec=(0, 0, xwait, 0)) # Horizontal lines for floors sim.AnimateText( x=xsign, y=y + yvisitor_dim / 2, text=str(floor.n), fontsize=xvisitor_dim / 2 ) # Text indicating the floor number sim.AnimateQueue(queue=floor.visitors, x=xwait - xvisitor_dim, y=floor.y, direction="w")
import salabim as sim ''' This program demonstrates the various animation classes available in salabim. ''' env = sim.Environment(trace=False) env.animate(True) env.modelname('Demo animation classes') env.background_color('20%gray') sim.AnimatePolygon(spec=(100, 100, 300, 100, 200,190), text='This is\na polygon') sim.AnimateLine(spec=(100, 200, 300, 300), text='This is a line') sim.AnimateRectangle(spec=(100, 10, 300, 30), text='This is a rectangle') sim.AnimateCircle(radius=60, x=100, y=400, text='This is a cicle') sim.AnimateCircle(radius=60, radius1=30, x=300, y=400,text='This is an ellipse') sim.AnimatePoints(spec=(100,500, 150, 550, 180, 570, 250, 500, 300, 500), text='These are points') sim.AnimateText(text='This is a one-line text', x=100, y=600) sim.AnimateText(text='''\ Multi line text ----------------- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
def __init__( self, model, predecessors, img_x=None, img_y=None, img_w=GLOB_SOURCE_DRAIN_RADIUS, img_h=GLOB_SOURCE_DRAIN_RADIUS, ): # initial attributes self.model = model self.predecessors = predecessors self.img_x = img_x self.img_y = img_y self.img_w = img_w self.img_h = img_h # visualization self.img = [ sim.AnimateCircle( radius=img_w, x=self.img_x, y=self.img_y, fillcolor="white", linecolor="black", linewidth=2, layer=1, screen_coordinates=True, ), sim.AnimateLine( spec=( img_w * math.cos(math.radians(45)) * (-1), img_w * math.sin(math.radians(45)) * (-1), img_w * math.cos(math.radians(45)), img_w * math.sin(math.radians(45)), ), x=self.img_x, y=self.img_y, linecolor="black", linewidth=2, layer=1, arg=(self.img_x + img_w, self.img_y + img_w), screen_coordinates=True, ), sim.AnimateLine( spec=( img_w * math.cos(math.radians(45)) * (-1), img_w * math.sin(math.radians(45)), img_w * math.cos(math.radians(45)), img_w * math.sin(math.radians(45)) * (-1), ), x=self.img_x, y=self.img_y, linecolor="black", linewidth=2, layer=1, screen_coordinates=True, ), ] self.predecessor_connections = [ sim.AnimateLine( spec=( predecessor.img_x + predecessor.img_w, predecessor.img_y + predecessor.img_h / 2, self.img_x - self.img_w, self.img_y, ), linecolor="black", linewidth=2, layer=2, screen_coordinates=True, ) for predecessor in self.predecessors ]
def setup( self, model, buffer, img_x=None, img_y=None, img_w=GLOB_PROCESS_WIDTH, img_h=GLOB_PROCESS_HEIGHT, ): # model self.model = model # initial attributes self.buffer = buffer self.img_x = img_x self.img_y = img_y self.img_w = img_w self.img_h = img_h # flags self.job = None self.state = "idle" # visualization if self.model.env.animate() == True: self.img = sim.AnimatePolygon( spec=( 0, 0, self.img_w - (self.img_w / 300) * 50, 0, self.img_w, self.img_h / 2, self.img_w - (self.img_w / 300) * 50, self.img_h, 0, self.img_h, (self.img_w / 300) * 50, self.img_h / 2, 0, 0, ), x=self.img_x, y=self.img_y, fillcolor="white", linecolor="black", linewidth=2, text=self.name() + "\n\nidle", fontsize=GLOB_FONTSIZE, textcolor="black", layer=1, screen_coordinates=True, ) self.buffer_connection = sim.AnimateLine( spec=( self.buffer.img_x + self.buffer.img_w, self.buffer.img_y + self.buffer.img_h / 2, self.img_x + 50, self.img_y + self.img_h / 2, ), linecolor="black", linewidth=2, layer=2, screen_coordinates=True, )
def setup( self, model, predecessors, img_w=None, img_h=None, img_x=None, img_y=None, img_slots=None, ): # model self.model = model # initial attributes self.predecessors = predecessors self.img_w = img_w self.img_h = img_h self.img_x = img_x self.img_y = img_y self.img_slots = img_slots # flags self.workload = 0 # visualization if self.model.env.animate() == True: self.img = [ [ sim.AnimateRectangle( spec=(0, 0, (self.img_w / self.img_slots), self.img_h), x=self.img_x + i * (self.img_w / self.img_slots), y=self.img_y, fillcolor="white", linecolor="white", linewidth=1, layer=2, arg=( self.img_x + (i * (self.img_w / self.img_slots)) + (self.img_w / (self.img_slots * 2)), self.img_y + (self.img_h / 2), ), screen_coordinates=True, ) for i in range(self.img_slots) ], sim.AnimateRectangle( spec=(0, 0, self.img_w, self.img_h), x=self.img_x, y=self.img_y, fillcolor="white", linecolor="black", linewidth=2, layer=1, screen_coordinates=True, ), ] self.predecessor_connections = [ sim.AnimateLine( spec=( predecessor.img_x + predecessor.img_w, predecessor.img_y if predecessor.__class__.__name__ == "Source" else predecessor.img_y + predecessor.img_h / 2, self.img_x, self.img_y + self.img_h / 2, ), linecolor="black", linewidth=2, layer=2, screen_coordinates=True, ) for predecessor in self.predecessors ] self.info = sim.AnimateText( text="# products: 0", x=self.img[0][0].x, y=self.img[0][0].y - 20, fontsize=18, textcolor="black", screen_coordinates=True, )