|
本帖最后由 zorsite 于 2015-9-23 16:05 编辑 # I B& @2 V* d& G# y9 \" o5 C6 |% _
& h: F5 L% F9 w. e# u0 X" |' G. t7 O
以货架随机摆放临时实体为例学习Flexsim事件及触发机制 # p$ L% n5 @" ?& j) |
很多初学者都对flexsim的事件及触发不太理解,到底先执行什么后执行什么,先触发什么后触发什么?用户手册中也没有相关的说明。如何才能把这件事情弄明白?其实并没有想象中那么难,只要稍稍花一点时间,你就能彻底掌握其中的奥妙。
0 u _) B4 O& D! f5 O$ {6 C; g接下来我们以货架随机摆放临时实体为例,来看一下在flexsim中,各种事件、触发的发生顺序。0 W# x. @4 d0 o9 z# \/ w# @" w' G$ z0 C
在flexsim中依次拖入货架、发生器、暂存区,软件会将这三个实体自动命名为Rack2、Source3、Queue4(请注意这三个实体的拖入顺序)。依次A连接发生器、暂存区、货架。双击打开货架属性,勾选“Floor Storage”,设置最大库存为50,设置列和行随机摆放,每个货位内最大摆放量为1,设置货架为5列10行。
* P2 y- o" _, A8 j4 y0 r7 D8 K 2 N7 T+ N1 N$ _, H( U5 A9 o
! x1 k& Y4 D1 j& j' m重置视图,最终效果图如下所示:
4 R7 d" s# M! j1 t: V8 U" Z% S" T6 H9 K W
在debug菜单中选择EventLog,打开Event Log窗口。6 i1 k; M( X, n' B" [ G
+ j7 j3 X( R8 n: V2 c点击settings按钮,我们可以看到flexsim可以记录的事件类型和事件列表。6 h9 A# \& L( Q! `) h L5 V
" J, j i2 y6 t+ w& |* j& k
Flexsim把事件分为了四大类:Engine、Trigger、TaskSequence、BeginTask。
5 W; {/ `2 U+ }/ O5 b) e: K' A' m7 T9 p7 N
引擎事件包括了创建实体、摧毁实体,打开输入/输出端口,接收实体,发送实体,发送消息,定时事件。
! S4 H, L7 S3 [8 q. j* X$ a( l! u/ ?& H. _+ S/ G% B8 |' ~: e
触发事件就多了,我们在实体属性的触发选项卡中见到各种触发都可以在这里找到,还有属性窗口中的一些设置项也可以视为触发。比如发生器的“到达时间间隔”,处理器的“预置时间”等,flexsim也将其归类为触发事件。
/ r' x+ {* a" S0 l2 k+ \
7 [' k7 v, {: i; MTaskSequence和BeginTask其实都属于任务事件,flexsim将其细化,分为两类。& c5 {6 e$ y0 ^' g7 D4 x: q8 m
任务序列事件只包括开始任务序列、结束任务序列、接收任务序列。
/ I5 r2 r! r+ D2 H! }/ z% r+ s/ \. Y( e/ O( {
开始任务事件则是任务序列的具体过程,比如装载、行走,卸载、中断、移动实体等。
& c, Q N9 H0 ~; P; _( z$ M% K& h" Q" f/ g w7 T1 L, A* L# u
在Event Log窗口勾选”EnabelLogging”,运行模型一段时间后,点击”Export”,将事件日志导出保存。也可以自己指定运行的时间段,比如设置Start Time为0,End Time为15。
! q* t6 b# w/ L打开保存的日志文件,就可以看到flexsim模型在运行过程中各种事件、触发的顺序。
$ _; |) Z, P6 O/ @' O: M6 j' l0 t @3 y' M m
先看一下0时刻模型发生了什么:
$ K/ S. S* [. P F4 F6 K! c Time W% P! G6 e% M. t. f% K" x y
| Object
0 k- Y" r+ A' F! k1 p% \% Z5 j | Event# ]7 l6 u* O# y( ]' D3 P7 a4 ^
| 0
3 q. t- }; y$ V0 H: b8 ] | /FlexsimModelFloor; a; O$ [* b8 S* N: I. F
| Trigger: OnReset" U! x/ `: e6 J( V4 R2 x9 q
| 0
+ @' ?) d& m9 { | /Rack4! g; j3 y9 X( N5 O. l
| Trigger: OnReset
+ f* @* b* l3 s7 I7 e3 y! `& } | 0( t- C6 h) B$ u ~. C9 a" v
| /Source3
. O0 R/ L7 w% U: r | Trigger: OnReset5 a4 g- Z9 ~5 P1 x3 g, B9 Q
| 0$ w+ c" {, }! i( H- n( C* N
| /Source3
) X! ]5 J0 G7 a" K4 M | Trigger: Inter-Arrival Time" J" h0 P* D6 Z) B# y
| 0
6 B5 [1 A X, f* ^, V! ~ | /Queue4" h' s X s9 J) `/ S. u# A: e" u: U# a
| Trigger: OnReset
0 R1 {8 ^' C) X8 q& t ~$ F# P) ] | 在0秒的时候各种实体会激发OnReset触发。本例中依次激发了FlexsimModelFloor、Rack2、Source3、Queue4的重置,重置的顺序并不是按照模型逻辑,而是按照实体创建的顺序。在创建模型的时候我们最先拖入的实体是货架,所以货架在发生器和暂存区之前被重置。而在货架之前,flexsim自动创建了ModelFloor实体,所以货架的命名是从2开始的。这一点可以打开树结构验证。* m" ]& M& _- X- P# t0 n
! i6 e% ]8 c$ |; f9 r' Z/ R! ?9 @
在发生器被重置之后,马上触发的“到达时间间隔”触发,这是为了决定什么时间创建第一个临时实体。
& F0 f( _( U" R, t- V在5.303038时刻,发生器创建了第一个临时实体,并由此引发了接下来的一系列事件和触发:
^% e/ L* ?, i# R: G- }0 _# v. r Time8 h2 w. y8 e1 [
| Object- c, g0 @$ c- s
| Event$ h, J8 d4 g- |; o
| Involved
$ m# V8 Y, s" N7 J# h | P1
6 K1 ]: q0 l3 W6 B; ]0 s, M+ q | 5.3030381 f U" A c9 t) x6 w
| /Source3& p# G$ t h$ ]: u5 B
| Engine: Timed Event
- Z" e9 y R2 I | /Source3
! h, ^1 M$ g; | | EVENT_CREATEPART, o2 ~. C) k7 S; {. j
| 5.303038
4 s9 @, i0 _* H9 W | /Source3! I$ \. |1 y- z1 M; h
| Trigger: OnCreation/ V0 ~5 Z2 Y2 u1 f; _+ S/ p! Q
| /Source3/Box6 E& j0 L: D8 ^; \" y* D! G! ^
| rownum: 0.0$ ^) A% a8 [% o0 H3 h$ d" a
| 5.303038
/ r6 u$ M" A7 ^ | /Source36 R+ R# I& I+ I& ~7 d% C( X
| Trigger: Send To Port$ d+ s2 h' \" u/ h
| /Source3/Box
8 ?; W F: k, t+ \! p |
% C" B9 D" i) B9 \5 E! |# X5 i
4 l3 I1 J+ A8 `; n8 d | 5.3030380 o5 t4 F& N v5 ]) l
| /Source31 q& T% D8 B$ _0 z2 B/ S; G
| Engine: Send Object
# t1 m7 h# p2 h# s( X3 q6 j0 z | /Source3/Box; _. t' Z8 L0 l) P' y, W, J5 k; R2 j
|
# Q$ X' J b9 p9 `) O
& j; P' c8 k1 l$ [8 D | 5.303038# f7 x( k! ~9 f; U8 q9 J
| /Source3
: @5 g! V' S0 O' j) j# x | Trigger: Inter-Arrival Time
/ _; }% c f' |+ }; P) P | ' y" ?* H* ]7 C' e( O0 o! d- H5 G
6 x( X/ _& W8 r1 C0 T |
; K, e2 j: Q) t% u% k' t. x; E4 B1 Z) E& G# G) D
| 5.303038! q! Z4 s' ]% ^% T7 V3 A& H* J, ^
| /Source34 R7 k+ V+ o2 o. H& D
| Trigger: OnExit" ?* A8 K: j2 X4 g/ f; e
| /Source3/Box
( L! x& j! a( t1 N! O | port: 1.0
, s+ m8 z. J. d% d | 当临时实体被创建时,首先执行的是定时事件:CREATEPART,然后才激发“创建触发”,临时实体被创建后,还要决定其从哪一个端口发送,然后执行发送,临时实体离开发生器。而在临时实体离开之前,发生器还激发了”到达时间间隔“触发。6 T) i) z3 @7 Z1 B+ J1 X0 V
本例中的每个实体都是以Engine事件开始,要么创建,要么接收。暂存区正是以接收实体事件开始:% ~; w3 v! c0 _: I+ o
Time
0 V% A! w3 P$ ~: G1 _ | Object' Z9 `9 Z3 @9 Y9 X" d
| Event
, y3 }- p3 r1 P t$ u | Involved
( X+ i8 |8 P5 D; g+ v' a | P1
( u3 X' t) L! h9 D5 i | 5.3030387 l; C$ p- J1 Z1 Z: [# p A
| /Queue4& H3 D9 K( Q5 _+ F# w: T
| Engine: Receive Object2 }4 u1 Q7 h j' d$ V1 N! W" c- o+ K
| /Queue4/Box
. \2 S6 @; j8 b7 f# t | ; l4 \9 Z2 G, _1 [% ?
1 q! X# N' V3 r5 v _% m" ^2 r
| 5.303038
! _* ~+ h$ [$ ]" N* L5 j | /Queue4
% `/ w6 r0 q% s/ I9 Z0 e | Trigger: OnEntry
/ N9 r& g. t2 [! n6 m/ d N | /Queue4/Box' b0 E+ o) }7 K( n( N1 l
| port: 1.0
/ A: I8 G8 R* B | 5.303038, U! i+ i4 e! F" K9 @: J/ J/ i
| /Queue4
- p/ f2 F q( b+ d! b, I | Trigger: OnEndCollecting
: c( B, L9 L4 O& x. E, |6 N | /Queue4/Box6 z# K3 c/ n9 `* F
| batchsize: 1.01 I; C2 _( R3 C1 M0 D. U* g, M% u
| 5.303038; O; o. m/ P7 Q6 ?
| /Queue4
* \* r3 }0 e: }/ ]+ v | Trigger: Send To Port
+ J, `2 b$ N+ J+ f0 R | /Queue4/Box
& z. X$ m6 N) E. e( S* N | 0 i2 x! P$ y5 u- P- `
) u9 C2 b7 Q: B G9 ?; p
| 5.3030387 X7 q3 L- z3 n/ m, }. k! ^; v6 J
| /Queue4
8 D. Z. h1 \$ w& Q1 V) i2 _ | Engine: Send Object! a. l: u& C* }, Z
| /Queue4/Box" b+ \) F6 s+ N5 P* V, h' D
|
. b `* C( }. G5 A6 ]4 a( {. N- N6 G4 g
| 5.303038
4 U2 X6 g, L7 q2 J, p/ H# m | /Queue49 |3 d3 H% U; x3 g1 n
| Trigger: OnExit& [/ x r' D2 h* U( y+ V
| /Queue4/Box
) W! I2 z" b9 t$ G9 c1 m# O. ? | port: 1.0
+ E6 m9 J3 b6 V+ K! q: Y; x, F | 接收实体之后激发了进入触发,然后判断批次,获取发送端口,执行发送,最后离开暂存区。
; u: Q! n2 j5 N& |' _- |货架同样以接收临时实体开始:0 W' N: o# S! j& ^3 i
Time' [* ^; E! \- P$ ^3 M" V9 {
| Object
5 n, B- ?: C- x7 o8 ~ | Event
# v2 y! A) ]- H# v4 p/ ? | Involved
& L1 K4 o2 \! L1 S | P1
& Y% O" U' [% a0 Q o | 5.303038
) C1 G; z; `$ V l | /Rack4' m& }: ?4 W3 T+ d
| Engine: Receive Object$ z2 U6 k2 H @# X+ N7 V3 Q2 ]
| /Rack4/Box! ~$ }* D3 j& D- h1 `
| 4 n. f9 q8 V) j6 X
+ P' |$ M0 q+ m: ^9 ]: ^! \" t
| 5.3030381 ]% V, i; S4 T: {% M+ D- \1 b9 C3 \
| /Rack4
+ f8 [8 F0 W; G0 P | Trigger: Place in Bay, Q! w* s+ j% R: h2 k, N3 @
| /Rack4/Box% D/ ?1 I, {( V; X/ D, i
| 6 Z- I8 {$ e( ?: c' d" V: \
+ _4 t7 S+ ]! Z# \" m/ c
| 5.303038
3 @, j7 x9 T( K7 ?* n, g | /Rack43 u- l+ J7 _$ _/ w, w4 z$ x) w' {: Y
| Trigger: Place in Level8 a* c( L% \3 V @
| /Rack4/Box
6 }; J1 b. `. v4 \ | bay: 3.0
/ x) ]/ C s1 |: S2 d! L/ ^+ y | 5.303038
1 r, U7 K; f$ a# c& ` | /Rack4
; ]0 x" j! ^$ D8 z8 `; \ | Trigger: OnEntry. z! M: j* F$ [: t2 x) {
| /Rack4/Box
c4 a( m6 x: j6 F | port: 1.0
9 p' |, m9 E1 N9 M! ` | 5.303038- j" E' J0 M" Q2 S/ ~* c4 N5 B
| /Rack4
0 M1 u% O$ D6 X( ?3 |3 s" b | Trigger: Minimum Dwell Time
9 j# J7 F, C* A | /Rack4/Box0 G- S0 l+ w! n: r6 P) ^
| port: 1.0
5 _9 k" S, j$ P1 `! {8 \$ h& l. a | 5.303038# h% G; F$ r1 m, A/ F+ A- M
| /Rack4. C$ }+ y( O. u5 x4 d
| Engine: Timed Event
$ M9 W8 Y0 T Y& e1 {$ x | /Rack4/Box
+ T9 x A H8 } E2 @0 l5 y | EVENT_PROCESSFINISH
2 D2 @/ Y( t' m: s | 5.303038
' `; s; f8 g8 q4 w | /Rack4
" v8 o$ u+ P u, n; S | Trigger: OnEndDwellTime
1 G6 V ^/ }; j! V6 U. | | /Rack4/Box: |( v+ s* Q0 }& {2 l+ S
| : W' m$ B' t3 {" X) b7 j4 D1 v
4 c' |; C# Y! O. P% a( t
| 5.303038' H6 x8 L- |4 W) D1 [6 W5 c6 b
| /Rack44 s0 r8 b! y& r! q4 z* a
| Trigger: Send To Port
6 d+ Y* L/ }% {2 X3 {* _ | /Rack4/Box, B) ]) g# [. ^3 A) w3 n4 ^
| / {2 Q$ \% @) T( n+ p s$ Y
8 u! E, C! m; {" U! _ | 接收临时实体之后依次判断应该放置在哪一列、哪一层,然后激发进入触发,临时实体进入货架之后需要获取其在货架最短停留时间,由于这里设置的最短停留时间是0,所以随即激发定时事件PROCESSFINISH(如果是停留结束会更合理、更便于理解),再激发“停留时间结束“触发,最后获取发送端口。由于本例中并没有为货架指定下游端口,所以这里没有执行”Send Object“事件,也没有离开触发。 u6 X2 \2 D; C, ?, a
接下来的其他时间节点都是在重复着同样的事件和触发,直到货架被摆满。$ w" C; r7 m+ X$ _1 p* s
通过Event Log工具,我们可以详细的分析每一个实体的工作机制。比如可以分析推式策略、拉式策略的不同,比如可以调用运输工具,添加任务序列,来分析任务的优先级别、先占级别的处理机制等等。
/ v) y( a0 [6 K' K, C: R5 S9 T
- o2 l& V% L2 H! Y0 _$ P) e4 }" o' T" M; J4 }
q9 a) I l% N V6 f# l |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
|