全球FlexSim系统仿真中文论坛

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

作者: zorsite    时间: 2015-9-23 13:53
标题: 分析Flexsim事件及触发机制的方法
本帖最后由 zorsite 于 2015-9-23 16:05 编辑 7 Y( {$ h+ ]+ E1 W7 c5 H

# Z4 J) m6 E! k' m* E
以货架随机摆放临时实体为例学习Flexsim事件及触发机制
' E9 {$ U7 \1 L8 G4 `9 L
很多初学者都对flexsim的事件及触发不太理解,到底先执行什么后执行什么,先触发什么后触发什么?用户手册中也没有相关的说明。如何才能把这件事情弄明白?其实并没有想象中那么难,只要稍稍花一点时间,你就能彻底掌握其中的奥妙。3 @" L2 o5 }9 }* w
接下来我们以货架随机摆放临时实体为例,来看一下在flexsim中,各种事件、触发的发生顺序。
  T+ z; O$ L0 ]- }- o% dflexsim中依次拖入货架、发生器、暂存区,软件会将这三个实体自动命名为Rack2Source3Queue4(请注意这三个实体的拖入顺序)。依次A连接发生器、暂存区、货架。双击打开货架属性,勾选“Floor Storage”,设置最大库存为50,设置列和行随机摆放,每个货位内最大摆放量为1,设置货架为510行。5 L. p8 g: i) |% O) u' l& }
[attach]2799[/attach]      [attach]2800[/attach]   ; Y2 _8 l* U( c) }, s
' [- L4 N2 i( J; w9 T4 v/ Q
重置视图,最终效果图如下所示:4 l) i4 s( x3 q
[attach]2801[/attach]$ c0 [& y1 ~6 ]; j& Y6 `  o
debug菜单中选择EventLog,打开Event Log窗口。
! Y5 w8 ?  L. K[attach]2802[/attach]
  {2 B% j2 J  ~2 ?点击settings按钮,我们可以看到flexsim可以记录的事件类型和事件列表。+ o7 S5 g: l6 R7 V
[attach]2803[/attach]: _: Y' H. @8 Z- p4 ^1 d9 ]
Flexsim把事件分为了四大类:EngineTriggerTaskSequenceBeginTask) ]- f( N& r1 i5 j6 }
[attach]2806[/attach]
9 c" _& P# Q0 Z' F1 B引擎事件包括了创建实体、摧毁实体,打开输入/输出端口,接收实体,发送实体,发送消息,定时事件。
' Q" r' k8 S$ O+ v! e' t. f  k! Y[attach]2807[/attach]
. P; u8 G5 D6 U触发事件就多了,我们在实体属性的触发选项卡中见到各种触发都可以在这里找到,还有属性窗口中的一些设置项也可以视为触发。比如发生器的到达时间间隔,处理器的“预置时间”等,flexsim也将其归类为触发事件。% Z0 Q& o7 n# R# l) O! W0 V
[attach]2808[/attach]. Z2 H. r$ J" ~) C
TaskSequenceBeginTask其实都属于任务事件,flexsim将其细化,分为两类。
3 G- L8 h9 S; K3 A; x, p: @" Y/ o+ B任务序列事件只包括开始任务序列、结束任务序列、接收任务序列。
" y8 L7 I2 j: J[attach]2809[/attach]8 K* X+ i9 i, @5 H: H. e
开始任务事件则是任务序列的具体过程,比如装载、行走,卸载、中断、移动实体等。6 c0 }2 ~5 o1 c* }
[attach]2810[/attach]
+ K+ v: c" F0 o; J7 }4 nEvent Log窗口勾选”EnabelLogging”,运行模型一段时间后,点击”Export”,将事件日志导出保存。也可以自己指定运行的时间段,比如设置Start Time0End Time151 [3 w' \1 M* m) T
打开保存的日志文件,就可以看到flexsim模型在运行过程中各种事件、触发的顺序。
, u. r1 D8 c1 l& n: R, I, a[attach]2804[/attach]1 b5 R: G9 P, ^$ O' \' k
先看一下0时刻模型发生了什么:' s) H/ w7 V1 O, d! b% P
  Time
8 A; F$ b/ [0 o& p! q  
  Object
4 k' i5 S" F2 i+ W* l+ X* ?  
  Event
1 m5 M$ p5 z2 {8 {2 @  
  0
  `% `: x  @7 e8 C5 x/ a9 p. j  
  /FlexsimModelFloor
8 S8 {/ i8 @1 K, o0 R  
  Trigger: OnReset
; o) A! {2 [2 H0 D2 f8 m5 Z. D* Y  
  0, K6 S5 S6 Y: j7 [
  
  /Rack41 b6 ^1 h3 ^3 k. Q
  
  Trigger: OnReset7 K$ }! e+ \5 \8 t, ]% c
  
  0
! Q/ B4 [+ z  y4 Z! E. B8 n- n  
  /Source3. f8 V: W+ ?9 k9 A, h
  
  Trigger: OnReset
+ J! X' j9 }/ Z7 Y6 U! ?  
  07 Y# _( |8 ]/ R" Y
  
  /Source3
6 ?4 z5 N0 Y% L6 U; q2 {  
  Trigger: Inter-Arrival Time2 f( s- ~( h6 t1 `+ ?% e
  
  0' a% Y# |% n" L: Y
  
  /Queue4
6 [0 G- h) C% O$ g6 @$ b4 l) u2 n  
  Trigger: OnReset
