全球FlexSim系统仿真中文论坛

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

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

[复制链接]
跳转到指定楼层
1#
zorsite 发表于 2015-9-23 13:53:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 zorsite 于 2015-9-23 16:05 编辑 & i5 o: w9 j6 V; e' K8 V: i7 ?
* T& N/ e7 m4 {- i7 Y1 @: Y& T
以货架随机摆放临时实体为例学习Flexsim事件及触发机制

% U: Z9 O4 B9 U/ A" E7 v8 ^很多初学者都对flexsim的事件及触发不太理解,到底先执行什么后执行什么,先触发什么后触发什么?用户手册中也没有相关的说明。如何才能把这件事情弄明白?其实并没有想象中那么难,只要稍稍花一点时间,你就能彻底掌握其中的奥妙。
( L7 G7 c: U- S& Y接下来我们以货架随机摆放临时实体为例,来看一下在flexsim中,各种事件、触发的发生顺序。8 g2 l3 w% K5 c+ p" a! [( R
flexsim中依次拖入货架、发生器、暂存区,软件会将这三个实体自动命名为Rack2Source3Queue4(请注意这三个实体的拖入顺序)。依次A连接发生器、暂存区、货架。双击打开货架属性,勾选“Floor Storage”,设置最大库存为50,设置列和行随机摆放,每个货位内最大摆放量为1,设置货架为510行。$ h1 o/ n3 x% M$ C
         
, I! L9 w& e1 D0 d, G! \/ {
3 y# L5 I& R) w5 k重置视图,最终效果图如下所示:/ _) e& g7 Y2 u  \( H$ V4 d
6 k6 J/ q" Q0 ^; U/ y
debug菜单中选择EventLog,打开Event Log窗口。
: V: b: H" [  v5 D1 d) Q% E
' `0 @( Q7 v. z点击settings按钮,我们可以看到flexsim可以记录的事件类型和事件列表。# C3 e0 p3 E' L
$ n* N3 _0 W8 Z" k6 @2 |  v. R
Flexsim把事件分为了四大类:EngineTriggerTaskSequenceBeginTask
( B1 T1 F3 F1 O: ~' E. c/ ?5 t$ x7 s7 k( M5 a( o
引擎事件包括了创建实体、摧毁实体,打开输入/输出端口,接收实体,发送实体,发送消息,定时事件。
- x- G$ U& U' W- b9 o! ]' }+ s+ p4 f) k# X1 F' B/ J% l
触发事件就多了,我们在实体属性的触发选项卡中见到各种触发都可以在这里找到,还有属性窗口中的一些设置项也可以视为触发。比如发生器的到达时间间隔,处理器的“预置时间”等,flexsim也将其归类为触发事件。' A$ Q+ \8 `& \" j8 R  F# S

  Z/ A/ c2 q5 w; n% L9 WTaskSequenceBeginTask其实都属于任务事件,flexsim将其细化,分为两类。- A! S+ D/ R" [- W- j
任务序列事件只包括开始任务序列、结束任务序列、接收任务序列。
# e) h; o& X6 c* r) f8 Q2 L4 J, j" A2 R2 o
开始任务事件则是任务序列的具体过程,比如装载、行走,卸载、中断、移动实体等。
; H7 ]8 o. @0 ^+ u3 o& v/ j6 x2 F0 Q0 v  Z( ~
Event Log窗口勾选”EnabelLogging”,运行模型一段时间后,点击”Export”,将事件日志导出保存。也可以自己指定运行的时间段,比如设置Start Time0End Time15
5 L9 n/ _0 m  s$ K打开保存的日志文件,就可以看到flexsim模型在运行过程中各种事件、触发的顺序。* x2 E! O7 x+ T/ F8 Y
* I; M  G/ G. f: v% f
先看一下0时刻模型发生了什么:' W/ n% }* T, ]+ }9 d* ?8 ^
  Time
- c4 H* }! G# J0 y  E  
  Object
9 ?8 ]3 `" k& g# d5 W2 _  
  Event
7 U4 T* g" }5 [+ [( t  
  0' ]' ]5 D/ K  Q9 t5 O5 C! d
  
  /FlexsimModelFloor
. j/ h" X9 w& s& }  
  Trigger: OnReset; y; p" T+ W, ]* B6 R
  
  0" N9 {( t. c& R4 O5 J$ E6 R
  
  /Rack4
' x4 {6 O; _  D  
  Trigger: OnReset1 p4 O3 J" E' P9 i* v
  
  00 ]9 o* \$ d# f. V3 ?2 ?8 o
  
  /Source33 e9 A: s  J! L. V- G+ T6 p( h
  
  Trigger: OnReset
1 M/ P: w6 H3 _8 z* M/ g  
  0
9 m1 t' c. k4 H8 |) s& i  
  /Source3( M! Z3 S6 F/ A& U
  
  Trigger: Inter-Arrival Time0 R) Z) J, ~8 {) v% k$ G# o
  
  0% g! ^' Y# h8 z+ }
  
  /Queue4
: w8 x# w+ J& K  
  Trigger: OnReset% Q% B* X( M+ o! T4 z" [$ j/ C
  
0秒的时候各种实体会激发OnReset触发。本例中依次激发了FlexsimModelFloorRack2Source3Queue4的重置,重置的顺序并不是按照模型逻辑,而是按照实体创建的顺序。在创建模型的时候我们最先拖入的实体是货架,所以货架在发生器和暂存区之前被重置。而在货架之前,flexsim自动创建了ModelFloor实体,所以货架的命名是从2开始的。这一点可以打开树结构验证。
9 A; n% B3 J8 x$ I8 m  I" S' U* ?* H+ f! [
在发生器被重置之后,马上触发的到达时间间隔触发,这是为了决定什么时间创建第一个临时实体。
3 b# L2 n; V& g* f! B5.303038时刻,发生器创建了第一个临时实体,并由此引发了接下来的一系列事件和触发:
& u1 p+ p5 v1 Q
  Time
: G: ]0 o  d+ d: ]1 C  
  Object1 l6 h7 s  v5 ]
  
  Event9 r1 d6 b' u" K
  
  Involved
$ S# u6 e$ Y+ M7 ^  n  
  P1
1 w  X  d1 V) B( }$ I+ q3 _  
  5.303038
$ }+ p0 }) S6 N0 Y$ }7 C7 b  
  /Source3( Z$ J& `7 b" ~9 j2 b
  
  Engine: Timed Event) b5 B% n0 G1 O" \7 i+ G; ?9 @
  
  /Source3
