关键词不能为空

当前您在: 主页 > 英语 >

Flexsim中的重要概念及开发技术

作者:高考题库网
来源:https://www.bjmy2z.cn/gaokao
2021-02-10 20:03
tags:

-

2021年2月10日发(作者:瓦尔希)


Flexsim


中的重要概念及开发技术




第五章



F lexsim


相关的概念及关键技术研究



5



1 Flexsim


软件介绍



Flexs im


就是由美国的


Flexsim


Software


Production

公司出品的


,


就是一款


商业化离散 事


件系统仿真软件



Flexsim< /p>


采用面向对象技术


,


并具有三维显示功能 。建模快捷方便与显示能


力强大就是该软件的重要特点。


该软件 体供


了原始数据拟合、


输入建模、


图形 化的模型构建、


虚拟现实显示、运行模型进行仿真试验、对结果进行优化、生成


3D


动画影像文件等功能


,

也提供了与其她工具软件的接口。图


5-1


就是

< p>
Flexsim


软件及其构成模块的结构图


[7]




ExpertFit


等拟与分布工具



输入建模



Flexsim


仿真软件


< p>
模型


建立


与调




模型


有效


性确




运行


仿真


试验



3D


的可


视化



结果


动态


显示



生成


影像


文件



系统仿真



运行仿真试验





Microsoft Visual C++



NET


Excel


等可以用作统计分


析的工具



结果统计分析





5-1 Flexsim


功能结构图



Flex sim


提供了仿真模型与


ExpertFit

< br>与


Excel


的接口


,


用户可以同过


ExperFit


对输入数据


进行分布拟合


,


同时可以在


Excel


中方面地实现与仿真模型之间的数据交换


,


包括输出与运行


模型过程中动态修改运行参数等。另外该软件还 提供了优化模块


Optquest,


增加了帮助迅速

< p>
建模的


Microsoft Visio


的接口





5



1



1 Flexsim


软件的主要特点



Fl exsim


仿真软件的特点主要体现在


采用面向对象技术


,


突出


3D


显示效果


,


建模与调试简


单开放方便

< p>
,


模型的扩展性强


,


易于 与其她软件配合使用


等方面。




1




基于面向对象技术建模



Flexsi m


中所有用来建立模型的资源都就是对象


,

包括模型、


表格、记录、


GUI


等 。同时


,


用户可以根据自己行业与领域特点

,


扩展对象


,


构建自己的对象库。 面向对象的建模技术


使得


Flexsim


的建模过程生产线化


,


对象可以重复利用

,


从而减少了建模人员的重复劳动。




2




突出的


3D


图形显示功能

< br>


Flexsim


支持


Open GL


技术


,


也支持

3ds



wrl



dxf



stl


等文件格式。 因此用户可以建立


Flexsim


中的重要概念及开发技术



逼真的模型


,


从 而可以帮助用户对模型有一个直观的认识


,


并帮助模型的验证。 用户可以在仿


真环境下很容易地操控


3D


模型


,


从不同角度、放大或缩小来观测。



3




建模与调试的方便



建模过程中用户只 需要从模型库中拖入已有的模型


,


根据模型的逻辑关系进行连接


,


然后


设定不同对象的属性。


建模的工作简单快捷


,


不需要编写程序





4




建模的扩展性强



Flexsim


支持建立用户定制对象


,


融合了

< p>
C++


编程。


用户完全可以将其

< br>当作一个


C++


的开


发平台来开 发一定的仿真应用程序





5




开放性好



提供了与外部软件的接口< /p>


,


可以通过


ODBC

与外部数据库相连


,


通过


sock et


接口与外部硬


件设备相连


,



Excel



Vi sio


等软件配合使用。




5



2 Flexsim


的一些重要概念



Fl exsim


就是目前国内最新的仿真软件


,

关于该软件的资料与使用经验还很少。


作者就是


在不断的摸 索中学习的


,


所以希望本文能对其她人有一定的借鉴。


要完全掌握好


Flexsim,


并将

< p>
其用到我们的工作、学习与研究当中


,


理解该软件 的一些重要概念与思想就是很重要的


,


本节


对集装箱码头建模仿真中用到的技术做一个梳理





5


< p>
2



1


面向对象的思想



相对于目前的一些仿 真软件


