|
本帖最后由 zorsite 于 2015-9-23 16:05 编辑
! c* S3 w/ S) A- y( s E! h3 [' q) r e& k* k A0 i
以货架随机摆放临时实体为例学习Flexsim事件及触发机制 # b) I/ s: g/ F7 q5 X; R7 R: ]
很多初学者都对flexsim的事件及触发不太理解,到底先执行什么后执行什么,先触发什么后触发什么?用户手册中也没有相关的说明。如何才能把这件事情弄明白?其实并没有想象中那么难,只要稍稍花一点时间,你就能彻底掌握其中的奥妙。0 T9 x1 J/ ?# s4 _3 k
接下来我们以货架随机摆放临时实体为例,来看一下在flexsim中,各种事件、触发的发生顺序。, g ?. W q+ \" {
在flexsim中依次拖入货架、发生器、暂存区,软件会将这三个实体自动命名为Rack2、Source3、Queue4(请注意这三个实体的拖入顺序)。依次A连接发生器、暂存区、货架。双击打开货架属性,勾选“Floor Storage”,设置最大库存为50,设置列和行随机摆放,每个货位内最大摆放量为1,设置货架为5列10行。
% Y3 y" I1 w1 C6 o1 R
/ w3 Z* t5 q' E' E
* Z2 V& U; X* G重置视图,最终效果图如下所示:9 j0 Z* J7 S/ Y7 L9 T( z
, V3 X+ _6 [* Z$ a1 n7 r7 m9 @1 q$ S; e
在debug菜单中选择EventLog,打开Event Log窗口。1 @; ~) I' \4 F& g4 S
r! m- \5 O) [# K
点击settings按钮,我们可以看到flexsim可以记录的事件类型和事件列表。3 T, N0 g4 d5 {$ W3 v
5 _. e# ^% [3 |9 M- ]6 ^+ p. zFlexsim把事件分为了四大类:Engine、Trigger、TaskSequence、BeginTask。
5 i0 D" S6 |5 [6 w3 {/ P8 q
) b* p9 Z' l& h0 t5 T' f( V9 E引擎事件包括了创建实体、摧毁实体,打开输入/输出端口,接收实体,发送实体,发送消息,定时事件。
% M/ _2 u) ^: K' t) C: Q! g* P( P
触发事件就多了,我们在实体属性的触发选项卡中见到各种触发都可以在这里找到,还有属性窗口中的一些设置项也可以视为触发。比如发生器的“到达时间间隔”,处理器的“预置时间”等,flexsim也将其归类为触发事件。 u1 ]5 A# x" |7 @9 u
, Q0 m V" E |4 X6 _9 ^# R) t4 y
TaskSequence和BeginTask其实都属于任务事件,flexsim将其细化,分为两类。
- U& u9 s% x; D4 [/ n* @任务序列事件只包括开始任务序列、结束任务序列、接收任务序列。9 e2 @3 U6 [5 ^, m0 E* ?! k) W
) ^! C9 F* I B3 V
开始任务事件则是任务序列的具体过程,比如装载、行走,卸载、中断、移动实体等。" M6 ?( N/ r: H; B) t* r9 ` z7 i
. g; a6 |0 b- r, \+ s在Event Log窗口勾选”EnabelLogging”,运行模型一段时间后,点击”Export”,将事件日志导出保存。也可以自己指定运行的时间段,比如设置Start Time为0,End Time为15。
: [) T( I5 v! B z" ~1 g0 P打开保存的日志文件,就可以看到flexsim模型在运行过程中各种事件、触发的顺序。1 a( t* v+ B3 z0 i" [% z( D+ J! Z
( F, [( H, b# Q9 U9 h
先看一下0时刻模型发生了什么:" o5 x5 T, X$ W @" o& z- u
Time# G; Q1 N5 H! K6 {8 R4 t
| Object9 q5 W0 A+ w7 Y4 _4 p0 A
| Event
u5 g3 r: `( t2 {4 ~ | 0$ w* B- F% C3 m
| /FlexsimModelFloor8 f2 ^+ @- B9 D5 r g# d& S
| Trigger: OnReset5 @4 U' R2 L, r9 O6 A
| 0
a, L+ k# W+ _/ w | /Rack4% k# ~9 ^7 z2 R( R' g" p" U
| Trigger: OnReset
# x9 F$ T0 M0 U; v$ ~ | 0% D; T5 n1 Y3 @7 M7 }5 b* {% v
| /Source3# c0 [ w. i$ K% G0 \4 E
| Trigger: OnReset
. N& K4 L1 \9 t0 Y | 06 o$ y, c7 ~- i# t5 Y5 P
| /Source3
$ w2 p6 }+ n' L4 f9 f+ p- | | Trigger: Inter-Arrival Time
4 | |. a! X# i2 Z0 ^3 u( y7 r | 0
2 E2 Q# e& p% M# ]9 U/ @0 i) Q | /Queue4$ m1 @: r4 u/ I" S3 J+ D. Y
| Trigger: OnReset
: @8 m. m9 y( f0 l/ f" F | 在0秒的时候各种实体会激发OnReset触发。本例中依次激发了FlexsimModelFloor、Rack2、Source3、Queue4的重置,重置的顺序并不是按照模型逻辑,而是按照实体创建的顺序。在创建模型的时候我们最先拖入的实体是货架,所以货架在发生器和暂存区之前被重置。而在货架之前,flexsim自动创建了ModelFloor实体,所以货架的命名是从2开始的。这一点可以打开树结构验证。
! q8 C# D8 Y$ P4 J8 w9 h1 n: ? D
7 r$ C& p. C) E# ?: P在发生器被重置之后,马上触发的“到达时间间隔”触发,这是为了决定什么时间创建第一个临时实体。9 e; b3 Z' T! x1 T
在5.303038时刻,发生器创建了第一个临时实体,并由此引发了接下来的一系列事件和触发:
0 ?) v8 t# {) [ Time: w! e4 Q9 u5 m+ ?/ G
| Object
& T6 X) `9 R) d: K) r/ A j | Event& u/ ?7 f6 |, ]4 W* M
| Involved; R, }" D0 S; \
| P1# j% T6 z+ P0 V
| 5.303038
5 x- x4 T8 e& c" c! F | /Source3* j5 \- G% `: w5 A
| Engine: Timed Event
: B8 H2 h+ O% K; W | /Source3
) ~, v- F/ u" b$ m6 K- ]% R% a7 t | EVENT_CREATEPART
3 `- J9 Z8 Z; r. A m | 5.303038
% @4 a) V4 ~% X8 w+ j0 r | /Source3
. O8 h5 V: o' O& C7 w | Trigger: OnCreation9 Z0 D y/ q. [/ m1 g
| /Source3/Box6 A& z) b3 N: D# {. A
| rownum: 0.0
; q1 Y, R1 B! _8 G+ W r | 5.303038
# r7 `* B; F/ b, d6 ~" K | /Source3" Y; A" S! L! U2 i# y0 m
| Trigger: Send To Port7 y' ]" ~ ]; W+ Q+ U$ J7 G
| /Source3/Box, B4 y' v" x5 O4 @- w) {: j6 K
|
7 N r$ {0 ^7 v5 G- W4 u$ e2 r; i$ t6 Q; s- x3 K* S7 a
| 5.303038- {! Z1 X0 A G# {
| /Source3, [) R5 h, r3 G$ N; b
| Engine: Send Object3 o& o; J8 X) [3 B" ^9 p
| /Source3/Box: b; g+ g+ g( Q0 `; d7 `$ z
| . J! l8 ^- m, L4 D. @5 O' `: C
+ h$ |; N% p) j% n: h | 5.303038
& L* b3 Y- z4 U6 m! s+ w) m) Q | /Source3
4 b; E8 ^2 ]* B8 E8 K | Trigger: Inter-Arrival Time% t* \- M4 k3 g( x5 ]
|
7 l) b, }7 T$ F1 g5 v$ n, u
* ~1 e1 S) p( l) }! P# l0 t |
# }* m5 A) U, `+ Z' E6 D- {7 m( w' Z; h% b
| 5.303038: c# Q9 S- l% W- q9 \2 r: d
| /Source3
" b0 R. S( S. S | Trigger: OnExit( W$ [6 c) V+ p/ f+ m9 j: ~4 m4 _
| /Source3/Box
% I1 N, @" q: j4 o1 V4 P% P | port: 1.0
, z# Y2 V5 b! ?) b | 当临时实体被创建时,首先执行的是定时事件:CREATEPART,然后才激发“创建触发”,临时实体被创建后,还要决定其从哪一个端口发送,然后执行发送,临时实体离开发生器。而在临时实体离开之前,发生器还激发了”到达时间间隔“触发。 V; f7 x1 ?( @5 y
本例中的每个实体都是以Engine事件开始,要么创建,要么接收。暂存区正是以接收实体事件开始: n I) P4 @8 y! N/ e1 |" q
Time1 [ D- e# A$ k D
| Object' X& J* C- V( ]
| Event# m- W- ^+ S1 B _
| Involved
+ X* |3 T0 p" h | P1
( ^; z9 y6 s+ d | 5.3030389 [& h8 `8 x, p. @: ^8 [
| /Queue4
: h1 c3 T9 A5 F7 q | Engine: Receive Object/ |% J3 i% ]: l3 S4 ^5 |( T8 D
| /Queue4/Box
" M* u: c* X a& O( \2 Y7 Q) B | 8 z5 B) d6 R! y. m l7 j
2 X9 n# }6 E9 V2 K9 C; Z
| 5.303038
- {4 R, J# G$ ^ | /Queue4
7 [# S5 H X) Z3 V' H$ q# R | Trigger: OnEntry$ h" k& Q; q, O( j/ p9 K6 B1 S
| /Queue4/Box+ I- w$ Y3 P, Z& J, b
| port: 1.0
5 _: K/ V! p a$ i/ X) X! L# L/ X | 5.3030380 W m2 P# _4 }
| /Queue4; f/ w& B- F8 V' p: E/ y6 @
| Trigger: OnEndCollecting. A. c$ U1 F' l; F
| /Queue4/Box
$ w7 X, P6 \6 \8 W0 Z, Z | batchsize: 1.0$ r$ c% q5 r' F
| 5.303038
) g5 r' T- W9 G/ e: d/ d | /Queue4( ?* _, W1 e n J' W+ b' N
| Trigger: Send To Port
# T8 L: R3 [& n, e& K6 r | /Queue4/Box: ^2 J0 f2 u9 k2 Y8 S7 z( X
| 0 N' b! X1 ~5 w& x
% \9 N/ a9 T- x0 C" H% n | 5.303038; g1 z( \5 K6 B b
| /Queue4
3 V$ w) S: N/ D6 S) x | Engine: Send Object
! }# X' G6 G/ p9 Q' R4 w# x | /Queue4/Box' H1 h" Z3 }' D& H# H# e+ n
|
& ?2 W% E' X! ?1 o5 g$ V
# L& _( w, g( T7 O4 G4 P0 e | 5.303038, I: i9 H2 V9 |2 Y
| /Queue4* d! G3 V! {4 d
| Trigger: OnExit K% {, W4 A) B
| /Queue4/Box6 X! t) M( t; N- D# X+ j5 A% m2 z1 Z
| port: 1.0+ O4 J& S" m& I6 X$ C' V
| 接收实体之后激发了进入触发,然后判断批次,获取发送端口,执行发送,最后离开暂存区。
7 t4 H+ s9 L6 @货架同样以接收临时实体开始:+ M9 j. D, n+ K& [" w: ]5 u
Time- b/ ]& K1 K: M) ]2 s0 ~
| Object
3 [) u4 a7 C: p; i2 M# ^; Y& O | Event
$ y1 v$ ~9 ~: K8 M8 P | Involved
) z, Q! f/ `8 J) C* Z | P1
2 z( D. X( Q8 C6 u8 E | 5.303038
: Q0 y, L' J" t# |* E | /Rack4% n/ n: E' [& g2 L) O6 o+ V
| Engine: Receive Object
/ T* s6 ~1 W; r3 s/ y | /Rack4/Box: H3 u& W+ u, q. u. z: j
| 6 |( H% L' X0 u+ ]1 q- _8 k
2 Q! Z% N' K; i: s o4 C$ R G% m | 5.303038
9 F6 k' ?9 S' ?' w: ?' L1 S | /Rack4
% W/ _% x9 X: f" W. [ | Trigger: Place in Bay1 N6 Z$ G0 x5 S; i
| /Rack4/Box
5 N) {/ H& g' k2 ?8 [, J: G |
3 q1 |3 _7 G- G S
9 o& C* ?- n+ K4 p. D* r% z8 J) L | 5.303038
, | N/ n4 ?$ q2 }. V+ o% F$ x4 Q | /Rack4
: s# g1 H: z; Y( [4 K% ?% @ | Trigger: Place in Level. Z& v. H& {- N8 P
| /Rack4/Box
. K3 q3 ?2 N6 k | bay: 3.0
& E( l$ g, ^5 d2 y; E8 K | 5.3030382 s! B$ d" P5 n$ N2 N
| /Rack4
2 d5 b; X9 H) a2 n0 U | Trigger: OnEntry2 o, p7 k4 d8 {/ R" q
| /Rack4/Box
6 k) h% X- N# S W( a, j | port: 1.0
$ y) j$ K' Y) p | 5.303038
9 A# E0 z% a; r- j2 o8 O" Z | /Rack4
9 b& V" q6 _$ Q1 W, X: ~, [ | Trigger: Minimum Dwell Time% G# x {" m3 Q/ w
| /Rack4/Box2 g: D4 w. P' R1 _7 \8 V( y0 W
| port: 1.0
8 z# i0 T# L3 n8 S | 5.303038
% R( |. C7 _4 \( C+ d4 A | /Rack4+ O' q' E% A. I
| Engine: Timed Event
. ] J9 k1 W9 \* u" D | /Rack4/Box+ h1 g( x* S% k) ^) R, U3 ^ P
| EVENT_PROCESSFINISH
7 L2 ^6 M W5 ?$ Q3 } | 5.303038& _. q6 U% E. N9 B1 \- [' b
| /Rack4
8 {8 F, y; O! p8 H. o | Trigger: OnEndDwellTime
' {+ \# _$ j/ _5 \7 O4 |/ L8 r. y | /Rack4/Box
) w, L7 ~0 N+ ^6 S% i/ ~7 a |
* X$ F* P$ d! C& Q) s4 {: [/ p5 ]) N! Q+ b
| 5.303038
9 l Q! a! V! i5 X, m' \ | /Rack4
: z5 {! u1 c8 o4 \- \0 l | Trigger: Send To Port
7 C* e6 n0 I% |! ?: h' T | /Rack4/Box
+ Q4 W" j3 K R1 z3 Z' j; ] |
0 Y s) [6 V, h) {4 q* R |- y0 ?1 l0 q2 V* m, I0 N' W& c: M4 Y
| 接收临时实体之后依次判断应该放置在哪一列、哪一层,然后激发进入触发,临时实体进入货架之后需要获取其在货架最短停留时间,由于这里设置的最短停留时间是0,所以随即激发定时事件PROCESSFINISH(如果是停留结束会更合理、更便于理解),再激发“停留时间结束“触发,最后获取发送端口。由于本例中并没有为货架指定下游端口,所以这里没有执行”Send Object“事件,也没有离开触发。, _8 @- G- m8 a9 H5 `- }3 Q
接下来的其他时间节点都是在重复着同样的事件和触发,直到货架被摆满。2 m0 w1 E" ?' J
通过Event Log工具,我们可以详细的分析每一个实体的工作机制。比如可以分析推式策略、拉式策略的不同,比如可以调用运输工具,添加任务序列,来分析任务的优先级别、先占级别的处理机制等等。
' h- T( R7 ? `1 G! ]
4 J# T; m, i3 W& d
7 W) v4 @; g7 W2 t8 N1 k) g+ ]! b% k# d0 E, |1 j0 d
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
|