, b5 J# x- f. T6 Z( L. q  
  EVENT_CREATEPART
8 f$ B, w( }% R  T& l: W2 D  
  5.303038
# E  K& s1 l1 w# l/ b$ h* X' `  
  /Source3
  b6 v; L+ \7 |. T# k. i  
  Trigger: OnCreation
: Z( Y. Q% _: u. r6 u  
  /Source3/Box
& g1 J: i5 B1 J9 S  
  rownum: 0.05 c; F$ J9 G+ v; n- Y
  
  5.3030383 C" c  a2 z, w( @
  
  /Source36 W) I0 x! t0 s$ {  r- F' _
  
  Trigger: Send To Port4 o2 z) m/ k  Z2 |0 o
  
  /Source3/Box7 Z4 q3 O) o$ b4 L( y* K9 }9 g
  
  $ M1 y+ g; O" T8 E3 Y' g' A: @' Z

6 T; W: V! s' Y: r& D; X5 `9 j/ H5 f  
  5.3030385 `$ C  _+ w( H, e( e
  
  /Source3* h$ X- a/ l5 ]( ?2 d
  
  Engine: Send Object
/ Y3 ]/ z" O1 j$ B. y  
  /Source3/Box; {" \# T+ ?( \' ~( i8 S" m8 L
  
  ' v6 P7 {$ a5 w' E- y- {6 E
. `& m, e9 L& z4 K% m9 q( K
  
  5.303038
# j6 f5 i' q/ {. w3 W# ]  
  /Source3
! r/ X# ]- x: [1 u  
  Trigger: Inter-Arrival Time
1 l! ^4 \' D. S* [% d  
  1 w, B  |3 @& R+ L1 `) r9 t8 M# O6 K
. j" _) S6 S$ A" D
  
  
. w- X0 d" n; y3 @! C' c: a" v  a& {+ J6 U
  
  5.303038
6 o6 L. f6 q! J, K% \6 w  _" t  u  
  /Source3
* y( k5 A+ |  b1 P  
  Trigger: OnExit) I- }  @7 ], Q; ?, B1 |  Q# `
  
  /Source3/Box. S. [0 Z2 E& K& @
  
  port: 1.0
- t0 w! s+ O! X8 U& B# |# _: C) X  
当临时实体被创建时,首先执行的是定时事件:CREATEPART,然后才激发创建触发,临时实体被创建后,还要决定其从哪一个端口发送,然后执行发送,临时实体离开发生器。而在临时实体离开之前,发生器还激发了到达时间间隔触发。* g1 {% \" C& v
本例中的每个实体都是以Engine事件开始,要么创建,要么接收。暂存区正是以接收实体事件开始:
, L# W! e2 ~" U& B
Time
1 L4 z, _# A, `' Q7 s4 Y  
  Object7 k  d, _; Y4 [: z- q5 M& W
  
  Event
! }9 V( Z& t3 H" ^; m( ?1 t( h  
  Involved
: r& a! q4 g2 x4 l  
  P1
% @5 x$ }" a) }: a" W. L  
  5.303038( X$ S% Q' a8 F/ q9 W/ E+ C
  
  /Queue45 Z2 X- ^% J# o6 B
  
  Engine: Receive Object/ D0 `: N# g& [! S3 A
  
  /Queue4/Box4 G% \7 f; |3 W7 ]; T& |
  
  
! ^4 x' L% |& [. @1 c! I1 N  W* Y8 e7 J: [& ^. l$ r
  
  5.3030386 ^: ^1 }7 m# h& ~+ s
  
  /Queue4; Q8 X" ^% m/ y( }2 Z8 u, e9 A
  
  Trigger: OnEntry9 {! V9 \) U1 G: }
  
  /Queue4/Box
. |/ B( |% m' x- p) u- ]( p6 C  
  port: 1.0' [4 e0 c# D( d& ]) @% H9 m
  
  5.3030389 ?; j( u" e  y6 f$ |% L9 w  ~7 k' v$ D
  
  /Queue4( e3 ?  w" m" d- g
  
  Trigger: OnEndCollecting
! y2 B) b6 s1 p5 o, [4 a& T  
  /Queue4/Box
5 Z. T' K- U) |# c# v  
  batchsize: 1.0. c* Q/ z( e$ A/ @. {' c" ?
  
  5.303038$ D! ]+ U5 p- V) Y- c3 Q' ]- A
  
  /Queue46 i5 {7 S; _& H2 ?$ W
  
  Trigger: Send To Port
+ [1 M2 _1 p/ v" R+ U  
  /Queue4/Box
& _2 P1 c$ U0 C5 @8 I  
  & P1 v& e2 K3 e' t. m( _# v

* q2 w0 _0 P/ \! @4 x  
  5.303038
# f5 X+ ?- E$ _: V1 z7 V1 r  
  /Queue4
8 @" _+ u! }% U  
  Engine: Send Object
9 w* Z. |( t+ k8 t  
  /Queue4/Box
/ f' T( d7 m9 E, f3 P8 }* g  
  & N3 [; c2 h# c' x: d

% o6 P( h5 G$ ~  
  5.303038
' E, e$ z/ `" j5 G2 n  
  /Queue4$ Q9 J3 \, }: ?2 q$ ^, N0 ^
  
  Trigger: OnExit
) f! V% ]  l. P) H  
  /Queue4/Box
