全球FlexSim系统仿真中文论坛

标题: 分析Flexsim事件及触发机制的方法 [打印本页]

作者: zorsite    时间: 2015-9-23 13:53
标题: 分析Flexsim事件及触发机制的方法
本帖最后由 zorsite 于 2015-9-23 16:05 编辑
, H! r4 m. I. x; `) d# A  i  v& u
以货架随机摆放临时实体为例学习Flexsim事件及触发机制
- y4 k3 N& g7 @' ?; }
很多初学者都对flexsim的事件及触发不太理解,到底先执行什么后执行什么,先触发什么后触发什么?用户手册中也没有相关的说明。如何才能把这件事情弄明白?其实并没有想象中那么难,只要稍稍花一点时间,你就能彻底掌握其中的奥妙。
+ Y! v! h) N/ i+ X; w9 y. B接下来我们以货架随机摆放临时实体为例,来看一下在flexsim中,各种事件、触发的发生顺序。. [8 c/ D. k3 d9 m: u
flexsim中依次拖入货架、发生器、暂存区,软件会将这三个实体自动命名为Rack2Source3Queue4(请注意这三个实体的拖入顺序)。依次A连接发生器、暂存区、货架。双击打开货架属性,勾选“Floor Storage”,设置最大库存为50,设置列和行随机摆放,每个货位内最大摆放量为1,设置货架为510行。
! O( L4 U! k- g% f; \) T[attach]2799[/attach]      [attach]2800[/attach]   
' R, c; ?8 T8 V7 B" y' P  n0 }
/ e8 N4 P: n1 B重置视图,最终效果图如下所示:2 x9 p( A3 H* l( U* ^3 l0 y
[attach]2801[/attach]
. k/ O* E6 @( @# |* S/ wdebug菜单中选择EventLog,打开Event Log窗口。
7 o) C5 K  ]" A7 f# ~& h% C# m* T4 `+ j[attach]2802[/attach]
% S2 d+ T0 O7 d1 P; m+ e# h点击settings按钮,我们可以看到flexsim可以记录的事件类型和事件列表。
# W) G% N5 n: ^, x[attach]2803[/attach]
/ p6 E/ E7 l0 d7 J. w" Z$ B9 mFlexsim把事件分为了四大类:EngineTriggerTaskSequenceBeginTask9 v* c2 h, s+ j9 S
[attach]2806[/attach]
8 X( c1 {2 N+ v$ E1 E引擎事件包括了创建实体、摧毁实体,打开输入/输出端口,接收实体,发送实体,发送消息,定时事件。
( F( i* y9 r$ ?* U[attach]2807[/attach]
1 S/ x; o; h' |4 ]. V触发事件就多了,我们在实体属性的触发选项卡中见到各种触发都可以在这里找到,还有属性窗口中的一些设置项也可以视为触发。比如发生器的到达时间间隔,处理器的“预置时间”等,flexsim也将其归类为触发事件。1 y, s2 d4 V+ f' b
[attach]2808[/attach]
7 V# Y0 m  Z, ~5 g! \* k; FTaskSequenceBeginTask其实都属于任务事件,flexsim将其细化,分为两类。
  b0 U! v) f0 L; b+ ~; c任务序列事件只包括开始任务序列、结束任务序列、接收任务序列。
  N8 T8 R9 }6 ?! t- w[attach]2809[/attach]$ c+ t) h+ |; w2 y
开始任务事件则是任务序列的具体过程,比如装载、行走,卸载、中断、移动实体等。; F$ m8 F" \+ |! r0 _8 ?
[attach]2810[/attach]6 H5 `, C* v* S6 b
Event Log窗口勾选”EnabelLogging”,运行模型一段时间后,点击”Export”,将事件日志导出保存。也可以自己指定运行的时间段,比如设置Start Time0End Time15
  U$ H6 R3 E/ J/ N, E打开保存的日志文件,就可以看到flexsim模型在运行过程中各种事件、触发的顺序。) M/ o6 f( R' b: {# T1 a2 {. i8 B4 {
[attach]2804[/attach]
. `1 T1 p- E- P# C  j  j先看一下0时刻模型发生了什么:. ?: p7 k/ @- M
  Time
( k: p9 I& [% R/ ]! \, p# v% _  
  Object) t' \0 ^4 ?; R& t: Z7 g! K
  
  Event; L2 Y0 O, Y2 {
  
  0
  a- T: J9 _8 Z; J* n  v  
  /FlexsimModelFloor
1 u1 z* @4 g. V& J/ J: E  
  Trigger: OnReset: R& ]3 A! }7 I% {
  
  01 r3 J, ~8 ]6 I
  
  /Rack4/ a  v7 n: J: L& F9 d4 l
  
  Trigger: OnReset