. {3 @( {% @7 {! k* K6 o6 E  
0秒的时候各种实体会激发OnReset触发。本例中依次激发了FlexsimModelFloorRack2Source3Queue4的重置,重置的顺序并不是按照模型逻辑,而是按照实体创建的顺序。在创建模型的时候我们最先拖入的实体是货架,所以货架在发生器和暂存区之前被重置。而在货架之前,flexsim自动创建了ModelFloor实体,所以货架的命名是从2开始的。这一点可以打开树结构验证。
8 m. U( O" U8 j" [[attach]2805[/attach]
. ~# M, S+ }  U9 V% D在发生器被重置之后,马上触发的到达时间间隔触发,这是为了决定什么时间创建第一个临时实体。
% r" }6 N! q9 A$ P& _0 H5.303038时刻,发生器创建了第一个临时实体,并由此引发了接下来的一系列事件和触发:$ i( F. v# j" F4 o/ X
  Time$ }/ _8 Q6 S8 M7 W+ |7 C
  
  Object
& t* g! x+ ~! p7 t; |  
  Event
8 k; b/ H$ P# g! Z2 T  
  Involved( ~8 E, N/ ^& a' f
  
  P1
' o+ s2 O1 h; i4 N  
  5.303038& z8 M1 U3 i& F/ T% m* m* J
  
  /Source3
' ?& A9 m1 I! }4 a) Q  
  Engine: Timed Event
! T3 }) j( X' l; a, J  
  /Source3! J5 U: |% f8 g; e! {# ~' u8 ?
  
  EVENT_CREATEPART
: e$ X! x4 }. O+ b! l- L3 b  
  5.303038# z$ {5 I, y0 ~( h( A
  
  /Source3! Z- n5 A9 A. z
  
  Trigger: OnCreation
( b$ i8 i8 r, E$ J7 B, Z' p' k4 B  
  /Source3/Box
8 p( a. Y- \, j) J) |( d6 }6 r; \  
  rownum: 0.0
- c/ c0 z* R7 J3 S; b6 x  
  5.3030387 y% P3 J6 V( ~, q
  
  /Source3
: g0 [+ H( i3 B( j5 e; E; p  
  Trigger: Send To Port3 i8 ~: ]; u0 c" l6 s$ M" h! f
  
  /Source3/Box% k" |3 m' g6 \1 p6 L
  
  
' U. G; A  y4 t* t: \. j# v  \  \: {! T2 c3 |  y1 c6 E% I; ~
  
  5.303038
. `- b% V" c! G  P2 d9 ?& U  
  /Source3
, U  Y: P  X; g3 f5 O8 H' U. [  
  Engine: Send Object
* b% d5 G! w5 D- u  
  /Source3/Box4 N$ Y) p& z8 h' D; k" n8 z( c
  
  
( f# P, X9 s0 Z! n6 Y) l9 j4 P2 z" B9 M
  
  5.303038( q# G/ q) J( X
  
  /Source37 k1 T# L$ X3 ?. ]  f6 t5 p7 A
  
  Trigger: Inter-Arrival Time% l6 @4 c  z. O9 ^) ^
  
  6 ?' e* L! Z! C9 p
, x/ u) f0 ~7 C( h; n* C
  
  
5 u6 s* W; F+ t; m/ [- \- `) M: C: T5 x4 b$ T3 z
  
  5.303038
% @# s9 y% k$ b  
  /Source3; i8 ^& S& c- k, a
  
  Trigger: OnExit% I2 f" b6 U9 Q  D/ z
  
  /Source3/Box/ B% ?3 b  F, j  a! @  u& @( Y
  
  port: 1.03 R3 p8 N) q+ V( a
  
当临时实体被创建时,首先执行的是定时事件:CREATEPART,然后才激发创建触发,临时实体被创建后,还要决定其从哪一个端口发送,然后执行发送,临时实体离开发生器。而在临时实体离开之前,发生器还激发了到达时间间隔触发。# P& v  H9 a8 E3 e
本例中的每个实体都是以Engine事件开始,要么创建,要么接收。暂存区正是以接收实体事件开始:
1 ]% c' f" @5 b7 X/ N1 B: m
Time3 P7 L& c( q9 P
  
  Object8 s5 g- O  D1 D" [
  
  Event" H  q. h+ c, S' E
  
  Involved6 u4 L+ a% E8 z6 k) N
  
  P1
1 N, F3 |5 O0 [  
  5.303038
: p& P+ y& R7 m, t2 L  
  /Queue46 ]8 G: }+ |; i( ^8 O8 N7 r6 F
  
  Engine: Receive Object7 x, @, h  R& u' E+ W. _
  
  /Queue4/Box
8 ]7 w# G! ?7 _+ r& u1 q  
  - r0 g1 I/ D' G6 N6 O- C" K
* D1 `! R0 E, |" Y2 z
  
  5.3030380 N( l/ K7 G" p; Q% a5 O
  
  /Queue4, n% c, T  C0 D/ {( q! F
  
  Trigger: OnEntry. P/ ], P2 M; c- f( c4 {" H$ M/ c
  
  /Queue4/Box
8 }4 k3 N0 [3 D  b  
  port: 1.0
# E; E# N7 d( ?/ @, @3 X  
  5.3030381 @& t5 @1 k) y$ g6 v, L7 Y/ Q
  
  /Queue4
5 n- ~, \& t. Z5 C- ^- O  
  Trigger: OnEndCollecting$ k/ S" z/ V: n0 R& t  ^9 l
  
  /Queue4/Box  n: f5 U9 Z9 B" F( N1 t' C
  
  batchsize: 1.0! Z1 a& _+ c! X0 ^( M! r7 f: ~
  
  5.303038
* Z9 K$ U0 O2 p7 Z  R0 I  
  /Queue4) F: c5 j2 i, B- g( `' X
  
  Trigger: Send To Port" K& j' F: w0 [8 u
  
  /Queue4/Box+ K) l& a4 E9 l! d
  
  : Y1 @; @0 W6 h8 k, U6 v$ x

# s  M; h) `1 Q4 P+ \: ?7 A: V  
  5.303038+ g4 z. b- z) e8 b4 S
  
  /Queue4
# |3 S$ d3 S9 X5 X# X- \  
  Engine: Send Object% p. q5 P6 h' [- J" }, R# A6 z
  
  /Queue4/Box' m1 q( Z. I1 i& x3 F
  
  
' P" d) _% p! b$ l6 ?. B
1 ]2 Z; f6 M: d2 _6 v  
  5.3030387 T$ Y2 j, m1 _% s  @& J! J/ O
  
  /Queue48 T5 w1 f5 i* u1 H' T, K* k3 m$ i
  
  Trigger: OnExit) H9 I: j0 w+ b3 w! P0 d6 Z7 E. y
  
  /Queue4/Box2 E. X% x# c( I
  
  port: 1.07 r( x. v, Z# `3 Y% X
  
接收实体之后激发了进入触发,然后判断批次,获取发送端口,执行发送,最后离开暂存区。
1 Z3 C9 J  g1 ]! d货架同样以接收临时实体开始:. |$ D1 o8 f; _3 l
  Time1 M6 E2 t5 {9 h
  
  Object  d+ g+ S4 T9 p
  
  Event8 l$ W2 f$ Q" N* R& O, ^
  
  Involved& O) ^1 b. R& Y0 i
  
  P1; Y* @1 l. M3 X
  
  5.3030382 I6 k2 ^3 [. T" ~
  
  /Rack4
, G* ^1 Y* e3 [9 l  
  Engine: Receive Object
$ D7 n& q  L6 a) J  
  /Rack4/Box9 j" j. a* @8 F9 P' O' q
  
  
; v" z/ k2 B% g' m6 \) [4 [7 g+ D9 ^  n. o4 U/ O
  
  5.303038! u% M" V- P) H( [8 D  }
  
  /Rack4
' Y7 \- b+ R" o+ y' e/ B) \* f6 o  
  Trigger: Place in Bay, `: }0 E6 q1 `
  
  /Rack4/Box
+ x2 ?" ?  h/ }% j, \  
  
& L9 s6 c* U% `; i% V6 ~4 M
. f5 @6 O9 ^0 X6 Q$ q2 f5 h  
  5.303038, R: G9 q. x& k
  
  /Rack46 a& q+ E3 W; D' X: h
  
  Trigger: Place in Level
& C7 K$ L7 K% }8 b  _4 N  
  /Rack4/Box" @: j( D" j2 W5 h6 o
  
  bay: 3.0* m& X4 n7 a7 J9 @  ]# d
  
  5.3030384 k. }! e+ }: T0 d+ A, m
  
  /Rack4
) b* a! v2 U, Y* Z; z. w  
  Trigger: OnEntry
1 G/ a6 p+ |  s; b: f1 o  
  /Rack4/Box$ I7 F3 @) n5 w" x
  
  port: 1.0
: m4 j" k0 d) d9 B* r6 ?8 {  
  5.303038' O/ K# J0 `* R' t: |
  
  /Rack43 V& v9 q6 L; M3 I& C
  
  Trigger: Minimum Dwell Time2 i0 O. k9 Z7 w' V/ V$ B
  
  /Rack4/Box0 K* p  X& `. A4 @" @7 m
  
  port: 1.00 t4 x( `& @: d( ?/ L
  
  5.303038$ i2 x: i4 T. n0 K/ J
  
  /Rack4
$ {4 m  Y9 ?+ l3 Y& W  
  Engine: Timed Event
: u2 [3 m% }9 @: W$ B) n' T! ~  
  /Rack4/Box) g; k* A& k+ F" W1 D
  
  EVENT_PROCESSFINISH
: H0 {8 f0 R. Y/ v5 D: p8 k/ S1 v  
  5.3030385 L- a# @0 _9 |& m8 y" ?
  
  /Rack4
2 q7 R: A8 S/ j9 Z8 l  
  Trigger: OnEndDwellTime% \+ H# D8 n% V6 ]7 ~: `# p! w
  
  /Rack4/Box
) N% e. M6 ~9 d; X  
  
, b" P3 y7 V- f' B$ ^* |
% P) ]  k, Y7 X% ?' U* L+ c  
  5.303038
