全球FlexSim系统仿真中文论坛

标题: 对于处理离散实体的固定实体,可否指定关闭某一个端口? [打印本页]

作者: zorsite    时间: 2015-9-29 14:48
标题: 对于处理离散实体的固定实体,可否指定关闭某一个端口?
本帖最后由 zorsite 于 2015-9-29 22:08 编辑 / l2 }/ O4 p4 k8 J$ g% `) X# r
. F& H4 Q; \  d+ l% v
我们知道有些命令可以打开、关闭输入输出。比如:打开输入输出:openinput、openoutput
0 C% A9 ^1 M) o/ {! U! w# |0 s关闭输入输出:closeinput、closeoutput* ^) ]! z- e) s0 v* N8 @& F$ a; E
假设在重置触发中使用closeoutput命令关闭暂存区的输出。
  1. closeoutput(current);
复制代码
关闭输出端口后输出端口右侧会出现红色的小方块表示关闭,一旦使用了closeoutput,所有的输出都将被关闭,即使有些端口仍然处于可用状态,临时实体也无法离开。
" C2 z0 V- m% ]$ X$ [. E[attach]2820[/attach][attach]2821[/attach]% `9 }' M* U! C+ X3 f
注意:4 D# W% Y7 h8 g4 @0 m
Connectionsin和connectionsout表示的是实体的输入、输出状态。为0则表示打开,为1表示关闭。
, B. Z. L7 }  {2 m+ L" hConnectionsin和connectionsout下的子结点表示有多少个端口,为0则表示不可用,为1则表示可用。可以在第一张图片中看到有1个绿色的三角箭头表示输入端口可用,2个红色的三角箭头表示输出端口不可用,以及红色三角箭头右侧的红色长方块表示输出关闭。

9 y) B$ @) V5 L2 c- o. zFlexsim中还有命令可以打开、关闭指定的端口:openip、openop、closeip、closeop
! W2 v; f" @+ |2 i& P& {# X。命令注释中说明此命令用于流体对象。离散实体内部行为会控制打开或关闭端口,可导致此命令失效。
Modelers should only use this command when working with fluid objects because the internal behavior of discrete objects controls the opening and closing of their ports, and therefore this command may be overridden.

$ G5 K3 o7 Y: P( p3 I  m* t是否真的会失效呢?测试一下。
: ]3 A/ J! v* Q$ n删除重置触发中的closeoutput命令,更改为
  1. closeop(current,1);