(



Witness,


eM-Plant



),Flexsi m


就是采用面向对象思想与


技术开发的


,


其本身更就是用


C++


语言实现。严 格地说该仿真软件


包括了两部分


,


仿真 软件与


后台支持环境


VC++



NET



由于


C++


就是一种面向对象的语言


,


所以使用< /p>


Flexsim


软件


,

< br>从用


户用于系统建模


,


或就是做 一些二次开发


,


这些工作都有面向对象思想的体现。可以这样说


,


没有领会面向对象的思想


,


就不能完全发挥


Flexsim


软件本身的特点


,


也就不能用其实现用户


的目的。使用


Flexsim


软件的用户需要对


C+ +


语言有一定程度的熟悉。本节主要就是解释


Flexsim< /p>


中所特有的一些面向对象思想


,


而不涉及 面向对象语言的解释


(


关于


C++


语言的知识


请查瞧相关书籍


)




对象


(Object)


的概念在


Flexsim


软件中无处不 在


,


我们先直观的感受一下。软件的运行界

面左边就是一个常用的对象库


(


如图


5-1)


。库中的各种部件就就是有特定功能的对象


,


这些对


象就是软件本身自带的


,


使用这些基本的部件对象用户可以完成大多数的仿真工作。我们使



Processor


来解释一下对象的概念


:< /p>


我们


日常所见的任何具体事物都可瞧作就是对象

< br>,


这里


Processor


就就 是一种设备


,


它的作用就就是对经过她的物件进行一些加工


,


即改变物件的状


态。这里我们可以将其当 作现实中的设备


,


如机床等。



Flexsim


中的重要概念及开发技术





5-1


这里我们借用


C++


程序设计语言中的对象的概念。

< p>
对象就是类的实例


,


类就是对现实对


象的抽象。类中包含了对象的数据


(


相当于现实对象 的状态


),


以及对象的方法


(


相当于现实对


象用来处理外界所给信息的方法


)


。对象封装了属性与方法


,


进一步到< /p>


Flexsim



,

对于软件中


可用的库对象


,


她们本 身有


自己的属性


(


如颜色


,


尺寸


,


位置等

< p>
)


,


还有处理物件的方法。在使用软


件的过程中


,


我们完全可以以人们平时的思维方式来 思考


,


而无须过多的抽象化


,


这也就就是


面向对象方法的优点。




5



2



2 Flexsim


的对象层次结构



面向 对象方法的一个优点就是


类与类之间可以有继承关系


,


对象的继承性给我们提供了


更大的柔性来扩展我们自己的对象

< p>
,


即衍生出新的对象。



Flexsim


中我们可以充分利用继承


性来开发我们自己的对 象


,


而软件本身也给用户提供了这样的机制。

< br>Flexsim


本身的库对象就


是高度抽象化的


,


具有很强的通用性


,


几乎涵盖了仿真中可能遇到的所有对象。这些对象之间


有一定的继承关系


,


她们之间存在着逻辑关系。


下图

(



5-2)


就是


Flexsim


中对象的层次结构。



Flexsim


中的重要概念及开发技术



FlexsimObject


FixedResource


Dispatcher


Navigator


NetworkNode


Source


Queue


Sink


Conveyor


Rack


Reservoir


FixedSourceTemplate


Processor


TaskExecuter


NetworkNavigator


CraneNavigator


Operator


Transpoter


Crane


ASRSvehicle


BasicTE


BasicRF


Combiner


Separator



从类的派生关 系图中我们可以对


Flexsim


中各种对象的逻辑关系一目了 然。


对象库中的


对象分为两种


,


一种就是从


FixedResource


中派 生下来的


,


另一种就是


TaskExe cuter


中派生下来


的。


通过分析我 们不难发现


,



FixedResou rce


中派生来的对象有一个共同的特点


,

其本身就是


不会运动的


,


她们的作 用只就是


产生或消除物件、存储物件、加工物件等等


;



TaskExecuter


中派生的对象


,


其本身就是可以运动的


,


其作用


就是将物件从一个地点运送到另一个地点。


< /p>


当现有的库对象不能满足用户的需要时


,


用户就需要创建自己的对象。


Flexsim


为用户提


供了这样一种机制——用户可以定制自己的库对象。在对象层次图中


,< /p>


