全球FlexSim系统仿真中文论坛

标题: 案例八 全局列表:调度距离最近的多载AGV,AGV满载后才去卸货 [打印本页]

作者: Yumaotuo    时间: 2018-5-4 09:36
标题: 案例八 全局列表:调度距离最近的多载AGV,AGV满载后才去卸货
本帖最后由 Yumaotuo 于 2018-5-4 09:37 编辑

1、模型描述

此案例是一个多载AGV调度模型的简化模型,AGV容量为3,产品加工完毕后由AGV搬运至卸货点,各个加工台在加工结束后呼叫距离自己最近的AGV执行搬运任务,并且AGV装满3个货物之后才去卸货点卸货。

2、模型布局

[attach]4354[/attach]

模型中有6台处理器在加工完产品后需要请求AGV过来搬运,搭建AGV路径网络,并在交叉路口放置控制区域进行基本的避碰。
发生器A连接6台处理器,并在发生器设置随机可用端口;
6台处理器A连接卸载区的暂存区;
处理器、暂存区和AGV全部A连接至路径网络;

3、逻辑设置

写入任务执行器列表

在AGV的自定义绘图触发器中,将未满载的AGV写入任务执行器列表
if (current.subnodes.length<3) //当AGV装载货物没满三个的时候
{
        string listName = "TEList1";
        List(listName).push(current, 0);//把自己推入任务执行器列表等待被占用

}
从任务执行器列表中拉入

在处理器的使用运输工具下拉列表选择使用列表中的从任务执行器列表中拉入,并选择ORDER BY distance ASC,即按任务执行器离当前处理器的距离按升序排序。所有处理器执行同样的操作。

[attach]4355[/attach]

实现满载后才卸货

完成上两步后可以实现处理器调用最近的AGV执行任务,但是不能实现装满3个后再去卸载。完成上两步之后打开处理器的使用运输工具的代码编辑框,在下面红字标注处作简单的修改即可。
if (true) {
        int callbackCase = param(5);
        #define CALLBACK_CASE 10293
        treenode pulled = 0;
        treenode ts = 0;
        if (callbackCase != CALLBACK_CASE) {
                ts = createemptytasksequence(assertattribute(current, "stored", 0), priority, preempt);

                inserttask(ts,TASKTYPE_TRAVEL, current, NULL);
                inserttask(ts,TASKTYPE_LOAD, item, current, port);

                inserttask(ts,TASKTYPE_BREAK, NULL, NULL);
//删去原有的卸载任务序列
                string listName = "TEList1";
                List list = List(listName);
                string queryStr = "ORDER BY distance ASC";
                Variant partitionId = 0;
                int removeFromList = 1;
                int addToBackOrders = 1;
                pulled = list.pull(queryStr, 1, addToBackOrders ? 1 : 0, ts, partitionId, (removeFromList ? 0 : LIST_DO_NOT_REMOVE) | LIST_RETURN_BACK_ORDER_IF_NOT_FULFILL);
                if (isclasstype(pulled, "ListBackOrder"))
                        eventlisten(pulled, "OnFulfill", c, 0, LIST_ON_FULFILL_VALUE, ts, 0, 0, CALLBACK_CASE);
                else if (objectexists(pulled)) {

                        movetasksequence(ts, pulled);
//装载第3个box后加入卸载任务序列,注意此处任务序列生成的时候AGV上只有两个货物,
pulled.subnodes.length等于2,不能把第三个货物也卸载掉
                                if(pulled.subnodes.length==2)
                        {
                                inserttask(ts,TASKTYPE_TRAVEL, destination, NULL);
                                for(int i=1;i<=pulled.subnodes.length;i++)
                                {
                                        inserttask(ts,TASKTYPE_UNLOAD,pulled.subnodes,destination);
         }
                        }
                        dispatchtasksequence(ts);
                }
        } else {
                pulled = param(1);
                ts = param(2);
                if (objectexists(pulled)) {
                        movetasksequence(ts, pulled);
                        dispatchtasksequence(ts);
                }
        }                                                        
}

return 0;

AGV上的货全部卸完

[attach]4356[/attach]

在卸货处的控制点触发写入以下代码:
Object que1  = model().find("Queue1");
for(int index=1;index<=te.subnodes.length;index++)
{
        moveobject(te.subnodes[index],que1);
}
这个模型适用于多台多载AGV同时作业,满足就近调度和满载而归的基本调度逻辑。


作者: 慧娴亚伦    时间: 2018-5-4 13:08
个人不是很推荐这个方法来实现,因为能够使用list功能的版本,肯定能够使用processflow,同样的条件下,使用pf完成更容易而且也更能够适应模型需求的修改。
作者: 滴水藏海028    时间: 2019-11-26 22:47

看起来有点复杂,研究一下,谢谢分享




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