# ~2 h: M7 r: A5 h  
  /Rack4
! q" y: @) r4 n0 p4 e. H0 h! m4 E  
  Trigger: Send To Port
$ h1 h+ C5 F* f# }5 z  
  /Rack4/Box
% G' r/ G% |& g9 s& l$ O+ m5 W! P  
  
8 o7 }0 z6 G2 {. E7 G4 `& {- |0 t" g0 B! y
  
接收临时实体之后依次判断应该放置在哪一列、哪一层,然后激发进入触发,临时实体进入货架之后需要获取其在货架最短停留时间,由于这里设置的最短停留时间是0,所以随即激发定时事件PROCESSFINISH(如果是停留结束会更合理、更便于理解),再激发“停留时间结束触发,最后获取发送端口。由于本例中并没有为货架指定下游端口,所以这里没有执行”Send Object“事件,也没有离开触发。
$ m" \, F2 w* n& G接下来的其他时间节点都是在重复着同样的事件和触发,直到货架被摆满。
" x! p! ]% S2 {% E' @通过Event Log工具,我们可以详细的分析每一个实体的工作机制。比如可以分析推式策略、拉式策略的不同,比如可以调用运输工具,添加任务序列,来分析任务的优先级别、先占级别的处理机制等等。: \$ L+ D) |- f5 u2 q& Q/ k
[attach]2811[/attach]
, P  F% j2 {" w9 F5 {9 y$ q

* q' T0 ]$ O% m# Z* I/ L* l( w2 _) b9 p, Z) v' M; u0 r: ^

作者: 1010265352    时间: 2015-9-23 14:04
学习啦
作者: FFFrenk    时间: 2015-9-24 12:04
感谢分享event log的使用方法!讲得很详细!
. V, E6 _3 g7 ]8 J/ W- a1 a: p5 }6 \* Q+ y- V
5 X( X5 s' {: h
文中出现其了一处与我理解不同的地方,我贴上来,一起讨论讨论~5 z( O/ O9 v# B4 s3 A; y4 `3 c
4 ~  s& P& i* Y. v0 T* S8 Q) m* ]' F
“重置的顺序并不是按照模型逻辑,而是按照实体创建的顺序。”) \" U$ @2 E& P  u
并不是实体创建的顺序,flexsim中并没有一个节点存放实体创建的时候(临时实体有)。
, ]  k$ d* @5 `这是因为,先拉到模型中的实体的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
我也说一点:
; g8 b2 C! q0 R7 G/ ?在事件日志中,涉及的实体一般都是box,这样我们很难区分到底是哪一个触发的,如果需要,我们可以对产生的临时实体进行重命名,编号处理,这样就可以知道就哪一个临时实触发了什么。
作者: manaijin    时间: 2016-4-12 11:04
对软件的运行机制学习很重要。
作者: 慧娴亚伦    时间: 2016-4-13 09:32
我也说一点:
7 F' O) C* N) B/ Y- m在事件日志中,涉及的实体一般都是box,这样我们很难区分到底是哪一个触发的,如果需要,我们可以对产生的临时实体进行重命名,编号处理,这样就可以知道就哪一个临时实触发了什么。% y  {3 @: O6 ]) U$ X  d$ \
657776724 发表于 2015-9-26 18:00

. i" ?2 }% Z8 Q2 |) i
5 N2 M$ e# u' I9 F. Y4 X. s# z2 f7 R' 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