Flexsim消息机制知识分享

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

F l e x s i m消息机制
Flexsim消息机制
消息是Flexism中一个很强大而且经常使用的逻辑功能。

消息可以使得分布在模型中的各个实体之间相互联系,可以跨越多个实体向他们发生消息执行特定的任务,而不必局限于相邻或上下级之间的实体。

message –从一个实体发送到另一个实体的信息.
当实体接收到消息时,消息触发器被触发。

消息通过命令发出。

sendmessage() 是立即发送消息,senddelayedmessage()是延迟一段时间之后才发送消息。

当使用这两个命令时,将给指定的实体发送一条消息,并执行此函数。

每个命令可以执行3个用户自定义参数。

命令的参数如下:
sendmessage(toobj,fromobj, param1,param2,param3)
senddelayedmessage(toobj,delaytime,fromobj,param1, param2, param3)
toobj:接收消息的实体
fromobj:发送消息的实体
delaytime:延迟时间(第二个命令特有)
param1:第一个用户自定义参数
param2:第二个用户自定义参数
param3:第三个用户自定义参数
其中传递的变量(即在接收消息的实体的消息触发中传递的变量):current:当前实体(接收消息的实体)
msgsendingobject:发送消息的实体
msgparam(1):消息的第一个参数(用户自定义)
msgparam(2):消息的第二个参数(用户自定义)
msgparam(3):消息的第三个参数(用户自定义)
发送消息和接收消息实体间的消息执行机制:
有一个这样的模型(如下图):
当传送带5上进入5个item时,发送一条消息给暂存区4,让其关闭输出端口:
那么可以这样发送消息:
在传送带5的进入触发(发送消息的实体):
if(getinput(current)>=5)
senddelaymessage(inobject(current,1),0,current,1,2,3);//发送一条延迟0秒的消息,传递的三个自定义参数分别为1,2,3
在暂存区4的消息触发(接收消息的实体)
treenode cv5=msgsendingobject();//声明发送消息的实体,即传送带5 int msgtype1=msgparam(1); //声明传递的第一个用户自定义参数,此时为1
int msgtype2=msgparam(2); // 声明传递的第一个用户自定义参数,此时为2
int msgtype3=msgparam(3); // 声明传递的第一个用户自定义参数,此时为3
//此时可以分别引用三个参数作为判断条件
//引用第一个自定义参数
if(msgtype1==1)
closeoutput(current);//关闭暂存区4的输出端口;
//或者引用第二个自定义参数
if(msgtype2==2)
closeoutput(current);
//或者引用第三个自定义参数
if(msgtype3==3)
closeoutput(current);
说明:
(1)三个自定义参数的数据类型需为数值型;
(2)三个参数一次只需引用一个,如果引用多个,且条件都满足,则按引用先后顺序执行;
还有一种比较极端的情况,就是什么参数都不引用,而直接写执行语句。

比如以上的例子,在暂存区4的消息触发中,所有声明都不写,只写closeoutput(current);也能达到上述的结果。

需要说明的是,这中情况只适合执行一种任务,比如关闭输出端口,当需要执行多种任务的时候,必须使用不用的参数来定义不同任务的执行语句。

在上面的例子中,还有一个参数是没有用到的,即msgsendingobject(),因为在这个简单的案列中没有使用的必要。

发送消息的实体可以是固定实体,也可以是临时实体。

当涉及对临时实体的操作时,使用临时实体作为发送消息的实体会使逻辑更加简单。

比如下面这个例子,我们使用临时实体作为发送消息的实体,将会用到msgsendingobject()这个参数。

模型如下图:
在一个网络路径里,希望任务执行器7先到发生器8取一个托盘,再到发生器9取一个货物。

任务只执行1次,使发生器8产生托盘(pallet)1次,使用到达时间表的到达方式,到达次数为1次;使发生器9产生货物(box)1次,使用到达时间表的到达方式,到达次数为1次。

两个发生器分别与执行器S连接,并将三个实体A连接到网络节点。

(1)在发生器8的创建触发发送一条消息给任务执行器7 senddelayedmessage(centerobject(current,1),0,item,1,0,0); //延迟0s,通过item来发送消息,使用第一个自定义参数1,其余为0;(2)在发生器9的创建触发发送一条消息给任务执行器7 senddelayedmessage(centerobject(current,1),5,item,2,0,0); //延迟5s,通过item来发送消息,使用第一个自定义参数2,其余为0;延迟5s的作用是使执行器先去发生器8
(3)在执行器的消息触发,创建2个任务序列来装载托盘和货物:treenode item=msgsendingobject();//声明发送消息的实体,分别为托盘和货物
int msgtype=msgparam(1); //声明传递的第一个用户自定义参数
if(msgtype==1){ //发生器8发送的消息
treenode ts=createemptytasksequence(current,0,0);//创建一个任务序列
inserttask(ts,TASKTYPE_TRAVEL,centerobject(current,1) ,NULL);//执行器移动到发生器8
inserttask(ts,TASKTYPE_FRLOAD,item,centerobject(curre nt,1));//装载托盘到执行器上,注意这里使用的是item;
dispatchtasksequence(ts);
}
if(msgtype==2){ //发生器9发送的消息,同理
treenode ts=createemptytasksequence(current,0,0);
inserttask(ts,TASKTYPE_TRAVEL,centerobject(current,2) ,NULL);
inserttask(ts,TASKTYPE_FRLOAD,item,centerobject(curre nt,2));
dispatchtasksequence(ts);
}
在这个模型中,通过临时实体(item)来发送消息,看起来比较清晰。

也可以直接使用发生器本身发送消息,则在装载托盘和货物的时候需要分别声明他们。

上述代码做下修改:
treenode source= msgsendingobject();//声明发送消息的实体为发生器;
int msgtype=msgparam(1); //声明传递的第一个用户自定义参数
if(msgtype==1){ //发生器8发送的消息
treenode ts=createemptytasksequence(current,0,0);//创建一个任务序列
inserttask(ts,TASKTYPE_TRAVEL,source,NULL);//执行器移动到发生器8
inserttask(ts,TASKTYPE_FRLOAD,first(source),source);/ /装载托盘到执行器上,注意这里使用的是first(sourse)定义待装载的托盘;
dispatchtasksequence(ts);
}
//发生器9发送的消息同理设置
两种方法中:
(1)通过item发送消息,可以直接定义item为msgsendingobject(),在一些复杂的任务序列中,这个是有好处的;但是在引用发生器本身的时候,需要通过与执行器连接的中间端口来定义它,如发生器8为
centerobject(current,1);
(2)通过发生器本身发送消息,可以直接定义source为msgsendingobject(),也可以通过中间端口
centerobject(current,port)定义,但是引用的item需要重新定义为first(source)或者rank(source,1)。

在以往分享的案列中,很多都使用了消息的功能。

有兴趣的朋友不妨去参考学习!。

相关文档
最新文档