" P; @, K& `4 P0 ^& f) _6 @  
  0
7 X3 |" {1 p$ ?1 I# \  
  /Source3+ F( q, t" J; u; t
  
  Trigger: OnReset
0 I9 ^% }0 X% J0 [+ C$ ^& ]7 J8 O  
  0; m$ ]1 g) V7 [# G0 b" m
  
  /Source35 C; n& B5 a, Z, j! _
  
  Trigger: Inter-Arrival Time
& _- A8 w/ R& W+ v; _, c3 W4 D  
  0  D1 C! j; ?) ?; I
  
  /Queue4% S2 C  }$ j' c' x; K9 d3 w
  
  Trigger: OnReset8 C# Y  D  y' [- ~7 d1 m
  
0秒的时候各种实体会激发OnReset触发。本例中依次激发了FlexsimModelFloorRack2Source3Queue4的重置,重置的顺序并不是按照模型逻辑,而是按照实体创建的顺序。在创建模型的时候我们最先拖入的实体是货架,所以货架在发生器和暂存区之前被重置。而在货架之前,flexsim自动创建了ModelFloor实体,所以货架的命名是从2开始的。这一点可以打开树结构验证。' \( j" H! q+ d; Z- I) ]& L; i
[attach]2805[/attach]
4 f$ L/ C- {" }在发生器被重置之后,马上触发的到达时间间隔触发,这是为了决定什么时间创建第一个临时实体。
9 p# t: T& `# x; k7 U" [5.303038时刻,发生器创建了第一个临时实体,并由此引发了接下来的一系列事件和触发:% ?+ Q6 C' z$ H# f$ `* |6 x
  Time
; P5 O" s( r2 J, B  
  Object
" r  v5 @, G# }  
  Event
/ U8 p6 i* q5 I7 G* q+ [1 r  
  Involved
$ Z& U% h' H3 b# t* u9 W  T3 x& \0 Q6 U  
  P1
* F2 L# q- n. \. f/ L7 n) ^+ T$ X+ ?  
  5.303038  O' A7 G1 k9 S7 T7 v
  
  /Source3
6 e+ q# ?, ?: F# J3 S* ?, S  
  Engine: Timed Event. a( J9 ~# \4 d  k1 u
  
  /Source3+ w( I' L! a# g6 W% {1 T
  
  EVENT_CREATEPART
. }) J4 z3 D. `2 }. E$ D  
  5.3030383 D% s7 @3 N2 x/ m. d0 V
  
  /Source39 R( n, z' n0 U/ t# y
  
  Trigger: OnCreation
! G; S, c. h! S: j4 F! a  
  /Source3/Box. a& O$ U% |" D9 h
  
  rownum: 0.0+ @. {+ L# s- F1 S9 C
  
  5.303038
+ i0 h) Q5 K" y1 X9 p  
  /Source3
( `- u) o" q+ q  
  Trigger: Send To Port! J: K1 v+ _/ R; h) g; ?1 x
  
  /Source3/Box8 T9 k) L3 ]3 a3 m' L) a* m1 w
  
  - v" Z7 V  j* M8 I* u8 m" N" }
2 d8 U, E+ y$ R
  
  5.303038
