全球FlexSim系统仿真中文论坛

搜索
查看: 19144|回复: 15
打印 上一主题 下一主题

分析Flexsim事件及触发机制的方法

[复制链接]
跳转到指定楼层
1#
zorsite 发表于 2015-9-23 13:53:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 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中依次拖入货架、发生器、暂存区,软件会将这三个实体自动命名为Rack2Source3Queue4(请注意这三个实体的拖入顺序)。依次A连接发生器、暂存区、货架。双击打开货架属性,勾选“Floor Storage”,设置最大库存为50,设置列和行随机摆放,每个货位内最大摆放量为1,设置货架为510行。
% 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把事件分为了四大类:EngineTriggerTaskSequenceBeginTask
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
TaskSequenceBeginTask其实都属于任务事件,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, \+ sEvent Log窗口勾选”EnabelLogging”,运行模型一段时间后,点击”Export”,将事件日志导出保存。也可以自己指定运行的时间段,比如设置Start Time0End Time15
: [) 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触发。本例中依次激发了FlexsimModelFloorRack2Source3Queue4的重置,重置的顺序并不是按照模型逻辑,而是按照实体创建的顺序。在创建模型的时候我们最先拖入的实体是货架,所以货架在发生器和暂存区之前被重置。而在货架之前,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
2#
1010265352 发表于 2015-9-23 14:04:53 | 只看该作者
学习啦
3#
FFFrenk 发表于 2015-9-24 12:04:12 | 只看该作者
感谢分享event log的使用方法!讲得很详细!
4 k1 S. o! `' R, u% a" x3 _! p5 n: @0 D" v" `: \

: V% ?" s2 v7 {! C文中出现其了一处与我理解不同的地方,我贴上来,一起讨论讨论~
) y) q3 m6 b% t# i, m" u! i  C1 k1 `% k
“重置的顺序并不是按照模型逻辑,而是按照实体创建的顺序。”
; W7 X. I" p& o+ J1 h并不是实体创建的顺序,flexsim中并没有一个节点存放实体创建的时候(临时实体有)。
; V2 A' ]& Q+ [4 M& U这是因为,先拉到模型中的实体的rank靠前。但是,rank是可以修改的,后拉进来的实体的rank可以调整到靠前,on reset触发就更加靠前咯。也就是是实现了“后进来的实体先触发重置触发”。
4#
慧娴亚伦 发表于 2015-9-24 21:03:39 | 只看该作者
非常好的学习材料!感谢分享!事件日志帮助我们更好地理解flexsim的运作机制,也能够帮助我们更快找到模型建立过程中遇到问题的解决办法。
5#
shiningcz 发表于 2015-9-25 10:49:13 | 只看该作者
感谢,以前自己看得一头雾水,现在明白多了
6#
shiningcz 发表于 2015-9-25 10:53:54 | 只看该作者
另外请教一下“拉入”策略时,上下游实体的触发顺序,“拉入”成功与否,触发器执行的次序是什么样的
7#
慧娴亚伦 发表于 2015-9-25 15:27:41 | 只看该作者
您可以按照加老师的方法,用eventlog来实验一下,实验出真知。
8#
657776724 发表于 2015-9-26 18:00:20 | 只看该作者
我也说一点:( M6 E+ C  Y/ O& k1 `1 g
在事件日志中,涉及的实体一般都是box,这样我们很难区分到底是哪一个触发的,如果需要,我们可以对产生的临时实体进行重命名,编号处理,这样就可以知道就哪一个临时实触发了什么。
9#
manaijin 发表于 2016-4-12 11:04:30 | 只看该作者
对软件的运行机制学习很重要。
10#
慧娴亚伦 发表于 2016-4-13 09:32:49 | 只看该作者
我也说一点:$ U9 ], t9 P& g
在事件日志中,涉及的实体一般都是box,这样我们很难区分到底是哪一个触发的,如果需要,我们可以对产生的临时实体进行重命名,编号处理,这样就可以知道就哪一个临时实触发了什么。5 T0 B0 l1 B) k( G# z1 L0 ?
657776724 发表于 2015-9-26 18:00

5 A1 b) }/ R$ I' d( y  E% e9 {" ^1 S( d
一个好消息:最新的2016版本已经自动区分在不同实体上面不同rank的实体了,这样就使得debug的过程更加简单方便快速~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|手机版|Archiver|全球FlexSim系统仿真中文论坛 ( 京ICP备14043114号-2 )

GMT+8, 2025-8-30 20:05 , Processed in 0.075679 second(s), 14 queries .

Powered by Discuz! X3.3© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表