0 W! m+ v8 w  y  
  port: 1.0
9 D( f7 q' Z: I2 S- \$ q  
接收实体之后激发了进入触发,然后判断批次,获取发送端口,执行发送,最后离开暂存区。7 l9 y, T8 C: E; V3 ~6 d
货架同样以接收临时实体开始:
/ d  K9 Q4 Q  A3 }5 q) ]9 ~" e+ q2 \
  Time" C  _( Q- ]4 d& l
  
  Object; k- a) n+ h4 ]: O. |6 {% S# l
  
  Event* d/ |# K. y1 l
  
  Involved8 N2 a0 r- l3 j! ^4 b9 d
  
  P1
- u+ ?1 i7 b3 i/ k1 f" k  
  5.303038
1 y' ?- h% E! V  
  /Rack4% F1 @2 {" \$ [2 ^' Q
  
  Engine: Receive Object% M( u/ F, l9 G# I' Q  a3 n  K
  
  /Rack4/Box# h/ v, J0 e; x( }, D
  
  9 v' g( Y3 ?$ z% l9 k4 |! O& R3 t% y
1 M  r& k; V- `# f1 z3 |
  
  5.303038$ F7 H" s' K7 A: k" l( f+ u
  
  /Rack4  |2 F6 Q# L! z2 R+ j
  
  Trigger: Place in Bay
) _+ P2 D' \1 {: _1 J  
  /Rack4/Box
/ X8 O) }$ k" ^0 m5 D) k  
  ( u& B* O& |- \' S) k+ b
  q9 s9 f' O4 \1 u( ^, u: x) o6 h
  
  5.303038& p" q2 c, y% l. o) C3 n# [" ^/ T
  
  /Rack4
! ]) U$ U; b2 ]; \- @  
  Trigger: Place in Level+ f1 W- w& D* G
  
  /Rack4/Box# E2 R! G' {/ k0 c+ u+ k3 ?
  
  bay: 3.0/ ?6 k% _  ^+ T* |9 _
  
  5.303038
* R- w1 L. G3 |: I9 n4 V9 Y* d  
  /Rack4' d/ s6 g% C- ~2 J
  
  Trigger: OnEntry+ n. ]  M& i& M" x' k( h8 r
  
  /Rack4/Box
/ W" P$ b% ^  o, k! {& j  
  port: 1.0
) I& m' k" m0 n# G+ X' V# d  
  5.303038, Y: B  T# N3 t* G$ @8 w( @
  
  /Rack4
" X  d; V% P" v; ?  
  Trigger: Minimum Dwell Time/ S8 u+ `1 |7 ?1 Y; R
  
  /Rack4/Box. t" R- i* p4 T& J
  
  port: 1.0) X) [9 n0 V5 Q$ D5 v/ `6 `
  
  5.303038
4 _$ m8 d3 w" ^5 |  
  /Rack4
* q3 l9 z  W/ J" w5 [  _5 Y  
  Engine: Timed Event
/ T/ _1 o! M$ q) q& o& B) D: W  
  /Rack4/Box8 s, l/ b: A9 D8 C
  
  EVENT_PROCESSFINISH" N$ }  K$ i- ^- F8 N' k
  
  5.303038
