欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

FlexSim实战练习(二)——多品种小批量订单拣选作业

发布时间:2024/1/1 80 豆豆
生活随笔 收集整理的这篇文章主要介绍了 FlexSim实战练习(二)——多品种小批量订单拣选作业 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

FlexSim实战练习(二)

提示:这里需要用到脚本函数有两个

  • Array.splic(int fromindex,int count)
  • Array.splic(int fromindex,int count,Array insert())
Array cars = ["Volvo","BMW","Audi","Ford"]; cars.splice(2,2); // ["Volvo", "Ford"] cars.splice(3, 1, ["Lotus", "Kia"]); // ["Volvo", "BMW", "Lotus", "Kia", "Ford"]

Array.append(Array otherArray)

Array myArray = [1,2,3,4,5]; myArray.append([7,8,9]); //[1,2,3,4,5,7,8,9]

以上FlexSim软件版本为19版。


1、案例背景及3D布局说明

如图所示,系统会按照时间表(Arrival Schedule)生成不同类型的产品。 首先,根据产品类型分别进入对应的两个传送带上; 然后,根据产品的批次在合成器上进行合成; 最后,进入到一个暂存区进行缓存,等待订单计划下达。

产品到达

其中,ID表示产品编号,Type表示产品类型,B_ID表示产品一批次的数量。

这张图表示,一共有4种类型的订单(该全局表名称“info”),其中类型1订单需要{ST101,ST102,ST103,ST104}共4种产品组成,类型2,、类型3以及类型4订单如图所示。


2、详细流程图文解释

在整个仿真项目流程中,一共可以分为三个部分:

  • 产品在发生器上产生,通过传送带进入合成器进行合成批次,最后进入缓存区等待订单下达;
  • 订单下达指令;
  • 订单下达后,操作员就会前往缓存区,对缓存区上的产品进行刷选,选择下达订单需要的产品搬运至放有tote的暂存区上进行订单组成。当满足订单需求后,操作员就会搬运该订单前往中转场。

第一步