我们瞧到有两个虚线



,


这表示用户可以从


FixedResource



TaskExecuter


中派生出自己的对象。

< br>Flexsim


的早期


版本中从这两个类中派生新的对象 比较复杂


,


最新的


3

< br>、


06


版中增加了


BasicF R



BasicTE



,


使用户的开发工作更容易。后


面的章节中将具体介绍 怎样来实现一个新对象的定制。



5



2



3


节点与树



在介绍树结构之前


,


我们先来了解


Flexsim


中节点


(node)


的概念。



节点就是树结构的最基本的组成单元


,


她们组成了链接的层次。所有的节点都有一个文


本缓冲区


,


用来保存节点的名字。节点可以就是其她节点的容器


,


可以就是用来定义一个对象



Flexsim


中的重要概念及开发技术



属性的关键字


,


或就是拥有一个数据项。属于一个节点的数据项类型可能就是


:


数值


(number),


字符串


(string),


对象


(object),


或指针


(pointer)




下面列出


FLexsi m


中不同类型的节点标志


:


标准


(Standard):



对象


(Object):



属性


/


变量


(Attr ibute/Varibale):



函数


(Function(C++)):



函数


(Function(FlexScript)):



用户可以在对象的树结构中任意地操作节点

< br>,


例如增加节点


,


删除节点


,


改变节点所包含


的值等。含有对象数据< /p>


(Object)


的节点可能包含有节点的子列表。含有对象数据 的节点称之


为对象节点。当您单击一个对象节点



,


您会瞧到在节点的左边有一个大于号


(>)


。单击


>


将打开对象数据的树分支。


如果一个节点包含子节点


,


可以按下

< p>
+


按钮来展开。


如果一个节点

包含对象数据


,


可以按下


>


来展开。



下图


(< /p>



5-3)


展示了一个队列


(Queue)


展开的对象数据树。





5-3




树结构


(tree)


就是一种很常用的数据结构。


Flexsim


仿真模型 中的对象


,


或对象中的属性与


方法节点 等都就是树结构


;


用户甚至可以直接在树结构中操作对象。



Flexsim


中有两个主要

< p>
的对象类型


:


模型


(Mo del)


或仿真对象


(Simulation


Object)


与视图对象


(View


Object)


。两种类型


都有对象数 据树


,


包含了属性与行为控件。一个对象节点的对象数据树中的 节点可以作为属


性、变量或成员函数。也有只就是作为简单的容器来包含节点以达到组织 的目的。



5



2



4


任务序列



任务序列


(Task Sequences)

< br>就是


Flexsim


仿真软件中的核心机制。

< p>
各种复杂仿真的实现很


大程度取决于怎样实现任务序列。前面介绍了


Flexsim


中有两种对象


,


一种就是派生至


FixedResource


的静态 对象


(


即对象本身不运动


);


另一种就是派生至


TaskExecuter


的 动态对象


(


即对象本身可运动


)



如果用户建立的系统模型全部使用了静态对象


,


那么就不需要任务序列


Flexsim

中的重要概念及开发技术



的机制


,


但就是这种情况几乎没有。


使用动态对象搬运物件

< p>
,


对象怎样运动


,


实现什 么样的功能



,


这就需要。

< p>


任务序列就是由


TaskExecuter


执行的一组命令序列。


这里


TaskExe cuter


涵盖了所有派生


自她的动态对象

,



Operators,Transpoters,Cr ane,ASRSvehicle,Robots,Elevators


以及其她可运< /p>


动的对象。图


1-4


表示一个任务序列< /p>


,


该任务序列有多个任务组成。



Simulation Time


P1




P2






Task1










Task2










Task3









Task4











P1: Priority Value


P2: Preempt Value



1-4

Flexsim




< p>
















的< /p>







:TASKTYPE_TRA


VEL



TASKTYPE_LOAD


< p>
TASKTYPE_UNLOAD



TASKTY PE_TRA


VELTOLOC


等。不同的任务序列有不同的设 置参数


,


用户可以根据需要在


使用的时 候查询帮助文档。



5



2



4


< br>1


默认任务序列



Fixed Resource


为了将物件


(item)

移至下一个站点


(station),


有一个创建任务序列 的默认机


制。


FixedResource

对象的参数对话框中一个通用的“


Flow