0 g# y; E) ^' L1 K0 G4 M  
  /Rack4% u8 z" Y2 G! p' @) b
  
  Trigger: OnEndDwellTime1 _) q% c- U6 O- u0 [
  
  /Rack4/Box
. F# Y  U. E; I& k8 g  
  
0 W3 h8 r# b; U4 E( D% L6 W
$ @- i$ r9 U" l5 V# t/ |  A- B2 P  
  5.303038
  C! `  i9 X* y3 i+ m6 ?5 q  
  /Rack4
& V- F* g/ M, q0 z  
  Trigger: Send To Port  ~1 ^( \5 z* B; k+ B8 I3 @/ D! X
  
  /Rack4/Box
: a5 `1 Q$ {* [6 r9 j6 [  
  
. i' [  O0 \9 J" Q: J& m) W& C$ o  y! H* O; [8 }* j
  
接收临时实体之后依次判断应该放置在哪一列、哪一层,然后激发进入触发,临时实体进入货架之后需要获取其在货架最短停留时间,由于这里设置的最短停留时间是0,所以随即激发定时事件PROCESSFINISH(如果是停留结束会更合理、更便于理解),再激发“停留时间结束触发,最后获取发送端口。由于本例中并没有为货架指定下游端口,所以这里没有执行”Send Object“事件,也没有离开触发。- b* h1 D! n  h: l
接下来的其他时间节点都是在重复着同样的事件和触发,直到货架被摆满。
1 r5 r  k+ s0 r; n通过Event Log工具,我们可以详细的分析每一个实体的工作机制。比如可以分析推式策略、拉式策略的不同,比如可以调用运输工具,添加任务序列,来分析任务的优先级别、先占级别的处理机制等等。
& d! D7 K8 E7 m3 K2 x  O" b" @$ l1 q% l" O. E5 x+ m
) F: f7 M5 k# N: G

4 ]6 D: M; Z5 ~+ E: s

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
2#
1010265352 发表于 2015-9-23 14:04:53 | 只看该作者
学习啦
3#
FFFrenk 发表于 2015-9-24 12:04:12 | 只看该作者
感谢分享event log的使用方法!讲得很详细!
% N% S! E  L* Y' f* e8 F" b2 ]) j/ t( Z* D
- D) G$ L, L& \& _3 w3 Z
文中出现其了一处与我理解不同的地方,我贴上来,一起讨论讨论~; Y+ e3 f8 K0 f7 W/ I

" B, f8 a% B5 L$ r. p. a' F. k  e“重置的顺序并不是按照模型逻辑,而是按照实体创建的顺序。”% K& M% c$ d- X8 z" l8 g9 v  r* f
并不是实体创建的顺序,flexsim中并没有一个节点存放实体创建的时候(临时实体有)。  d9 R& Z" {% a7 f% i
这是因为,先拉到模型中的实体的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 | 只看该作者
我也说一点:: `$ r- D9 @5 t5 y' d
在事件日志中,涉及的实体一般都是box,这样我们很难区分到底是哪一个触发的,如果需要,我们可以对产生的临时实体进行重命名,编号处理,这样就可以知道就哪一个临时实触发了什么。
9#
manaijin 发表于 2016-4-12 11:04:30 | 只看该作者
对软件的运行机制学习很重要。
10#
慧娴亚伦 发表于 2016-4-13 09:32:49 | 只看该作者
我也说一点:% q8 I3 [1 L$ u( c  J# K
在事件日志中,涉及的实体一般都是box,这样我们很难区分到底是哪一个触发的,如果需要,我们可以对产生的临时实体进行重命名,编号处理,这样就可以知道就哪一个临时实触发了什么。! i, V+ C4 O) C" j' G  n
657776724 发表于 2015-9-26 18:00

4 m8 r" X' s2 M& w$ @" v1 Z) D2 l$ K$ l5 L( T7 o% s# U2 a' K% y6 t
一个好消息:最新的2016版本已经自动区分在不同实体上面不同rank的实体了,这样就使得debug的过程更加简单方便快速~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-6-28 19:00 , Processed in 0.078442 second(s), 14 queries .

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

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