完成后,你的模型布局应该类似于上图。
具体操作如下:

  • 从Library模型库中拖出3个Source,4个Queue,2个Straight Conveyor,2个Combiner;
  • 按照图中连线方式进行"A"链接;
  • 注意,2个Source、2个Queue与2个Combiner链接时,必须要Source首先链接到Combiner,且2个Source都产生Pallet.

  • 2个Conveyor的上游Queue,双击打开,找到send to port,并选择By Expression>item.Type;
  • 选择一个Combiner,在进入触发和离开触发中,写上代码如下:
  • //进入触发 if (port == 2) { int de=item.B_ID;Table thelist = getvarnode(current, "componentlist");treenode thesum = getvarnode(current, "targetcomponentsum");// thesum.value = 0;for(int index = 1; index <= thelist.numRows; index++) {thelist[index][1] = item.B_ID;//inc(thesum, item.B_ID);} } //离开触发 item.labels.assert("B_ID").value = item.first.B_ID; item.labels.assert("ID").value = item.first.ID; //把产品上的标识赋值给下面的托盘。
  • 对combiner下游的Queue,在进入触发里设置Push to List1,并打开List1列表,进行如下的设置;

    以上是"第一部分"流程的所有活动。


  • 第二步

    具体操作如下:

  • 从库中将以下实体添加到model中:
    (1)1个 Source
    (2)1个Queue
    (3) 1个"Operator1"
  • 将Source和Queue进行"A"链接;
  • 在Queue的进入触发上,写上如下代码:
  • treenode OP=Model.find("Operator1"); senddelayedmessage(OP,0,current,item.Order,0,0);//item.Order对应的是订单编号

    应该会有人问,这第二步的作用是什么。它的作用就是:利用发生器按时间间隔发送一个Box到Queue上,使进入触发的代码被触发,这一个流程来模拟"订单下发"动作。
    Source的设置可以参考我的,当然,你也可以自己编写。

    以上是"第二部分"流程的所有活动。


    第三步

  • 从库中将以下实体添加到"model中:
    (1)1个 Source;
    (2)12个Queu;
    (3)1个BasicFR;
  • 按照文章第一张图布局的样子,对Source与1个Queue进行"A"链接,同时,Queue与另外10个Queue进行"A"链接;
  • 对下游10个Queue的进入触发中设置Push to List1:
  • if(true) {string listName = "List1";List(listName).push(item,2);}
  • Process Flow>Add a general Process Flow,最终流程图样如下:
  • 以下操作都将在Process Flow 上进行:
    (1)拉入1个事件监听的发生器,并用吸管吸取操作员的On Message,同时在Msg Param1这一行,写入"Order",并选择assign,Order表示订单编号。
    (2)拉入1个Pull form List 和1个List,通过Pull form List右边的感叹号与List进行链接。打开Pull form List,在Assign to 中写入token.Pallet,并在Partition ID填入2,表示为拉入的token.Pallet是10个Queue进入的Tote。
    (3)拉入2个Assign Labels,并分别命名为“goal_01”和“Array”。goal_01的作用是获取当前下达订单对应需要几种产品,因此,代码为Table("info").cell(token.Order,1).as(Table).numRows。Array的作用是将当前订单对应的产品编号,通过数组的形式存储到对应的Queue上,即up(token.Pallet)。代码如下:

    Table dd=Table("info").cell(token.Order,1); Array Save =up(token.Pallet).as(Object).save; for(int i=1;i<=token.goal;i++) {string name=dd.cell(i,1).value;Save.append([name]); }return Save;
  • 拉入1个Assign Labels,并命名为“OP”,用于将model中的操作员以及中转场进行赋值。
  • 拉入1个Assign Labels:“goal_02”,1个Wait for event,1个Delay,1个Decide,并进行连线,如图所示。

    这里,goal_02的作用是获取进入缓存区的产品数量Queue_Num=token.Q_01.subnodes.length,在Decide中进行判断token.Queue_Num >=1,如果成立,token就会顺着直线往下走;否则,token就会前往Wait for event等待并监听缓存区有产品进入后,再次判断token.Queue_Num >=1是否成立。
  • 拉入1个Custom Code,1个Assign Labels,1个Delay,1个Decide,并进行连线,如图所示。

    其中Custom Code的代码如下:
  • treenode BF=Model.find("BasicFR1");//就是之前拉入的BasicFR,这边需要注意名字要一样,或者改成你model中BF的名字; int Queue_num=token.Q_01.subnodes.length;//再次获取缓存区中产品的数量值,确定for循环的次数。 Array save_item=Model.find("BasicFR1").save_item;//获取BF上的Array数组(以下简称BF); Array Save=up(token.Pallet).save;//获取Tote存放的Queue上的Array数组(以下简称Qu); for(int i=1;i<=Queue_num;i++) {treenode item=token.Q_01.subnodes[i];string item_id=item.ID;for(int j=1;j<=Save.length;j++){string order_id=Save[j];if(item_id==order_id)//如果缓存区中有产品属于当前订单组成部分,则把Qu中该产品编号从数组中剔除出去,并在BF中添加被剔除的产品编号{Save.splice(j,1);save_item.append([order_id]);break;}} } int array_num=save_item.length; if(array_num == 4)//获取BF数组长度,如果长度==4,说明目前产品已满足订单需求;如果长度==0,说明目前产品不属于该订单; {BF.panduan = 1; } else if(array_num ==0) {BF.panduan = 3; } else {BF.panduan = 2; }

    判断完毕后,将判断结果赋值给BasicFR的panduan标签。最后通过Decide把token送到对应的下游去。
    8. 这一步没有什么好讲的,主要是从BF上save_item存着需要搬运的订单组,以及订单组的长度save_item_L;


    9. 这里的代码需要注意的是,把BF上存放订单的Array("save_item ")清空,用于下个token进入时的保存。

    以上是第三步的所有活动。


    总结

    由于篇幅的限制,许多知识点无法详细说明,而且其中一些代码只适用于订单数量为4个的时候,存在优化的空间。

    总结

    以上是生活随笔为你收集整理的FlexSim实战练习(二)——多品种小批量订单拣选作业的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。