”选项页


,


选择其中的“


Use

Transport


”复选框


,


这 样就可创建默认的任务序列。对于


Processor


对象


,


还可以自动创建对


Setup time/Process time/Repair operation


的任务序列。



当 仿真运行时


,


这些自动创建的任务序列就会传递给与其中心端口 相连的动态对象来执


行。这里给个简单的例子说明。假设用户选择了

Queue


对象参数对话框的“


Flow

< br>”选项页


中的“


Use Transport

< p>
”复选框


,


当系统运行时


,


产生了如下任务序列


:


P1




P2






Travel










Load









Break










Travel









Unload



< br>Operator


收到该任务序列时


,

< br>顺序地执行任务序列中的每个任务


,


执行过程如



:Operator


先移动到


Queue



(Travel);

接着拿起物件


(Load);


然后移动到下一个站点处


(Travel);


最后放下物件


(Unl oad)




在仿真运行的任意时刻< /p>


,


一个


TaskExecuter


只能执行一个任务序列


,


而此时


FixedResource


可能创建了许多任务序列


,


这些未执行的任务序列被放置在缓存队列中等待执行。




5



2



4



2


定制任务序列



一般情况下

< p>
,


默认的任务序列就可以满足仿真要求。


有时候用 户需要为某些特定的工艺、


多个设备的组合操控灯定制任务序列。这里分三种介绍定制任 务序列


,


第一种就是创建最简


单的、只 分配给一个对象执行的任务序列


;


第二种就是由多个对象协同作 业的任务序列。



?



定制简单任务序列



使用


3


条命令来创立任务序列


,


命令执行的顺序如下


:



Flexs im


中的重要概念及开发技术



cre ateemptytasksequence(



);


inserttask(



);


dispatchtasksequence(


< br>);


从函数名就可以瞧出创建任务序列的过程。首先创立一个空的任务序列


,


然后在此任务


序列中插入具体的任务


,


最后发布该任务序列。


我们举个简单的例 子


,


叉车运动到集装箱旁边


,


然后装载集装箱。在这个过程中


,


涉及了两个任 务


:


运动


(TASKTYPE_TRA


VEL)


与装载


(TASKTYPE_ LOAD)


。具体实现如下


:


fsnode* new_ts = createemptytasksequence(forklift, 0, 0);


inserttask(new_ts, TASKTYPE_TRA


VEL, station);


inserttask(new_ts, TASKTYPE_LOAD, item, station, 2);


dispatchtasksequence(new_ts);

这里叉车


(forklift)


就是任务序列的执行者


,


我们为其创建了一个新任务序列


(new _ts),


在此任务


序列中插入具体的任务

(TRA


VEL/LOAD),


最后发布任务序列。



我们在创建新任务序列时


,createe mptytaskseqence


函数的第一个参数


forkl ift


可以就是该


任务序列的执行者


,


或者就是


Dispatcher


对象。


关于


Dispatcher


对象的作用 下一小节有具体的


介绍。后两者参数决定了该任务序列的优先级别


,


我们可以根据任务的紧急程度来定义任务


序列的执行顺序。



Inserttask


函数插入具体 的任务类型。第一个参数表示该任务所属的任务序列。前面提


过不


同的任务类


型有着不同


的代码


,


以及不同的参数


选择。这些


参数分别就



:Task


Type/involve d1/involved2/var1/var2/var3,


有些参数就是选择性的< /p>


,


这要根据任务类型来决定。


这里以


TASKTYPE_LOAD


为例


,



1-5


表示了不同参数的意义。

< p>
用户可以根据所示规则查询


具体的任务的参数选项。



P1




P2






TRA


VEL








LOAD


Task Type: LOAD


Involoved1: bject to load


?


item


Involoved2 : object to load from


?


station


Var1 : output port


?


2


Var2 : 0 (


默认值


)


Var3 : 0 (


默认值


)




1-5


任务


Load


的参数含义




?



协同作业的任务序列



协同作业的情况 有很多


,


比如叉车作业需要一个司机来操控

,


或者一件物品需要两个人来


Flexsim


中的重要概念及开发技术



同时搬运等。

< p>


Flexsim


中叉车、


人都就是可运动对象


,


要实现协同作业的任务序列相对于只< /p>


对一个对象创建任务序列要复杂许多。