复制代码
只关闭暂存区的第一个输出端口,重置模型看效果如何。4 b- A4 ^# q" e- T
[attach]2822[/attach]
& H/ J/ O; d/ u  R! \$ v2 V  U- O/ }# B, W" @/ f- q  @
不管是从模型还是从树结构中观察,好像都没有发现第一输出端口被关闭。, B9 [: G4 j- ?; o) Q
没关系,还有一个命令专门查看某个端口是否打开:opopen。如果处于打开状态则返回1,否则返回0.
6 }6 ?) F# z6 B" x& X: ^$ y[attach]2823[/attach]
  j& ?7 c5 X8 f4 [0 [9 V% j! B7 u; Y: z! x+ D& Z1 d9 ^
通过中断调试,在本地变量窗口中查看两个端口的opopen返回值,发现都返回1,表示都处于打开状态,并没有被关闭,结果和在树结构中观察到的一致。
, k1 e- N1 `2 n结论:不能通过closeip、closeop命令来关闭处理离散实体的固定实体的输出输入端口。
7 _3 [& [5 c9 n+ d0 p* L( n+ {, x" j# O
我对Flexsim中的端口相关命令进行了一下分类,并总结了一些规律:' J: q% @5 H% c& R
ip=input port- ^* c. w# D7 u, }* ^/ |
op=output port2 h! K) E; H% r8 }$ S* w
cp=center port, m" u7 Y9 p; p' p
nr=number数量
+ S# C- B% [% n- D' u! Dno=NO.序号,号码
0 b, X5 m5 ^0 ?2 r7 x2 |9 b4 h+ v
) _5 V7 n) k* R0 i( K6 o) z1 }
命令大致分为以下几类:
4 p- u) V+ p9 ~8 {/ o操作类:; X, R( I0 g, F( L
比如打开、关闭、停止、恢复2 S. s! }  ~1 E4 {
判断类:
4 s! s9 h- y( I+ N/ @判断输入输出状态、
- r) \6 M$ M. z. G判断输入输出端口状态、5 E9 u9 Y! ^3 H$ i3 \
判断端口连接是否畅通、  W7 e! @! S! ]9 T5 D9 j2 _3 m/ Y
判断上下游端口是否可用9 l+ R) d7 z% }9 B0 i3 D
统计类:8 t$ ^+ x- j5 Z5 K$ ?
统计输入输出中间端口的数量3 i; H1 i. a2 c( t5 p0 X
获得上下游实体类2 [4 e! ?2 o/ C$ e( t9 l
获得上下游端口号码类
( [" L% l5 G% `7 u6 J
打开输入输出* N8 }3 \0 p# A
openinput
# y2 W8 a4 ]2 D* N, K: ]0 topenoutput$ |: Q- f) s- F* q, k7 n2 U
关闭输入输出
- C8 u0 X5 n& C* |8 ?: @closeinput) v0 ]( J/ X  {( `! l/ d- C, C6 [
closeoutput; ^# a* f6 j% K' {
停止输入输出1 i7 y9 e# h7 O
stopinput
+ G$ E& e7 [9 t0 m; m2 v) Q& Nstopoutput
' r5 ~7 U+ v7 A恢复输入输出
. H2 B9 R* Y# S6 aresumeinput# X, y$ P4 o5 {% Z
resumeoutput
* x- Y0 \" B: O* K" K$ |! E" z打开某个输入输出端口(用于流动实体)
: y* G! j4 [( b- Qopenip. Y$ _3 ]6 g/ @" ^# {; o  }2 ]
openop& {; S  l& A5 l0 N
打开所有输入输出端口(用于流动实体)! q6 r1 ]8 n  e* {+ n! k
openallip7 p- D) S& o& P8 m, o. l" n% Z
openallop
; Z8 E* ], i" R6 c  E, g& M, R关闭某个输入输出端口(用于流动实体)
0 J  G( C6 w5 Vcloseip# {3 U! c+ w3 @- _7 F; x
closeop
% F0 s" z- s0 v- _5 H3 y关闭所有输入输出端口(用于流动实体)
* ~  A- v6 ?( Acloseallip5 s& a) Y. s- b4 P; n3 i
closeallop
. Y) d& {- |3 Q$ [# X! V2 A+ z
9 G" b& p5 i. n6 w# T$ v2 F判断输入输出是否打开$ J- {5 o1 ^3 b
inputopen  \' W% O1 Z" Q# D" P
outputopen$ M( ], s  }1 n, N8 x$ ~3 i
判断输入输出(端口)是否就绪(畅通)
0 s$ `$ L7 P9 ]7 ^7 I; hipready6 G9 P( l5 M3 `0 P1 u9 {: e1 V
opready
* T' F/ T# W- ]8 t8 m1 {判断某个输入输出端口是否打开! Z) q- n5 H5 ~* f3 P
ipopen4 |, v! \7 [1 J0 v! k* k
opopen( y  }" y# ?$ R- `9 e
判断上下游端口是否可用
! y$ Y, s2 l) T/ J% Kipavailable5 K$ t  p7 i0 O
opavailable
& o, _& h" z5 @1 F$ Y$ T% z: n: t1 m3 O# A- E5 R: }# e1 z4 e
统计输入输出中间端口数量
3 S  y: H9 e: u. c  A
nrcp
$ |, k( i7 ]3 j# \3 |nrip7 {( d0 Z# C9 R3 m
nrop
- W$ X% M, J! X9 T% n/ P2 ~
# B* b$ R& H1 o1 @( K返回上中下游实体; }9 q% p8 _0 P; l, D
centerobject
( t" Q# `: t1 {0 u3 rinobject
9 U1 W. U% ]2 j' ]* R% }outobject
, I5 Y$ ?* o( J7 ]获取上下游端口号码
: B/ q9 `2 ^# s8 h1 Z# v1 ]+ a
ipopno上游输出端口号码
. {: ^) ^9 m3 E% b" i  w% c4 l5 ucpcpno中间端口号码0 `- w$ Q$ p: T  q2 ^% \' O
opipno上游输入端口号码

: D0 Q" Q  B: a- c8 t' E- }5 n/ i[attach]2824[/attach]
作者: 大摸鱼    时间: 2015-9-29 19:23
加老师的帖子篇篇都是精华呀,感谢加老师无私分享
作者: 慧娴亚伦    时间: 2015-9-29 20:38
目前看到下载次数有18次,但是回帖非常少,感谢楼主无私奉献,希望大家学习至少也给楼主一些支持和感谢!
作者: zorsite    时间: 2015-9-29 22:01
哈哈,回帖什么的我不介意的,但是有人回帖我还是很开心的。特别是二位版主的回帖,更是给了我无穷的动力。
4 z! B1 P+ g0 W+ o4 R; d其实没有建设性意见的回帖还是少来点好,这样后来者查看的时候不至于浪费太多时间。
作者: 657776724    时间: 2015-10-2 08:17
很详细!很深入!感谢分享!不过在“判断”的那一个部分那几个代码似乎让人难以区分差别
作者: 657776724    时间: 2015-10-3 10:19
说一下自己的理解,不知道对不对:
. `+ \* p, b6 n" d7 a, j1、inputopen是用来判断箭头前面是否带杆;
" X1 |0 }! O8 e( V* M& o/ x2、ipopen是用来判断箭头的颜色;5 H  t& \% d% R1 o5 x0 h) a+ M
3、ipavailable是综合判断是否带杆和箭头颜色;! ^& j) L) v* V! f4 m0 R( a
请指正
作者: shiningcz    时间: 2015-10-8 14:45
我同意楼上对inputopen和ipopen的理解,但ipavailable是判断上游实体的端口状态,不是自身,有点区别
作者: 781643823    时间: 2015-10-8 17:00
这个问题已经在4.0的时候就做过了 ,如果要真的解决关闭某一个输出端口,只能关闭他的下一个实体的输入端,就是在onexit写入代码closeinput(outobject(current,1)),就可以了!你可以试试
作者: 慧娴亚伦    时间: 2015-10-9 16:18
我觉得这样想是不是可以加深大家的理解:& U* D$ E+ L! B3 r
端口是否开放(open)和输出是否打开(inputopen)都只是输出端口一个片面的属性,不能决定到底能否将实体向下游发送。而是否可用(available)则是一个更加严格的概念,需要各方条件都符合才行。
作者: zorsite    时间: 2015-10-9 20:47
本帖最后由 zorsite 于 2015-10-9 20:49 编辑
1 T( S5 _! S0 v$ [9 u" M( }
  i8 x# V' b/ O0 @2 b& v9# 慧娴亚伦
; H" c7 P# b( a# g9 w6 f/ E: B( l5 Y! [! u5 b$ Y6 p
总结的很有道理。
( ]7 N3 p# y1 K( _6 W" B) C也很感谢各位非常有意义的讨论和回帖。8 e- _/ T7 ]7 }, S

( E& S% l) Y6 g% E8 Q我之所以提出这样一个问题,是在做FMAT样题第一题的时候,FFFrenk版主提醒说有更简单的解决方案,就是系统自带的拉入策略“Pull Best Item”。missman也给出了自己的代码。见http://www.flexsim.asia/viewthread.php?tid=5361&page=1&fromuid=610#pid17648
: y2 h* t  x4 m% f: o7 p6 T( ^于是我就去研究“Pull Best Item”策略,发现其设置了非常严格的端口检测条件,有兴趣的可以观摩观摩:
  1. ) H! ?% w* o  r3 t. A
  2. int nrports = nrip(current);
    6 E5 @+ d4 \& L- L7 p9 w! b
  3. int domax = 0;
    / `; Y' ]. x2 m# l, u! r( p
  4. if (!inputopen(current))
    1 Z9 [8 s5 S- \* V
  5. return PULL_REEVALUATE_ON_READY;/ v5 K- c, \( L( E( t8 Y4 b
  6. double bestval = domax?-10000000000:10000000000;
    , P6 i" w3 Z2 u1 W2 U8 Z& U$ ~
  7. int bestportnr = 0;! J* O0 l9 x3 J9 o( J, m- V9 Z5 U
  8. treenode bestitem = NULL;
    2 o( r1 m- ~" b' I8 v9 e: `( M% x1 c
  9. for (int i = 1; i <= nrports; i++) {
    ) d4 `) e9 n/ Y, V
  10. treenode object = inobject(current, i);+ g" a$ M/ R$ G, p
  11. if (!outputopen(object))
    / ~! }" o4 }  W
  12.   continue;
    / v) _' H  l8 W; X
  13. int opnr = ipopno(current, i);
    , x$ a/ a! E6 f$ G- q( D$ r! q5 c8 h
  14. if (!opopen(object, opnr))
    3 j; m4 \  t+ C5 i+ u6 x
  15.   continue;
    2 l2 B6 L8 U( L, a7 k# {/ q9 l
  16. int startindex = 1; int endindex = content(object) + 1; int incr = 1;) U" B8 \' E, X$ P+ a! y
  17. if (getvarnum(object, "lifo")) {
    ! d' k! i* b' R: ~
  18.   startindex = content(object);
    / M' A) r# I+ d% |4 z6 Z! O
  19.   endindex = 0;- ]5 q9 P* X2 E! w" A) g- k. Z3 q
  20.   incr = -1;
      [. \% g( k0 Y! y' p% N& ~  T' n+ Z
  21. }
    2 v, U. g- L" [7 W5 f) h

  22. ' e7 s9 J3 V; m6 Q% @8 g
  23. for (int j = startindex; j != endindex; j+=incr) {
    8 m5 Y: W- u% S) @: F6 _
  24.   treenode item = rank(object, j);: H( ]7 a) i; f" S3 c+ e
  25.   if (evaluatepullcriteria(current, item, i)) {$ o+ e5 ]* H5 u' H% y3 E6 t+ G
  26.    double val = getitemtype(item);& d7 G, }5 k' O) J9 }* o
  27.    int newbest = domax ? val > bestval : val < bestval;3 |# C5 Y$ D8 }4 Q1 }" m* M
  28.    if (newbest) {+ S# Y- X; \# v5 F. q( |( k2 |
  29.     bestval = val;/ ]2 C/ E9 [6 v/ W) F* j0 L1 p
  30.     bestitem = item;: B0 b' W1 A1 J) k$ {* @
  31.     bestportnr = i;6 E8 d0 t, ]$ e6 t/ C* B
  32.    }
    2 L& T: i/ j1 _9 A
  33.   }
    5 D9 `* J9 u# }$ _/ ?2 Y
  34. }
    9 _% Z5 P, E; {7 ~* ~+ [
  35. }
    % a4 @/ J( g9 w& a4 U
  36. if (bestitem)
    - G( a: j- K9 w0 y9 d/ Z6 j! d* B
  37. pullitem(current, bestitem, bestportnr, BYPASS_ALL);8 q) i7 a0 R  q! t* R  }4 G
  38. else return PULL_REEVALUATE_ON_READY;" A  m+ O! C  s7 m0 x# n
  39. return 0;
    ( Z% O% X) s: v/ _6 c
复制代码
在这段代码中,前三个if都是判断端口状态的。/ Y! v% x# E8 q. |3 H1 n7 g. P
if (!inputopen(current))
, W6 G  o  b! f) d1 Q3 l, x" mreturn PULL_REEVALUATE_ON_READY;
8 ~! Z2 |7 M) R, ~. x5 p/ @//如果处理器端口没打开,用return跳出此段代码
) e$ B( x# {- R  T1 u5 @......
% P8 s) M3 W7 jfor (int i = 1; i <= nrports; i++) {! W# e6 @# R% m- i  z1 L' k
treenode object = inobject(current, i);& @1 u5 J& Q4 k: `1 v
if (!outputopen(object)); w  H: [: H- `
  continue;" r/ A* L& S6 q7 `6 W+ ~: ~
//如果上游输出端口没打开,用continue跳出此次for循环
; o+ o7 B5 {- j8 S# cint opnr = ipopno(current, i);2 p5 [& r4 X$ U  G5 i) k
if (!opopen(object, opnr))0 Z& U% ], A5 V( C
continue;
' m- h6 Q' ^. S5 I" ?//如果上游输出端口打开了,继续判断上游实体与当前实体相连的那个输出端口是否打开,如果没打开,则用continue跳出此次for循环
4 \! t7 ^' }3 F9 p1 Y3 |% S: f- f6 x
我主要是对最后一次判断比较不理解,因为根据我在前面的分析,固定实体是不能单独打开或关闭某个端口的。
作者: zorsite    时间: 2016-3-30 10:45
我同意楼上对inputopen和ipopen的理解,但ipavailable是判断上游实体的端口状态,不是自身,有点区别
3 t" E+ D) w: T. ]4 ishiningcz 发表于 2015-10-8 14:45

# e7 z) _8 y9 M* r$ F! h' G非常正确,我在原帖子中没有说太清楚。& V! |- U, E; ^6 p" B
[size=1.1em]ipavailable [size=1.1em](obj object, num inputportnum)' q1 {2 [4 Z( g
Description
, I7 n  a& A* l6 w4 ?Returns a 1 if the upstream object through the specified object's input port is available. Particularly, it checks if the upstream object exists, if it is stopped, if its output is open, and if the connected output port is open. This function returns 0 if the upstream object isn't available.
; Q0 X& B5 Q1 T: q
" O1 Z# ?* k' o& F+ ]Example) D# y/ @9 J; T' u
ipavailable(current,1)
作者: eb_sun    时间: 2017-5-14 08:32
理解起来有点难度,继续好好学习




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