|
本帖最后由 zorsite 于 2015-9-23 16:05 编辑 4 h, X; d9 g! n
8 m" Z2 ^" A! ? d+ m
以货架随机摆放临时实体为例学习Flexsim事件及触发机制 z: K: W# P' ] A7 u) p9 p
很多初学者都对flexsim的事件及触发不太理解,到底先执行什么后执行什么,先触发什么后触发什么?用户手册中也没有相关的说明。如何才能把这件事情弄明白?其实并没有想象中那么难,只要稍稍花一点时间,你就能彻底掌握其中的奥妙。
3 W7 N. ]: B( Q& y% g8 ?接下来我们以货架随机摆放临时实体为例,来看一下在flexsim中,各种事件、触发的发生顺序。
' a1 Y4 n, z2 `0 k在flexsim中依次拖入货架、发生器、暂存区,软件会将这三个实体自动命名为Rack2、Source3、Queue4(请注意这三个实体的拖入顺序)。依次A连接发生器、暂存区、货架。双击打开货架属性,勾选“Floor Storage”,设置最大库存为50,设置列和行随机摆放,每个货位内最大摆放量为1,设置货架为5列10行。0 ^# a6 u* E4 D% k
4 D: ~8 G3 D# w& d" W4 ?$ Q3 Z9 a
, V! L- e: t9 K' B q! G- [重置视图,最终效果图如下所示:
- e4 b9 x. A5 ~( d' W8 E: c J2 J* m6 x2 \+ U) l# [
在debug菜单中选择EventLog,打开Event Log窗口。1 K, j% i4 F5 L
$ g& Z$ L, T, ^' x/ D+ H0 ?8 G9 R
点击settings按钮,我们可以看到flexsim可以记录的事件类型和事件列表。7 I+ w0 W' q& k+ [4 s7 Q
9 N( ^$ U- g+ r I, x4 Q/ W8 @Flexsim把事件分为了四大类:Engine、Trigger、TaskSequence、BeginTask。
9 {5 B4 r8 Q+ d9 d# I: W9 h: E# ~2 n5 k" } e% E
引擎事件包括了创建实体、摧毁实体,打开输入/输出端口,接收实体,发送实体,发送消息,定时事件。! D! C) P) _7 h+ P' `7 O: w% x2 z: J0 e
* t) X% t; L( N$ W( f2 b
触发事件就多了,我们在实体属性的触发选项卡中见到各种触发都可以在这里找到,还有属性窗口中的一些设置项也可以视为触发。比如发生器的“到达时间间隔”,处理器的“预置时间”等,flexsim也将其归类为触发事件。
9 C. {9 J0 t0 o9 D+ N" g6 }$ S$ P: H
TaskSequence和BeginTask其实都属于任务事件,flexsim将其细化,分为两类。% w) l/ h+ l! k& P
任务序列事件只包括开始任务序列、结束任务序列、接收任务序列。
& K! E k0 Z! H/ j% |( V
/ \+ T" |& Z Y t% K开始任务事件则是任务序列的具体过程,比如装载、行走,卸载、中断、移动实体等。$ ^: G+ T% Q' o/ f
* e' z2 ~5 ]' v% x
在Event Log窗口勾选”EnabelLogging”,运行模型一段时间后,点击”Export”,将事件日志导出保存。也可以自己指定运行的时间段,比如设置Start Time为0,End Time为15。2 U: v+ Y; X: ^8 g* O, Q4 U5 E
打开保存的日志文件,就可以看到flexsim模型在运行过程中各种事件、触发的顺序。
8 d5 c( F6 |8 T. R
, _+ c h* l. p4 m9 u4 o8 m j* \4 ~先看一下0时刻模型发生了什么:
) w0 r( l/ l4 ^0 x6 [- L Time
" j5 \" ?6 U4 H% q) ], R | Object
6 N# y7 B4 r% n! t5 C8 v& X | Event. d, Q7 |8 ?* P; R
| 0
5 D5 {) n: C+ C | /FlexsimModelFloor
( E9 q3 n! |. \+ h | Trigger: OnReset
5 r( [6 T1 t8 n0 w5 w& k) S. _ | 0
) J4 S3 `4 O* x, O0 R | /Rack4* N0 e. Q; g$ V7 V3 B
| Trigger: OnReset
3 d- m6 b% z0 T: X/ O. a/ r( R | 0( {3 ^, R8 ?4 q
| /Source3
) u* L% X$ z( O$ x | Trigger: OnReset- C N. M" z1 B' H) \
| 0+ v& G' Q, a1 D. j+ `8 B
| /Source3. |, s( v" h* Z( Y, K0 c
| Trigger: Inter-Arrival Time
: u# m5 F, a& g. n0 \ | 0
) s0 w7 J7 \) \) z& o% ?1 B | /Queue45 F# M. S: [& z5 p1 T9 i! g' H
| Trigger: OnReset/ k6 F1 _/ j8 f) Y
| 在0秒的时候各种实体会激发OnReset触发。本例中依次激发了FlexsimModelFloor、Rack2、Source3、Queue4的重置,重置的顺序并不是按照模型逻辑,而是按照实体创建的顺序。在创建模型的时候我们最先拖入的实体是货架,所以货架在发生器和暂存区之前被重置。而在货架之前,flexsim自动创建了ModelFloor实体,所以货架的命名是从2开始的。这一点可以打开树结构验证。
0 n6 |& z* H' ~$ o* u/ o: Q) K; x2 P3 Y) u
在发生器被重置之后,马上触发的“到达时间间隔”触发,这是为了决定什么时间创建第一个临时实体。# P/ [# y3 E( S/ B
在5.303038时刻,发生器创建了第一个临时实体,并由此引发了接下来的一系列事件和触发:( N/ c5 y( q* q/ k* g# v
Time
8 D4 ?& B$ H$ R- q3 F1 T4 E* g | Object9 k. N( J: @9 J5 E- _5 T' C
| Event5 k. J9 U) G5 l7 ]+ F1 q1 n# b
| Involved' }; t& w4 _9 n) Z
| P1' X5 h( l) [# t1 ^) x# Q+ F# i
| 5.303038, X/ V+ ]1 _: ^# f
| /Source3
\# N6 A, z8 R; {$ I7 z | Engine: Timed Event( k, [2 A- F7 ?7 Y; y ?: m
| /Source3
, B2 I0 q5 M! i | EVENT_CREATEPART
) g" v9 x$ x9 u/ _- J( H E | 5.3030382 C. V' F! @( ~
| /Source3' s$ M# u( \' d
| Trigger: OnCreation
1 G: [# U" K" }. {5 g- c& l% M+ |( j+ { | /Source3/Box
4 {/ _+ @) `2 f7 O | rownum: 0.0
`; {: J! y2 w; s" k | 5.303038
! P6 _3 ?# H6 ]8 N* c( ?" z V# K1 c | /Source3) @$ E0 j/ B' ]/ m4 v$ Z8 n' x
| Trigger: Send To Port
a$ \# h( v) d | /Source3/Box. F* M9 W! ~3 o8 `( K I
| 8 {+ K0 }& {! X# e3 h ~
* r; S A4 P4 m* x( G& O | 5.303038; a( `$ d: H/ r% b" c: @& Q
| /Source3
; Q% v- X$ Q4 m: ?! I. f w! M+ O' x3 o | Engine: Send Object1 W2 p4 b, |3 Q5 Q" e: F
| /Source3/Box H! X# P& i; ]" B
| ' H A2 Y! t' {9 V) p
8 I" N- i3 Z/ {. [1 m5 r% l% A
| 5.3030386 v" z6 ^( B/ Z0 {$ u1 T3 W
| /Source38 [: X7 @' B* _/ p: r
| Trigger: Inter-Arrival Time3 ?$ I# r9 K9 }2 ^% j, B
|
& N4 M: u1 ]( _+ z# g3 ^* F
9 ?% i' B- |" j/ x2 f |
( \( ^( B: J! i5 v+ o
; V$ b' Q k3 w- W$ s | 5.303038
# N$ q1 U; G7 T# x/ O) f# N | /Source3
, E; q! H* ?( {+ _ | Trigger: OnExit/ Y+ U% \( i' i: a+ ~2 ?4 i
| /Source3/Box
" O9 G& ]) a, V8 S/ ? | port: 1.02 R2 h$ f+ Y8 t1 c% O
| 当临时实体被创建时,首先执行的是定时事件:CREATEPART,然后才激发“创建触发”,临时实体被创建后,还要决定其从哪一个端口发送,然后执行发送,临时实体离开发生器。而在临时实体离开之前,发生器还激发了”到达时间间隔“触发。
8 Q3 |0 l4 F1 l/ h本例中的每个实体都是以Engine事件开始,要么创建,要么接收。暂存区正是以接收实体事件开始:
# d3 L/ k7 V. ] Time
7 v# ?9 _+ P% D9 h | Object* ~( @* @ t' L' v8 D
| Event
2 m9 n+ M. h3 R! _; x2 o | Involved
4 j$ ?" T, |( G: S' c4 b( G" } | P1- R( i& A, K8 ^
| 5.303038
: S) ?' W$ \' ]" A$ b | /Queue4; l% h9 B, E0 b3 G/ o
| Engine: Receive Object5 I- H: i3 t! n0 s I/ ~( X
| /Queue4/Box- G1 A# ^7 y( Y3 B8 V5 R
| * K/ r) W9 ]$ ^6 r
* w8 c& @2 c6 O7 F- o, q7 V | 5.3030381 A8 d7 m/ K: j9 z( F! m
| /Queue4. J* O8 y: b" D/ G. s
| Trigger: OnEntry
3 t5 Z7 ]) Y( N, P5 p | /Queue4/Box
2 G' W* ]- G" M& [7 q1 t/ J8 O | port: 1.06 p4 \; N! I4 w% T" J
| 5.3030380 k- J9 S2 I1 A
| /Queue4. n# s+ W! _: L2 s2 v' |
| Trigger: OnEndCollecting* A1 D2 z7 {6 R& V( y4 _
| /Queue4/Box
! I; O* B4 T+ }- w G6 D9 T6 [ | batchsize: 1.0/ }" o; n9 z$ {4 E' z
| 5.3030383 v* j& s/ H% q2 R8 O; C) k4 M5 ?5 H
| /Queue45 E0 ~1 b" [; c% b
| Trigger: Send To Port& |. P8 f6 z7 J) s
| /Queue4/Box
, b2 D% ^- y/ o2 m) a" [0 o Z |
* z+ i% N% G8 T* E$ T3 Q! v- O9 X
4 i2 g( v. T* I2 |' Y# T | 5.303038# @8 \" [7 s" w. q y2 J
| /Queue4
" c& q {4 `. |7 z- U0 e# Z | Engine: Send Object. }2 t! K4 ^( @ ~3 ^* `
| /Queue4/Box! d) b7 A, a# y: ?. h3 Z0 o
| ; q0 r" I, p% f% @" j$ y: B7 \
; H, E! L; F4 q( w* N& u
| 5.303038
7 N0 M9 F, ^! P. j( ^$ o9 r | /Queue4: R$ y8 A8 R- G; d
| Trigger: OnExit
2 U0 f# f8 ?" s) J; q; | | /Queue4/Box( R3 |3 Z1 s I& R, j) d% o
| port: 1.0' F, f; F( \% v p
| 接收实体之后激发了进入触发,然后判断批次,获取发送端口,执行发送,最后离开暂存区。5 k; \" X9 J S5 Q+ r% x
货架同样以接收临时实体开始:/ G- r8 x# o5 d( k) {3 ~6 G
Time
! |/ W& b! f6 L* d. x1 C9 V | Object, k* N4 e; e* q' w( q) {( h; D
| Event0 Z: \/ n9 a/ K. L. @2 ~
| Involved( Z$ k: U. M& |. }( ^. \ B
| P1
0 ~( c& Q& J8 R | 5.3030384 K2 \ N0 f7 C6 _; n& R+ C, z
| /Rack47 d7 n6 J0 w# r V
| Engine: Receive Object0 E+ v& q* x R2 A+ V
| /Rack4/Box! Q% J# D; G; s/ i9 N# b) @
|
, G6 W& x8 Q+ g7 |' f2 B9 G: r9 `7 W" \+ c! ~" E( e, B
| 5.303038% S: ]2 E! J2 Y C) t7 k' a/ w
| /Rack4
/ @2 Y3 R+ ~- K: { | Trigger: Place in Bay
; G" t ^+ d1 c8 ~' q4 u | /Rack4/Box
/ S( s y# y3 L: f6 C |
! Y" t. }" T: W* D. \* F) H
$ h6 e; F0 L. X$ D+ ^2 h' ~ | 5.303038* v/ ]' s3 G- ^
| /Rack4# H4 S+ Q" p1 X2 d) k
| Trigger: Place in Level
% ~7 `1 c! F8 u2 x | /Rack4/Box
% ?. g; [8 m8 H, H& v1 r7 b( M | bay: 3.01 f- V( f5 M" U+ v2 c: L/ `
| 5.303038 x0 e! [3 X5 }+ }8 ^# j
| /Rack42 x6 l* B3 S( D) O: ~" Z
| Trigger: OnEntry0 K6 ?* d( a% \% A6 R! r
| /Rack4/Box
; G6 `; g; N3 y6 V; Y3 `: j | port: 1.0
( c* F* t; [& Q5 | | 5.303038
6 w0 Z6 f. p( c | /Rack4
5 f$ F# p) S3 z/ [ | Trigger: Minimum Dwell Time
% y, e0 H! S2 `: \- T3 B( J | /Rack4/Box4 T$ B6 [: X u+ \" ^
| port: 1.08 n* v. e4 g* N! ?* \1 V8 u G/ F
| 5.303038. L. d& i! U* w
| /Rack4
2 [, L% @7 y" w1 j7 I | Engine: Timed Event
) O$ t |) j+ W: b4 ?, g | /Rack4/Box
& N' [$ I- ]) q2 B4 [4 Z5 u$ K | EVENT_PROCESSFINISH& C7 _! \) w, O1 N' q% I
| 5.303038
, K, Z6 Y* J u) K# O( G | /Rack4
' w9 ?1 l4 l, A* t# x0 }& K7 c | Trigger: OnEndDwellTime
. _; [) P' {' B0 @ | /Rack4/Box; U$ p2 j" h$ I. i
|
* q1 x! d( y; M7 _8 p8 r0 J1 ?' d3 s5 l) Z9 h' U1 r) A9 W) m
| 5.3030386 a7 L3 }8 ?6 `( \: C' E# T
| /Rack42 A- {& B$ S' @ o; J; j( r
| Trigger: Send To Port
% _2 ]; A8 q j+ o9 ^ | /Rack4/Box+ M& v1 w5 |. x7 ^1 _' N
|
6 W2 `" m" N5 J, ]) r, A# i+ V& s- u6 Z- c) X
| 接收临时实体之后依次判断应该放置在哪一列、哪一层,然后激发进入触发,临时实体进入货架之后需要获取其在货架最短停留时间,由于这里设置的最短停留时间是0,所以随即激发定时事件PROCESSFINISH(如果是停留结束会更合理、更便于理解),再激发“停留时间结束“触发,最后获取发送端口。由于本例中并没有为货架指定下游端口,所以这里没有执行”Send Object“事件,也没有离开触发。3 A* s& _, q9 ]: J# [# I
接下来的其他时间节点都是在重复着同样的事件和触发,直到货架被摆满。: B: H' k/ a# t! N4 Z& v
通过Event Log工具,我们可以详细的分析每一个实体的工作机制。比如可以分析推式策略、拉式策略的不同,比如可以调用运输工具,添加任务序列,来分析任务的优先级别、先占级别的处理机制等等。 H- Q: x8 b! \3 p( _
' R w; T( t9 P# {8 s
, c/ B0 X) Z7 _$ ^! F$ Y5 z! n$ N
9 S. ?0 f. B7 ^# a/ q8 S9 K |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
|