我们以叉车与司机的协同工 作为例来说明怎样实现协


同作业的任务序列。



我们先来分解任务的执行过程


:1)


人运动到叉车上< /p>


(Travel);2)


人进入驾驶室


(


这里就是叉


车的动作


)(Load); 3)


叉车运动到指定地点


(Travel);4)


叉车装载货物


(Load);5)


叉车运动到卸载点


(Travel);6)


卸载货物


(U nload)


。图


1-6


就是叉车与人 的任务序列。



Forklift


P



P








Wait








Load




Travel



Load



Travel



Unload


Operator


P



P



Travel to forklift















Wait




1-6


协同任务序列



从图中可以瞧出


,


叉车在人到达之后才执行任务


,

< p>
人进入叉车之后就随着叉车一起完成叉


车的任务。人的任务序列中只有一个 任务


,


其她时间不做任何事情。




Flexsim


中实现的代码要复杂一些


,


调用的函数与前面所讲的函数不同。


涉及的函数主


要有


:


createc oordinatedtasksequence(



); < /p>


insertallocatetask(


);


insertproxytask(



);


insertsynctask(



);


insertdeallocatetask(

< br>…


);


dispatchcoordinatedta sksequence(



);


一个 协同作业的任务序列的定制就是很复杂


,


也就是很容易出错的。 在开始实现之前必


须分析清楚作业的过程。对于前面人操控叉车的例子我们已经将作业流 程分析清楚了


,


下面


就是具体的实现< /p>


,


我将每个函数的功能写在程序的注释当中。


//


创建协同任务序列



fsnode * myts = createcoordinatedtasksequence(operatorteam);


//


为每个执行对象分配任务



int opkey = insertallocatetask(myts, operatorteam, 0, 0);


int forkliftkey = insertallocatetask(myts, forkliftteam, 0,0);


//


人的分派任务序列



int traveltask = insertproxytask(myts, opkey,


TASKTYPE_TRA


VEL, forkliftkey, NULL);


insertsynctask(myts, traveltask);


//


叉车的分派任务序列



insertproxytask(myts, forkliftkey, TASKTYPE_MOVEOBJECT, opkey, forkliftkey);


insertproxytask(myts, forkliftkey, TASKTYPE_TRA


VEL, loadstation, NULL);


insertproxytask(myts, forkliftkey, TASKTYPE_LOAD, item, loadstation);


insertproxytask(myts, forkliftkey, TASKTYPE_TRA


VEL, unloadstation, NULL);


insertproxytask(myts, forkliftkey, TASKTYPE_UNLOAD, item, unloadstation);


//


释放分派的任务序列



insertdeallocatetask(myts, forkliftkey);


insertdeallocatetask(myts, opkey);


Flexsim


中的重要概念及开发技术



//


发布协同任务序列



dispatchcoordinatedtasksequence(myts);



5



2



4



3


对象


Dispatcher


及任务序列的分配 规则



现在考虑一种较为复杂的情况


:


有两个


Queue


对象用于存放物件< /p>


,


三个


Operator


对象用于


搬运物件


;


三个


Operator


就是自由的


,

< p>
没有被分配给固定的


Queue,


那么怎样来有效 地调用这三



Operator


呢?此 时就要用到


Dispatcher


对象。



Dispatcher


用来控制一组


Transporter



Operator


。任务序列从一个静态对象发送到


Dispatcher,

然后


Dispatcher


来调配这些任务序列分配给与其 输出端口相连的动态对象。动态


对象接收到任务序列后执行相应的命令序列。

< p>


Dispatcher


对象的功能就就是将任务 序列进行队列存储与发送任务序列。根据用户建模


的逻辑


,


任务序列可以被排队等待或就是立即传送个相应的对象。


Dispa tcher


的参数设置对话


框只有两项


,


当接收到一个任务序列时


,


调用“< /p>


Pass To


”函数。顾名思义


,


该函数将任务序列发



< br>接





;












0,






< p>








,






QueueStrategy


”定义的规则将任务序列放入队 列中等候。


QueueStrategy


函数返回任务序


列的相关值


,


然后根据优先级来确定任务序列 在队列中的位置。高优先级的任务序列放在队


列的前面


,


低优先级的放在队列的后面。如果优先级相同


,


