Simscript学习
Simscript安装
使用simr500_win64_gnu_student_2018-09-13.exe安装学生版
注意:最好是进入管理员用户,再安装,否则可能会出现权限不够的问题
实例学习
实例1 Bank
简介
Investigating service time of customers depending on the number of tellers and other factors.
根据出纳员人数和其他因素调查顾客的服务时间。
Preamble.sim
begin class Customer
every Customer has
a do_banking process method
end
“Object attributes” are declared in every statement within begin class blocks. In the following example, every Vehicle object has an integer attribute named ID, a text attribute named Manufacturer, and double attributes named Maximum_Speed and Current_Speed
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rlvhx8D3-1594092049646)(Simscript%E5%AD%A6%E4%B9%A0.assets/image-20200704202914225.png)]
bank.sim
main
main
write as "starting output", / using 6
call initialize
start simulation ''-- start the actual simulation run
call show_results ''-- show results in form
stop
end ''main
write as “starting output”?
/ using 6?
调用initialize
开始仿真
调用show_results
结束
routine show_results
1
routine show_results
''-- Show results in a form after simulation is complete. But first
''-- let the user admire the graphics and then click on the screen
''-- to get the results form.
define xlo, xhi, ylo, yhi, click_x, click_y as double variables
define dialog as a Dialogbox reference variable
define utilization as a real variable
当仿真完成的时候,以表格的形式展示结果。在展示结果之前,让用户先欣赏一下图形结果
定义一些变量
2
''-- display the 'endsim.icn' which asks for a user click
call erase(Bank'shape) ''-- erase the old title icon
let appearance(Bank'shape) = Templates'find("endsim.icn")
call display_at(Bank'shape)(12000, 31000)
【补充】
gui.m:guiitem’erase
Erases the graphic.
调用erase,擦除之前的title和icon
重新设置Bank’shape的icon为endsim.icn
设置icon的位置为(12000,31000)
3
''-- now wait for mouse click on the endsim icon
call get_bounding_box(Bank'shape) yielding xlo, xhi, ylo, yhi
call accept_input(bank_window)(0,0,0,0,0) yielding click_x, click_y
while click_x < xlo or click_x > xhi or click_y < ylo or click_y > yhi
call accept_input(bank_window)(0,0,0,0,0) yielding click_x, click_y
【补充】
gui.m:graphic’get_bounding_box yielding integer, integer, integer, integer
Computes the smallest rectangle necessary to completely enclose the icon. The bounding box is given in NDC coordinates. (归一化的设备坐标)
调用get_bounding_box,计算能够将icon包含在内的最小矩形,返回值为两个坐标(xlo,ylo) (xhi,yhi)?
【补充】
gui.m:window’accept_input given double, double, integer, integer, gui.m:graphic reference yielding double, double
waits for the user to click inside a window. A cursor can be shown while waiting
调用accept_input,返回鼠标点击的坐标?
4
''----- now show the results dialog
create dialog
let appearance(dialog) = Templates'find("results.frm")
file this dialog in form_set(bank_window)
以表格的形式展示结果对话框
5
''--- set the current values: parameters:
let value(find(dialog)("NUM.TELLERS")) = bank'no_of_tellers
let value(find(dialog)("INTARR.TIME")) = bank'mean_interarrival_time
let value(find(dialog)("SERVICE.TIME")) = bank'mean_service_time
let value(find(dialog)("BUSINESS.HOURS")) = bank'day_length
''-- result variables:
let value(find(dialog)("FINISH.TIME")) = TIME.V * HOURS.V
let utilization = avg_teller_busy(1) / Bank'no_of_tellers * 100
let value(find(dialog)("TELLER.UTIL")) = utilization
let value(find(dialog)("AVG.Q.LEN")) = avg_queue_length(1)
let value(find(dialog)("MAX.Q.LEN")) = max_queue_length(1)
let value(find(dialog)("AVG.CUST.WAIT")) = Bank'mean_waiting_time
''-- wait for user to dismiss the dialog
call accept_input(dialog)
end
let utilization = avg_teller_busy(1) / Bank’no_of_tellers * 100
计算银行出纳员的利用率(%)?
给其他的变量赋值
最后展示结果
routine initialize
1
routine initialize
define clockGraph as a Clock reference variable
define queueGraph as a Meter reference variable
define waitGraph as a Plot reference variable
''-- initialize simulation parameters, create entities etc.
Bank'no_of_tellers = 4
Bank'mean_interarrival_time = 2.0
Bank'mean_service_time = 7.0
Bank'day_length = 24.0
定义clockGraph、queueGraph、waitGraph作为一个可以引用的变量?
【Programming_Manual原文】
A “reference variable” is a typed pointer variable that can hold the “reference value” or address of an entity.
reference variable 可以作为指针变量,记录引用的值,或者实体的地址
【注意】
Clock
Meter
Plot
都是gui.m中的class
初始化Bank类里面的类成员(属性)
no_of_tellers
mean_interarrival_time
mean_service_time
day_length
都在Bank类里面声明
2
''-- create entities
create every teller(1)
let u.teller(1) = Bank'no_of_tellers
activate a Bank'generator now
新建实体teller(1)
【问题】
teller后面跟着的是一个括号和括号内的数字,这个代表什么意思?
#Preamble.sim resources include Teller display variables include n.q.teller accumulate avg_teller_busy as the average of n.x.teller accumulate avg_queue_length as the average, max_queue_length as the maximum of n.q.teller
以上为Teller在Preamble.sim中的声明
【问题】
Teller是一个资源?
【原文】
accumulate(或者tally)可以用于统计某个对象属性。
此处定义avg_teller_busy作为n.x.teller的平均值,定义avg_queue_length作为n.q.teller的平均值,max_queue_length作为n.q.teller的最大值。
【问题】
u.teller(1),如何分析该字符串的命名规则?
将Bank的类成员变量no_of_tellers的值赋给u.teller(1)
激活Bank的类成员generator(process method)
【原文】
Any method that is a subroutine may be declared as a “process method,” which can be invoked directly by a call statement or scheduled by a schedule statement for execution at some future simulation time. In our example, let us define a process method named Trip given the trip distance and average speed and yielding the duration of the trip.
任何作为子例程的方法都可以声明为“process方法”,它可以由call语句直接调用,也可以由schedule语句调度,以便在将来的某个模拟时间执行。在我们的示例中,让我们定义一个名为Trip的过程方法,给定行程距离和平均速度,并得出行程持续时间。【总结】
此处initialize调用generator,generator调用do_banking,这一个调用链是代表Customer进程
3
''-- Set animation speed (TIMESCALE.V) and make CLOCK.UPDATE be called
''-- every time TIME.V changes.
''-- Also: Associate the graphs with the display variables.
Let TIMESCALE.V = 1000 '' clock ticks (1/100 sec) per unit
Let TIMESYNC.V = 'clock_update'
该部分的作用:
设置图形动画的变换速度,当time.v改变的时候,clock_update函数被调用
4
''bring up a window
create bank_window
let title(bank_window) = "A Simple Bank Simulation"
call display(bank_window)
新建一个图形化窗口bank_window?
命名为"A Simple Bank Simulation"
调用display(bank_window)
【补充】
gui.m:guiitem’display
Displays the graphic.
#Preamble.sim define bank_window as a Window reference variable
预定义bank_window为一个Window引用变量
【补充】
gui.m:window
A Window is created for each separate window that is to appear on the screen. Any object that is to appear inside or be attached to the window must be first be filed into one of the sets owned by this object.
将为要显示在屏幕上的每个单独窗口创建一个窗口。任何要出现在窗口内部或附加到窗口的对象必须首先被归档到该对象所拥有的其中一个集合中。
5
create bank_view
file this bank_view in view_set(bank_window)
新建bank_view
#Preamble.sim define bank_view as a View reference variable
【补充】
gui.m:view
Each View can have its own world coordinate system that graphic objects filed into its graphic_set obey. The viewport can be sized within the window.
将这个bank_view放入bank_window中
6
create clockGraph, queueGraph, waitGraph
let appearance(clockGraph) = Templates'find("clock.grf")
let appearance(queueGraph) = Templates'find("queue.grf")
let appearance(waitGraph) = Templates'find("wait.grf")
file clockGraph in graphic_set(bank_view)
file queueGraph in graphic_set(bank_view)
file waitGraph in graphic_set(bank_view)
新建三个实例?
【补充】
gui.m:template reference gui.m:graph’appearance
Use on the left to specify the template that refers to an Graph saved by the SimStudio Graph Editor.
【补充】
gui.m:template reference gui.m:templates’find given text
searches “template_set” for a template with the matching name. The Template is returned and can be assigned to the “appearance” attribute of and Icon, Graph, or Form object. A runtime error is generated if the template cannot be found (unless no_error" is non-zero)
将reference变量和对应的gui图标链接起来
【补充】
gui.m:graphic’graphic_set
owned by a View, a graphic must be filed in the set before it can be displayed
图形属于视图,必须先将其归档才能显示
把三个graph归档到bank_view
7
''associate the display variables with the graphs
show Bank'CLOCKTIME with clockGraph
show n.q.teller(1) with queueGraph
show histogram Bank'waiting_time_histogram with waitGraph
将Bank类的成员属性clocktime和clockGraph绑定,通过clockGraph展示clocktime
通过queueGraph展示n.q.teller(1)
在waitGraph中展示Bank类的waiting_time_histogram
8
''-- display title text in top left corner
create a bank'shape
file this bank'shape in graphic_set(bank_view)
let appearance(bank'shape) = Templates'find("title.icn")
call display_at(bank'shape)(12000.0, 31000.0)
call get_parameters
#Preamble.sim define shape as an Icon reference variable
新建一个实例
将bank’shape放入bank_view的windows中
设置bank’shape的图标为"title.icn"
【补充】gui.m:graphic’display_at given double, double
This is shortcut method that will set location_x and location_y, then call display"
设置bank’shape的图标的位置为(12000,31000)
9
call get_parameters
''-- init simulation parameters from user input
let u.TELLER(1) = Bank'no_of_tellers
end
调用get_parameters
接收参数
u.TELLER(1)的值设定为Bank’no_of_tellers的值
结束
routine get_parameters
1
routine get_parameters
''-- Offer the model parameters for change by the user in a form.
define dialog as a DialogBox reference variable
define field as a Field reference variable
Offer the model parameters for change by the user in a form.
以表格形式提供模型参数供用户更改。【补充】
gui.m:dialogbox
A DialogBox can be displayed in a modal fashion using the accept_input method. Use the “display” method to show a modeless dialog.
定义dialog为DialogBox的引用变量
【补充】
gui.m:field
a Field is contained in a dialog box or palette and refers to one of the control items (Check box, value box, etc) contained in the form. Fields are created automatically when the “appearance” property of the Form is assigned. (指定窗体的“外观”属性时,将自动创建字段。)
定义field为Field的引用变量
2
create dialog
let appearance(dialog) = Templates'find("input.frm")
file this dialog in form_set(bank_window)
新建一个实例
设定外观
将dialog以表格的形式放入bank_window中
3
''--- set the current values: parameters:
let value(find(dialog)("NUM.TELLERS")) = Bank'no_of_tellers
let value(find(dialog)("INTARR.TIME")) = Bank'mean_interarrival_time
let value(find(dialog)("SERVICE.TIME")) = Bank'mean_service_time
let value(find(dialog)("BUSINESS.HOURS")) = Bank'day_length
设定dialog中每个属性的值
4
let field = accept_input(dialog)
if field = 0 or name(field) = "EXIT"
stop
endif
【补充】
gui.m:field reference gui.m:dialogbox’accept_input
Call this method to allow the user to interact with the dialog box. For modal dialog boxes, this method will return when the user presses a ‘terminating’ button. A reference pointer to the selected field is returned. For modeless dialogs, the “display” method should be used show the dialog and then promptly return. If marked as Asynchronous" in SimStudio, the current process is suspended.
使用field接收dialog表格中的数据
【补充】
text gui.m:field’name
Each field in a form has a unique name. This name will match the name given to the corresponding control in the dialog box editor. DEFAULT: assigned in SimStudio editor
如果field为空或者其name==”EXIT“,则停止get_parameters?
4
''-- now set the new parameter values
Bank'no_of_tellers = value(find(dialog)("NUM.TELLERS"))
Bank'mean_interarrival_time = value(find(dialog)("INTARR.TIME"))
Bank'mean_service_time = value(find(dialog)("SERVICE.TIME"))
Bank'day_length = value(find(dialog)("BUSINESS.HOURS"))
end
从dialog中获取参数值,设定Bank类的成员属性的值?
Routine clock_update given TIME yielding NEWTIME
Routine clock_update given TIME yielding NEWTIME
''-- This routine is called every time TIME.V changes (attached to
''-- that event in INITIALIZE.GRAPHICS. The assignment to CLOCKTIME
''-- (is a display variable) causes the associated clock icon
''-- to be updated on the screen.
Define TIME, NEWTIME as double variables
Let NEWTIME = TIME
Let bank'clocktime = TIME
End
该routine被绑定到初始化的图形界面中。当time.v改变时,该routine将会被调用。更新bank类的成员属性clocktime,和对应的图形界面的时间数值
process method Bank’generator
process method Bank'generator
''-- Generates CUSTOMER processes with random interarrival times.
define time_to_close as a real variable
let time_to_close = time.v + day_length / hours.v
until time.v >= time_to_close
do
create a Customer
activate a do_banking(Customer) now
wait exponential.f(mean_interarrival_time, 1) minutes
loop
end ''generator
该process method的作用:以随机的到达时间产生Customer进程
hours.v(默认值为24.0)
一直做:
产生一个customer
激活Customer的do_banking进程
等待exponential.f(mean_interarrival_time, 1)分钟
进入下一次迭代
直到time.v大于等于time_to_close,退出迭代
process method Customer’do_banking
process method Customer'do_banking
''-- Models behavior of a customer entering the bank (created by
''-- the GENERATOR).
define arrival_time as a real variable
let arrival_time = time.v
request 1 teller(1)
let bank'waiting_time = (time.v - arrival_time) * hours.v * minutes.v
work exponential.f(bank'mean_service_time, 2) minutes
relinquish 1 teller(1)
end ''do_banking
模拟Customer进入银行后的行为,主调函数为Bank’generator
将当前时间作为Customer的到达时间(arrival_time)
请求一个空闲的teller(出纳员)【期间可能需要等待出现空闲的teller,导致time.v>=arrival_time】
更改waiting_time的值(单位为s?)
【exponential.f】
A double function that returns a nonnegative random number from the exponential distribution having mean μ equal to double_arg, where μ > 0. Integer_arg must specify a random number stream between 1 and dim.f(seed.v), or a negative stream number to generate the antithetic variate.
一种双精度函数,从指数分布中返回一个非负随机数,其平均值μ等于双参数,其中μ>0。Integer_arg必须指定一个介于1和dim.f(seed.v)之间的随机数流,或指定一个负的流数才能生成反变量。teller为当前customer的工作时间:上述函数返回的随机数
释放一个teller(服务结束)