, z0 i4 x0 C$ x% {  
  /Source3& R0 ^$ N5 O, W- q; b; z( C
  
  Engine: Send Object# ~4 ^9 n$ X: a! s
  
  /Source3/Box8 ^7 ~6 L5 F$ M/ u/ b, i
  
  0 `5 p, C' Y8 ^! ?' d- N

- V; O& |# L! M" \! {9 q' }  
  5.3030380 b* [& S1 K- j7 G) g$ I6 s6 n
  
  /Source3
2 m( f2 _$ F; x  u& n5 f  
  Trigger: Inter-Arrival Time
7 a4 S5 a& U! `$ z  
  
  o2 u4 ]( N; {& a% R- C4 A% ~
# o" V; J6 _# n$ j  
  
" _1 C9 g0 W# ~; Y0 c" o4 ?6 ^
- r7 s* @- V3 x2 t  
  5.303038# X* H+ d8 n0 t0 K1 G1 g5 v
  
  /Source3
  z+ w) J7 B, n( b( _. D  
  Trigger: OnExit. E1 x0 i. C: G$ j
  
  /Source3/Box: D1 x; \3 s( V. r9 K; k* u2 J7 \
  
  port: 1.03 V1 J+ z/ |5 W; A- d
  
当临时实体被创建时,首先执行的是定时事件:CREATEPART,然后才激发创建触发,临时实体被创建后,还要决定其从哪一个端口发送,然后执行发送,临时实体离开发生器。而在临时实体离开之前,发生器还激发了到达时间间隔触发。
- ?1 `  z6 i( S5 D: m$ t本例中的每个实体都是以Engine事件开始,要么创建,要么接收。暂存区正是以接收实体事件开始:8 L$ @) G, P! b6 m5 H1 q2 \
Time
" K% D0 \8 D( e7 e  
  Object% D, O9 g2 ^) A3 q
  
  Event
* y" N% J1 p# W  
  Involved
! K5 r' R% C  f% A: L: T  
  P1
, u) G: y# V. j  
  5.303038
6 Q* a# G- h* s( Y, x  
  /Queue4# V% O3 r5 v. ~  A. N! Q. k+ N3 l- b
  
  Engine: Receive Object
, ^8 q9 p0 l+ m4 b6 n5 V  
  /Queue4/Box+ g# i: A) B: E  e% ?4 O
  
  ! T' E0 L9 H, t* E. I0 E5 B9 w

/ ]6 C. k$ S& q" A- A  
  5.303038
3 t% V5 r6 C. a' o' B  
  /Queue4
( q0 x: D9 G  @  
  Trigger: OnEntry
) j! O( ?# A5 s0 k0 b. K  
  /Queue4/Box
! ]" N& Y9 @- c  
  port: 1.0* k3 u- t2 c5 y1 [* i
  
  5.303038# R* g: T1 L, j
  
  /Queue4
( R( I+ R) U& @4 N( q- ?! Z* J" z3 \  
  Trigger: OnEndCollecting
. g; v; N5 M( A: `  
  /Queue4/Box# c- g; c' h& a
  
  batchsize: 1.0
' C1 l5 C9 O# R& U1 Q4 w0 G  
  5.303038% m' K- j- ]  c- m2 d" c
  
  /Queue4
6 x; i0 }. G$ f  Q: |  
  Trigger: Send To Port$ Z8 e8 i+ M* y: G# L9 G" o
  
  /Queue4/Box" V* a$ Q& T( |! {
  
  
" c$ o0 Q: [5 M3 ^
6 [% l5 p/ K; ~% b$ n' b  
  5.303038
5 T( H0 }! h. J7 u1 F# w  
  /Queue4
  I0 ?6 A2 [6 N% }9 F  
  Engine: Send Object: T; l8 [1 @6 S, c/ i+ ^/ O  r
  
  /Queue4/Box
$ a5 D9 d9 @. f* K  
  
' V: N9 U# {/ H0 H+ w  d& G+ E! ]6 ~3 E' Y: o) f3 P
  
  5.3030385 ^/ I% e  A* X# x0 i7 x
  
  /Queue4
( o( m: W1 a. Q5 j3 C' h7 a: |  
  Trigger: OnExit& }$ ~3 `+ c3 t* Q1 K' I
  
  /Queue4/Box
' B  {' `  ^4 ^& B$ T  
  port: 1.0" R% a/ V6 r' p- e; _! g# {. P
  
接收实体之后激发了进入触发,然后判断批次,获取发送端口,执行发送,最后离开暂存区。
5 ?- O; U% e. V* v* u货架同样以接收临时实体开始:4 q/ R" C/ j* l, l/ a! ^
  Time
- v% e' E& B/ r3 s  U! ?  
  Object. E6 |6 E- j8 n) G6 g
  
  Event& _9 S4 s9 O  @! O' Q  ?
  
  Involved1 ]' s3 W/ p: \/ ~6 n1 i
  
  P18 f7 S, k6 c( s/ L
  
  5.3030389 s5 C0 G8 J* h( U" T, y
  
  /Rack4& ]" p- r, f! h0 x
  
  Engine: Receive Object
  E7 z# x& n5 v  
  /Rack4/Box- n3 N+ ^8 V( f' L1 h) F$ Y' u
  
  " p5 C1 J, s6 O/ K) Z: q% _0 C
* o$ J2 b7 k6 ^# L, i4 A6 o  C
  
  5.303038
4 ~1 |: M1 w8 `' d/ L$ [  s  
  /Rack4
% M; P2 X6 h# n! H* E) @% H% L8 Y  
  Trigger: Place in Bay7 D' [7 u' E# J* N
  
  /Rack4/Box# E: i- I: m0 N# Q
  
  + r' D$ g2 q6 I4 @8 H: f' {
# c/ b4 U9 x- F# f$ \
  
  5.3030386 C" c& w6 [6 e0 v4 }: p. J
  
  /Rack4; k2 _3 K* V- }  D
  
  Trigger: Place in Level
- L  G' c0 B9 H7 a3 D5 c1 [& b+ t: \+ f  
  /Rack4/Box: H( a* u. S3 J
  
  bay: 3.0+ q) M$ i% N1 P. E, s8 A. F
  
  5.303038
8 {7 ], w0 B/ m1 V3 l  
  /Rack4& i5 a" d" [; }* o% Z2 p. ]5 {
  
  Trigger: OnEntry2 H! U* a' X% [% u. {
  
  /Rack4/Box4 Y* M3 l/ c- Z
  
  port: 1.0
' a. U9 g) s5 v8 H$ z  
  5.303038
: K3 z7 {9 X. o* x' F( X2 D  
  /Rack4; `( `% O& K7 x1 S
  
  Trigger: Minimum Dwell Time
  W" j5 k! z3 \/ O; A% ]% K% a  
  /Rack4/Box) L# J, U' j3 {% |
  
  port: 1.0
3 d3 o9 K! g, I  
  5.303038. n. v: `4 o8 e  C2 S
  
  /Rack4
! }9 n& M& m  `- K' E/ `  
  Engine: Timed Event" r! ?8 m5 W7 P# N) I* I
  
  /Rack4/Box
7 s7 Z: Y/ }$ j+ w  
  EVENT_PROCESSFINISH
9 i6 C% g2 ~% y1 s- \* m1 `  
  5.303038: L- N8 q5 j$ W
  
  /Rack4
2 a8 _/ ?+ G+ Y( ]% T6 l  
  Trigger: OnEndDwellTime4 p2 r* S% V. L8 J% E3 v
  
  /Rack4/Box  D8 R4 v- n6 g9 o7 U
  
  
0 g; C6 t  U  l, V- ]$ H# X' p5 [
/ |* A5 [$ U6 G0 l' E  
  5.303038
3 G- P0 [) t; n6 ~9 a) d  
  /Rack4) `9 Z6 Z9 }1 w! H
  
  Trigger: Send To Port- g9 t! m1 V3 y* \$ g
  
  /Rack4/Box5 R( I0 Q' b3 w' w+ F: V. p* l
  
  ) {, X' R- F* r( U+ z) X

+ R7 @- H% t, x/ B  
接收临时实体之后依次判断应该放置在哪一列、哪一层,然后激发进入触发,临时实体进入货架之后需要获取其在货架最短停留时间,由于这里设置的最短停留时间是0,所以随即激发定时事件PROCESSFINISH(如果是停留结束会更合理、更便于理解),再激发“停留时间结束触发,最后获取发送端口。由于本例中并没有为货架指定下游端口,所以这里没有执行”Send Object“事件,也没有离开触发。3 g& L& d% F2 u* Y  @- v
接下来的其他时间节点都是在重复着同样的事件和触发,直到货架被摆满。
! S0 e; u2 ~# H) ?" N9 ^通过Event Log工具,我们可以详细的分析每一个实体的工作机制。比如可以分析推式策略、拉式策略的不同,比如可以调用运输工具,添加任务序列,来分析任务的优先级别、先占级别的处理机制等等。$ m1 _" S7 I3 [1 f. Y. \; m
[attach]2811[/attach]
/ b7 A0 z: T* H. P( l) O

9 T+ G4 j9 W2 z" J' f2 J- W' @& o5 Z" {# D

作者: 1010265352    时间: 2015-9-23 14:04
学习啦
作者: FFFrenk    时间: 2015-9-24 12:04
感谢分享event log的使用方法!讲得很详细!
- o6 c8 g3 o6 Q, L4 v& l
; z7 d  M; f9 K# Z0 n
* a6 \1 `* z/ H- w5 u+ I文中出现其了一处与我理解不同的地方,我贴上来,一起讨论讨论~# j# a! i- q. R' T9 R! c+ d, I

" J3 E( G2 p1 y- Q" o“重置的顺序并不是按照模型逻辑,而是按照实体创建的顺序。”
) i6 Z8 _) G1 @并不是实体创建的顺序,flexsim中并没有一个节点存放实体创建的时候(临时实体有)。
4 J0 P9 h- F; q) J# G这是因为,先拉到模型中的实体的rank靠前。但是,rank是可以修改的,后拉进来的实体的rank可以调整到靠前,on reset触发就更加靠前咯。也就是是实现了“后进来的实体先触发重置触发”。
作者: 慧娴亚伦    时间: 2015-9-24 21:03
非常好的学习材料!感谢分享!事件日志帮助我们更好地理解flexsim的运作机制,也能够帮助我们更快找到模型建立过程中遇到问题的解决办法。
作者: shiningcz    时间: 2015-9-25 10:49
感谢,以前自己看得一头雾水,现在明白多了
作者: shiningcz    时间: 2015-9-25 10:53
另外请教一下“拉入”策略时,上下游实体的触发顺序,“拉入”成功与否,触发器执行的次序是什么样的
作者: 慧娴亚伦    时间: 2015-9-25 15:27
您可以按照加老师的方法,用eventlog来实验一下,实验出真知。
作者: 657776724    时间: 2015-9-26 18:00
我也说一点:
* G6 C: X3 n8 v0 }! ?5 R' e5 y( e! r在事件日志中,涉及的实体一般都是box,这样我们很难区分到底是哪一个触发的,如果需要,我们可以对产生的临时实体进行重命名,编号处理,这样就可以知道就哪一个临时实触发了什么。
作者: manaijin    时间: 2016-4-12 11:04
对软件的运行机制学习很重要。
作者: 慧娴亚伦    时间: 2016-4-13 09:32
我也说一点:
6 }7 v) {* C6 a( ~6 X) g在事件日志中,涉及的实体一般都是box,这样我们很难区分到底是哪一个触发的,如果需要,我们可以对产生的临时实体进行重命名,编号处理,这样就可以知道就哪一个临时实触发了什么。  k/ \7 z+ Z3 z' \7 E; h
657776724 发表于 2015-9-26 18:00

$ O2 B# Z+ w1 \6 Y; q" [  b- V" L5 A  _% n, H
一个好消息:最新的2016版本已经自动区分在不同实体上面不同rank的实体了,这样就使得debug的过程更加简单方便快速~
作者: 木土    时间: 2016-5-16 21:23
学习了 谢谢
作者: 4a415007    时间: 2016-5-23 15:51
感謝
作者: gree    时间: 2016-6-1 15:52
赞,借鉴学习了
作者: lulu-luka    时间: 2017-4-11 06:16
mark~先把Flexsim的运行机制搞清楚~磨刀不误砍柴工
作者: liuzhifan    时间: 2017-4-11 09:25
点赞,好好学习
作者: wuy    时间: 2025-4-21 15:38
感谢




欢迎光临 全球FlexSim系统仿真中文论坛 (http://www.flexsimasia.com/) Powered by Discuz! X3.3