则根据队列的先进先出


(FIFO)


原则

来处理。用户可以根据需要


,


动态的改变任务序列的优先级 。



当将队列中的任务序列进行排序时


,Dispatcher


执行队列策略函数


,

< br>遍历取得已有任务序


列的优先级值


,

与最新的任务序列优先级值比较


,


根据比较的结果重新进行 队列排序。




Flexsim


对象层次图中


,


我们发现

Dispatcher


就是所有


TaskExecuter


的父类


,


也就就是说

< br>所有的


TaskExecuter


也就是


Dispatcher


。这就意味着


Operator



Transporter


也可以担当


Dispatcher


的角色来分配任务序列

< br>,


或者就是自己执行任务序列。




5



2



4



4 Dis patcher



TaskExecuter

< br>的区别



在仿真执行的任意时刻


,


即使任务序列的等候队列中多个任务序列


,TaskExec uter


一次只


能执行一个任务序列。



Dispatcher


对象的作用只就是在缓存队列中存放已 排序好任务序列


,


并将队列最前面的任务序列发送给动态对象< /p>


,


但并不执行任务序列。




5



2



4



5


利用任务序列实现集装箱的装卸过程



在集装箱码头的作业的过程中


,


集卡行驶到岸桥设备处等待装箱


,


岸桥将集装箱从船上卸


下装到已等待 的集卡上


;


装箱后的集卡行驶到堆场中


,


场桥将集装箱从集卡上卸下


,


堆放到 堆


场中。集装箱从船到堆场的过程中


,


经过了集卡、岸桥、场桥等设备的搬运


,


Flexsim


中就


需要使用任务序列来完成这个过程。< /p>



这里涉及了三个可运动对象


:


集卡、岸桥与场桥。这里设计的思路就是这样的


,


集装箱的


运输由集卡来实现


,


这样集 卡就有这样一个任务序列


:Travel


?


Load


?


Travel


?


Unload


。集


装箱装入集卡的作业由岸桥设备完成


,


卸载放入堆场的 作业由场桥设备完成


,


所以集卡的任务


序列中


Load/Unload


的任务就应该由岸桥与场桥来完 成。



岸桥完成一次作业的过程也就就是完成一个任务序列的过 程


,


可以知道岸桥完成的任务


Flex sim


中的重要概念及开发技术



序列应该就是


:Travel


?


Load


?


Travel


?


Unload


。岸桥在作业的过程 中


,


集卡处于等待的状



,


也就就是说岸桥与集卡之间就是协同作业的。场桥的情况与岸桥一致。


Flexsim


中可以使


用调用子任务的方 法将岸桥与场桥的任务序列插入到集卡的任务序列中。



1-7


表示了主任


务序列与子任务序列之间的关系。

< br>


集卡主任务序列



Travel


Load


Travel


Unload


岸桥子任务序列



Travel


Load


Travel


Unload


场桥子任务序列



Travel


Load


Travel


Unload




1-7


集装箱搬运过程的任务序列












Flexsim


中的实现的主要代码如下


,


其关键的代码在文中有注释


:


//


获取任务序列中的任务数量



int nroftasks = gettotalnroftasks(tasksequence);


//


查找


Load/Unload


任务


,


找到之后调用子任务来替换这两个任务



for(int i=1; i<=nroftasks; i++)


{



int tasktype = gettasktype(tasksequence, i);



switch(tasktype)



{




case TASKTYPE_LOAD:




case TASKTYPE_FRLOAD:




{





int msgtype = (tasktype == TASKTYPE_LOAD ? 1 : 2);


// changetask(



)


函数会发 出一个消息


(message),


我们在消息的接受者的


OnMessage(



)

< br>函



//


数中创建岸桥与叉车的子任务序列






changetask(tasksequence, i, TASKTYPE_CALLSUBTASKS, current, NULL,


msgtype, tonum(gettaskinvolved(tasksequence, i, 1)), tonum(gettaskinvolved(tasksequence, i, 2)),


gettaskvariable(tasksequence, i, 1));




}




break;

-


-


-


-


-


-


-


-



本文更新与2021-02-10 20:03,由作者提供,不代表本网站立场,转载请注明出处:https://www.bjmy2z.cn/gaokao/631389.html

Flexsim中的重要概念及开发技术的相关文章