|
本帖最后由 zorsite 于 2015-9-23 16:05 编辑 2 I2 _% q/ B& ]( C( B* g
" t6 D, B, J' w$ C3 F; F+ k$ I以货架随机摆放临时实体为例学习Flexsim事件及触发机制
: U: F8 z" u5 w6 p) X很多初学者都对flexsim的事件及触发不太理解,到底先执行什么后执行什么,先触发什么后触发什么?用户手册中也没有相关的说明。如何才能把这件事情弄明白?其实并没有想象中那么难,只要稍稍花一点时间,你就能彻底掌握其中的奥妙。% K% k: Z1 x$ {: `5 c- C( \+ D
接下来我们以货架随机摆放临时实体为例,来看一下在flexsim中,各种事件、触发的发生顺序。
/ f5 z& l4 d4 E" E) ]5 v在flexsim中依次拖入货架、发生器、暂存区,软件会将这三个实体自动命名为Rack2、Source3、Queue4(请注意这三个实体的拖入顺序)。依次A连接发生器、暂存区、货架。双击打开货架属性,勾选“Floor Storage”,设置最大库存为50,设置列和行随机摆放,每个货位内最大摆放量为1,设置货架为5列10行。8 U! v$ U/ G3 _, F
( j- T' f5 O& l* c- L+ K. G2 b# V
7 d# }3 q1 _* e ^( e重置视图,最终效果图如下所示:
3 M# Q y( l: d0 m- P1 q" n. ~9 j3 t% v6 \1 q/ d
在debug菜单中选择EventLog,打开Event Log窗口。
9 [7 G+ i9 M) H- P! x1 R! w
8 F# R; v/ _& j" I& G$ z% ~0 {点击settings按钮,我们可以看到flexsim可以记录的事件类型和事件列表。
% B. K- Z6 S8 M8 t
& |5 ^( _5 {6 i: F: uFlexsim把事件分为了四大类:Engine、Trigger、TaskSequence、BeginTask。, G& M4 o3 y4 @; E2 N* d
1 H/ h- S; k' |; }
引擎事件包括了创建实体、摧毁实体,打开输入/输出端口,接收实体,发送实体,发送消息,定时事件。! N) A) x k W- C$ [8 y; u$ c1 k/ P
$ S' I( o8 @$ g, I1 h% h触发事件就多了,我们在实体属性的触发选项卡中见到各种触发都可以在这里找到,还有属性窗口中的一些设置项也可以视为触发。比如发生器的“到达时间间隔”,处理器的“预置时间”等,flexsim也将其归类为触发事件。
7 C w% j1 m- q( A/ ?) ^) g5 `$ X- v; {/ V: }
TaskSequence和BeginTask其实都属于任务事件,flexsim将其细化,分为两类。0 i. j9 l0 l y
任务序列事件只包括开始任务序列、结束任务序列、接收任务序列。
* T6 l2 r* B3 m7 |1 x0 P) x) E" g/ @0 z4 r6 Z( l
开始任务事件则是任务序列的具体过程,比如装载、行走,卸载、中断、移动实体等。
$ M: u. Z7 {- \' z& c; d/ d9 j- I3 |: T
在Event Log窗口勾选”EnabelLogging”,运行模型一段时间后,点击”Export”,将事件日志导出保存。也可以自己指定运行的时间段,比如设置Start Time为0,End Time为15。
0 u4 _& M, q) D" p打开保存的日志文件,就可以看到flexsim模型在运行过程中各种事件、触发的顺序。1 M" V+ g) u' h9 [0 q7 {$ [
" T$ n0 H9 E" L" F; h0 z先看一下0时刻模型发生了什么:) l) c" T4 H1 R" }
Time% B7 N5 r$ w- ^$ z
| Object$ n @1 o: L( E8 s- D# J8 L
| Event: i. c& t K4 Q# f9 n
| 0
% W/ ?( l# X9 w/ W6 n | /FlexsimModelFloor
( ]5 Z/ N, X. e0 ^9 ~: K% g | Trigger: OnReset2 x. w) b* a4 R; z8 k) j( J/ Q
| 03 S3 S n5 Y3 c9 T
| /Rack46 v$ s) m2 i' G4 y
| Trigger: OnReset
) w3 p. o9 O7 P0 {$ @ | 0
% C3 S' X3 A7 W! {; ^9 t! c | /Source3) Q1 q& Z8 j/ d6 M2 D
| Trigger: OnReset
, ^% n9 P8 \9 G4 l& w- O | 09 j/ ~6 X( w$ b6 q. M. x
| /Source3
9 s+ n% k% z) g6 D | Trigger: Inter-Arrival Time; z. V( g2 b+ B5 n' S" @! \0 _( F
| 0
& j5 Y7 _, g2 @' e6 C | /Queue4
: ^$ a% `- a) R4 `/ w | Trigger: OnReset
% E, X# O! f4 ~8 p( G" I. v) C | 在0秒的时候各种实体会激发OnReset触发。本例中依次激发了FlexsimModelFloor、Rack2、Source3、Queue4的重置,重置的顺序并不是按照模型逻辑,而是按照实体创建的顺序。在创建模型的时候我们最先拖入的实体是货架,所以货架在发生器和暂存区之前被重置。而在货架之前,flexsim自动创建了ModelFloor实体,所以货架的命名是从2开始的。这一点可以打开树结构验证。7 t G0 C; v5 }6 j: h G- r
0 h6 E3 J3 C8 k' W9 r
在发生器被重置之后,马上触发的“到达时间间隔”触发,这是为了决定什么时间创建第一个临时实体。/ q4 O+ V+ ~; B3 N( W' Y w2 K
在5.303038时刻,发生器创建了第一个临时实体,并由此引发了接下来的一系列事件和触发:
% G' @ i' \! J$ }# q; Q* R Time9 C% J- d2 j6 G6 P3 ~3 n0 @7 P+ l, d
| Object) Q3 w% y9 r, a. S, F
| Event
C' i3 Y; O2 I) P | Involved
/ k* l( H" e$ a6 A& z$ \ | P1
; f; r, t) y# R | 5.303038
% S& l8 Z5 l3 e | /Source3
7 B/ O/ @5 p5 a" U8 H$ G6 l( ?+ y | Engine: Timed Event/ }3 ~% b$ y" D1 A" q3 R
| /Source35 ~1 q8 \! B; Y
| EVENT_CREATEPART: m* r8 ?0 W6 z8 _0 ~. Q j
| 5.303038
. `# L' a" [4 R! Z3 e- a* O; [! \1 w | /Source3
) f3 P( U; ], _ K) B/ O | Trigger: OnCreation
; t$ Q; O; s6 M% v2 {5 t! K6 s | /Source3/Box
& [" E7 W% E. b9 n | rownum: 0.0
# |6 ^, Q3 M( ^5 ] | 5.303038/ y( Y. H8 @& Y0 g2 G
| /Source3
, x3 @/ @0 j- U5 q, O* T | Trigger: Send To Port
+ M! Y' a& p0 k/ l! }3 N; @ | /Source3/Box
# C4 ?! j1 r! ^4 Z+ ?4 W& N |
3 d9 }- n: _/ m2 e' T7 ]8 I- i/ f/ T1 t8 y j8 O, Z
| 5.303038! k/ h- c8 d+ ^% w5 |5 b
| /Source3' u; f Q0 }! E$ K% M! P' _
| Engine: Send Object
( |! ~4 g7 e5 s# P# N9 S | /Source3/Box
3 y/ Q# X) C4 n: ]; P" }% P' _+ P1 I | ( W' p; U( [9 p/ y9 V
' V8 b6 G" W) e c+ z9 X
| 5.303038
' q7 @5 n; Z( ^( d) S | /Source3
! x$ i2 |' \/ U; a | Trigger: Inter-Arrival Time* {; \2 h; B7 v f7 k' Y% [! x
|
8 Q2 ^! P& {/ `' M6 _
2 o: I& N- m8 o( Q2 N8 H" W | Z3 r1 I' b5 o
; y( x" \8 ^ S: O4 [8 r! ^: w8 B
| 5.303038
% g5 [: G k' {$ g | /Source3
% @; G3 {3 e* } w/ Q2 x | Trigger: OnExit
' ^" ~* P1 k3 L1 F- t | /Source3/Box
3 L8 E7 G" q0 Y5 y, j, L | port: 1.01 E$ M6 U0 H% v7 Z: p4 Q
| 当临时实体被创建时,首先执行的是定时事件:CREATEPART,然后才激发“创建触发”,临时实体被创建后,还要决定其从哪一个端口发送,然后执行发送,临时实体离开发生器。而在临时实体离开之前,发生器还激发了”到达时间间隔“触发。
( t1 i1 H! K8 h- g- O; B# M2 _本例中的每个实体都是以Engine事件开始,要么创建,要么接收。暂存区正是以接收实体事件开始:
6 ^8 d1 ]' X7 i8 N+ \# v" q) x Time4 {& w0 g6 z- [6 ^
| Object
5 E6 n# F6 L! \! x7 [' P | Event
: L1 N' q5 H* n$ u9 @7 N$ C6 ? | Involved/ ]9 b8 B7 S) n w
| P1
& H; B3 Z4 k* C9 O! {# Y3 o1 W5 b | 5.303038; B9 |- w' l" M
| /Queue4/ ], N5 F! e- u3 W
| Engine: Receive Object
5 ^1 N# i1 ?/ H% \* q- E! h | /Queue4/Box
0 N Y7 f9 t$ } | 4 d( Z; e# g4 l
5 g' W# J) K) q' {8 l
| 5.303038- j! j, E/ G0 V& i
| /Queue4
* \* n; p5 X/ G% g' v | Trigger: OnEntry i! P* ^) M- I. W# X
| /Queue4/Box
7 ?" s, f- g+ G" M, a( ~! L7 c | port: 1.0* \0 G3 q( E/ t0 Q6 ~
| 5.303038( U- r8 {. m% W! D1 J4 c7 _
| /Queue4
' K+ L" B! }' g$ u | Trigger: OnEndCollecting# r: b8 e8 Y Y8 m3 N4 c
| /Queue4/Box0 Y$ e' K1 f$ D. m, b p# s# P
| batchsize: 1.0
; q! ^ t/ U+ e+ C6 N | 5.303038
. ^& E6 E" Q; ?" v | /Queue4% z& M. M# i4 o, t5 o+ w
| Trigger: Send To Port
/ d/ D: E$ R/ z- O/ Z2 } | /Queue4/Box
! W0 t: K/ l& `5 q8 G5 C. ~ | . B: L$ X5 ?, f A% u3 @2 D
; h9 c7 Y, U8 r. R9 _
| 5.303038. X* _! @, q5 f
| /Queue4" O2 g# t: g; ~. ~" c
| Engine: Send Object
; k: a4 D4 S" x( O' f1 D | /Queue4/Box
+ i' A, a/ m$ u# G |
; z& V0 T9 f4 X/ ], ^; ], d
* Q4 @% \8 z- L& @# M+ Y1 ~ O: l/ j | 5.303038, d+ v% x: Y$ ^1 r9 e
| /Queue4
7 U7 e4 a, u2 b5 e+ U | Trigger: OnExit
" u# z7 A, p1 b9 p: e1 m | /Queue4/Box
5 `+ B' F7 O% Q0 C& F | port: 1.0- }2 W% [: W% j" T
| 接收实体之后激发了进入触发,然后判断批次,获取发送端口,执行发送,最后离开暂存区。
8 _% b. M5 X$ h( k货架同样以接收临时实体开始:
% {4 `' g# O5 y" x; R6 X6 C+ F Time
7 K1 n; m; [0 Q& Q | Object' O+ p: l7 Z' o4 d, b( G y6 H+ h
| Event
$ f% J- R' S2 A1 T4 k% C4 R | Involved
! i0 E; I) R: Y- f7 h | P1- _7 b' Q* t( e: N
| 5.303038
% s6 c- u8 H0 z+ Z8 X& {4 R | /Rack4* d) @' D& }! C$ j" q* z3 F
| Engine: Receive Object. |9 C* O2 Z4 `( ]
| /Rack4/Box
1 i9 |- u; j% F0 n |
) O5 ]+ B8 m% Q+ r& q0 ^
6 h* u! c q$ y | 5.303038
8 {% ~: { ]- ^. L) t6 N% ~1 v: v | /Rack4
1 A4 K3 m6 @. b1 ?7 u | Trigger: Place in Bay
8 Z) t5 _, N9 g% |. Y0 l, |3 P6 e | /Rack4/Box
- ^# I) p- M! Q0 ^% D7 _ | * a5 T1 [8 s+ |1 X) e
/ ~. i4 l+ c7 Z8 {
| 5.303038
3 D& I+ n2 K) L( V- c: M' r | /Rack40 y) a% {1 H, J7 U7 y I
| Trigger: Place in Level$ Z7 }$ N4 S' P. o; {& o
| /Rack4/Box) y% k* i6 y- T7 D0 l& m+ m
| bay: 3.0( ?. O4 N' S. E7 z+ z& Z h
| 5.303038
3 ^, S$ U) x6 ^9 t | /Rack4
1 N# `5 T/ u! A }( A3 L | Trigger: OnEntry
! v! L$ |4 m$ t+ U, g | /Rack4/Box, N& k, O' P0 o0 O, k% Q
| port: 1.0
( j/ h5 Q8 @2 t Z- Y) f | 5.303038
; N i+ S! {3 b' w6 @- N# m | /Rack47 j7 u4 X6 n( k8 e7 A
| Trigger: Minimum Dwell Time
* i- v( U# h# W | /Rack4/Box
" H# i \6 q7 u | port: 1.01 k. I h! d7 z
| 5.303038' F. Z8 |" L. C6 t. c; t* r
| /Rack4
2 F7 z" E& S( U( R6 c; ]$ J | Engine: Timed Event2 W& T; f7 B. B- Z8 g$ T. H% I+ i
| /Rack4/Box
; M" O _: c8 _ s& a' K' O9 R | EVENT_PROCESSFINISH
2 w4 q4 x: }$ ` Z+ b& c- C8 x | 5.303038* K8 ]2 T2 b6 i1 A8 B! W
| /Rack4
7 p: T% E6 P4 s6 a! `/ o+ V( h | Trigger: OnEndDwellTime6 t1 [6 b9 {. E' u2 K# l/ L
| /Rack4/Box$ H- j4 Q+ [$ }$ p2 o) m9 ]' {, P6 ]5 i
|
/ e' H; d, o! X% }0 ~# l0 i r" G5 |" L3 m, {
| 5.303038) c+ m# r; d7 k
| /Rack4
7 r; v3 a' \( D | Trigger: Send To Port
2 e+ W% n! B. W | /Rack4/Box
! s+ J/ M: a, V1 G! U) a. q |
. ]* B0 l4 }' U
; s* s( i) p6 q% l) \ | 接收临时实体之后依次判断应该放置在哪一列、哪一层,然后激发进入触发,临时实体进入货架之后需要获取其在货架最短停留时间,由于这里设置的最短停留时间是0,所以随即激发定时事件PROCESSFINISH(如果是停留结束会更合理、更便于理解),再激发“停留时间结束“触发,最后获取发送端口。由于本例中并没有为货架指定下游端口,所以这里没有执行”Send Object“事件,也没有离开触发。! T2 Y. k3 i) T$ o }( ^% @) s) Y9 V
接下来的其他时间节点都是在重复着同样的事件和触发,直到货架被摆满。/ r1 [9 k7 e: c; r1 o
通过Event Log工具,我们可以详细的分析每一个实体的工作机制。比如可以分析推式策略、拉式策略的不同,比如可以调用运输工具,添加任务序列,来分析任务的优先级别、先占级别的处理机制等等。
4 P# q% S$ ^/ K4 U/ a$ `# [2 D6 H" e" F4 t, {5 D0 H
- J0 R5 _' R) n' x* `$ \; I( \% f) W, b' Z
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
|