2018数模国赛B题 RGV动态调度 matlab程序 + 思路解析

        这次国赛整体比较顺利,由于对A题偏微分方程的知识所知甚少,出题当晚即确定了B题,并和队友讨论清楚了RGV的整个运转过程,差点没忍住当晚就开始写代码哈哈哈。第一天晚上粗略计算到带故障排除的一道工序情况,但直到第二天晚上才顺利解出并修正所有结果。此外,一定要规划好写作的内容和进度,得出的成果在论文中展现不出来就白搭。

        这次的赛题并不好套用智能算法,因此不妨尝试自己建立模型,整个RGV调度过程会很清晰地被模拟出来。以下是具体解题过程:

一. 几个审题关键点

1.分析RGV

        RGV有互斥的四种状态:移动、停止等待、上下料和清洗作业。

       上下料:在第一次操作时,在CNC上没有熟料时(即CNC未开始工作时),RGV只对其进行上料操作,但是由于两个机械爪是连在一个机械臂上的,下料操作也会被被执行。也就是说,RGV对CNC完成一次上下料的时间是固定的,而不管CNC上是否有熟料。

        清洗作业:清洗作业包括放熟料到清洗槽、取成料到下料传送带共两步(实际清洗时间可忽略)。在RGV在第一次进行清洗作业时,清洗槽内没有成料,但是由于两个机械爪是连在一个机械臂上的,取成料操作也会被执行。也就是说,RGV的清洗作业时间是固定的,而不管清洗槽内是否有成料。

        移动:题目中默认RGV只有在收到某CNC需求信号后,才会移动至该CNC处,对其进行上下料操作。

2.分析传送带

        由于上、下料传送带都既能连动,也能独立运动。因此CNC在从上料传送带取生料时、将成料放到下料传送带时,RGV均无需等待或移动,可直接操作。

 

二. 对一道工序CNC的分析求解

        首先,RGV根据距离就近原则选择下一操作的CNC。在RGV对所有CNC完成一次上料操作后,不断进行上下料->清洗作业->上下料…的循环操作。

        matlab代码如下,输出结果见case_1_result变量,可直接导入对应的Excel。

clear all;clc;
%cnc: 
% 第一行:cnc位置常量
% 第二行:cnc工作变量,空闲为0,忙碌为1
% 第三行:cnc工作时间,为常量560
% 第四行:cnc上下料时间
% 第五行:cnc预计完成时间
% 第六行:cnc加工物料数
cnc = load ('1_cnc_1.txt');
cnc(6,:)=-1;
%rgv:
% 第一行:rgv初始位置变量,初始为1
% 第二行:rgv工作变量,进行上下料或清洗作业,空闲为0,忙碌为1
% 第三行:rgv一次清洗作业时间
% 第四行:rgv预计完成时间
rgv = load ('1_rgv_1.txt');

%speedRgv:
%移动1~3个单位所需时间
speedRgv = load('1_speedRgv_1.txt');

case_1_result = (1:800)';
t = 0;
r = 1;  %仅计数用

while t <= 28800  %以秒为计数单位
    
    %1.在rgv和cnc均空闲状态下,找到距离最近的cnc编号
    dist = 4; 
    signal = 0;
        for i=1:8
            if cnc(2,i) == 0  %如果cnc空闲
                if abs(cnc(1,i)-rgv(1))<dist  %找到距离最近的cnc并返回cnc编号
                    dist = abs(cnc(1,i)-rgv(1));
                    cncNum = i;
                    value = cnc(1,i);  %记录cnc位置以传递给rgv
                    step = abs(cnc(1,i)-rgv(1));  %rgv走的步数的绝对值
                end
            end
        end
        if step ~= 0 && cnc(2,cncNum) == 0  %rgv移动到最近的cnc处
            t = t + speedRgv(step);
            rgv(1) = value;
            signal = 1;
        end
  
    %2.上下料和清洗操作
    if  cnc(2,cncNum) == 0
        cnc(2,cncNum) = 1; 
        rgv(2) = 1;  
        %记录加工cnc的编号
        case_1_result(r,2) = cncNum;
        case_1_result(r,3) = t;
        t = t + cnc(4,cncNum);  %上下料
        cnc(6,cncNum) = cnc(6,cncNum) + 1;
        signal = 1;
        cnc(5,cncNum) = t + cnc(3,cncNum);  %cnc预计完成时间=上下料+工作时间
        if cnc(5,cncNum) ~= 0
            t = t + rgv(3);  %清洗作业完成时间=上下料+清洗时间
        end
        r = r + 1; 
    end
    
    %3.更改cnc状态为空闲
    for i = 1:8
        if t >= cnc(5,i) && cnc(5,i) ~= 0
            cnc(2,i) = 0;
        end
    end

    if signal == 0
        t = t +1;
    %else
        %continue;
    end
    
end
 

%计算下料开始时间,即改cnc的下一次上料时间
for i = 1:800
    for j =i+1:800
        if case_1_result(i,2)==case_1_result(j,2)
            case_1_result(i,4)=case_1_result(j,3);
            break;
        end
    end
end
    

采用的是第一组数据,txt文件如下。第二、三组数据以同样格式生成即可。下同,不再赘述。

1_cnc_1.txt:
1	1	2	2	3	3	4	4
0	0	0	0	0	0	0	0
560	560	560	560	560	560	560	560
28	31	28	31	28	31	28	31
0       0       0       0       0       0       0       0

1_rgv_1.txt:
1
0
25
0

1_speedRgv_1.txt:
20
33
46

 

三.  对两道工序CNC的分析求解

        首先,将加工第一道工序的CNC记为A类CNC;加工第二道工序的CNC为B类CNC。RGV在对所有A类CNC进行一次上下料之后,不断进行A->B->A->B…的循环访问,即RGV从A类CNC处取到半熟料后,下一操作只能是对B类CNC进行上下料操作;RGV在清洗作业完成后,下一操作只能是对A类CNC进行上下料操作。对A、B类CNC的数目和位置分布,采用全排列暴力解决(运行时间较长,应再优化),找出A类和B类CNC的比例和在8个位置上最优的分布位置。

        matlab代码如下:

clear all;clc;

%全局搜索判优使用
%  ls = [1,2,3,4,5,6,7,8];
%  tmp = 0;
%  f = perms(ls);
%      for ii = 1:length(f)  
%          ls1 = f(ii,1:4);
%          ls2 = f(ii,5:8);

%做第一、二道工序的cnc:
ls1=[1,4,6,8];                                                  
ls2=[2,3,5,7];  
work1=400;
work2=378;

%%数据导入

%1.cnc: 
% 第一行:cnc位置常量
% 第二行:cnc工作变量,空闲为0,忙碌为1
% 第三行:cnc工作时间
% 第四行:cnc上下料时间
% 第五行:cnc预计完成时间
% 第六行:正在加工的物料编号
% 第七行:cnc是否初始判断,0为初始,1位正常
cnc = load ('2_cnc_1.txt');
for i=ls1
    cnc(3,i)=work1;
end
for i=ls2
    cnc(3,i)=work2;
end
%2.rgv:
% 第一行:rgv初始位置变量,初始为1
% 第二行:rgv工作变量,进行上下料或清洗作业,空闲为0,忙碌为1
% 第三行:rgv一次清洗作业时间
% 第四行:rgv预计完成时间
% 第五行:正在操作的物料编号
rgv = load ('2_rgv_1.txt');

%3.speedRgv:
%移动1~3个单位所需时间
speedRgv = load('2_speedRgv_1.txt');

case_1_result = (1:800)';
t = 0;
r = 1;  %计数
flag = 0;  %rgv上有半成品物料为1,没有为0;
while t <= 28800  %以秒为计数单位
    
    %1.在rgv和cnc均空闲状态下,找到距离最近的cnc,并让rgv移动过去
    % 第一道加工:
    dist = 4; signal = 0;
    for i=ls1
        if cnc(2,i) == 0 && flag == 0  %如果cnc空闲,rgv上没有半成品物料
            if abs(cnc(1,i)-rgv(1))<dist  %找到距离rgv最近的cnc并返回cnc编号
                dist = abs(cnc(1,i)-rgv(1));
                cncNum1 = i;
                value = cnc(1,i);
                step = abs(cnc(1,i)-rgv(1));
            end
        end
    end
    if step ~= 0 && cnc(2,cncNum1) == 0 && flag == 0 %rgv移动到最近的cnc处..若rgv在等待,rgv也将移动到最近的cnc处
        t = t + speedRgv(step);
        rgv(1) = value;
        signal = 1;
    end
    
  
    %2.rgv对第一道工序进行上下料操作
    if  cnc(2,cncNum1)==0 && flag == 0  %该cnc空闲,且rgv上没有半成品物料
        cnc(2,cncNum1) = 1;   
        %记录加工cnc的编号
        case_1_result(r,2) = cncNum1;
        case_1_result(r,3) = t;
        t = t + cnc(4,cncNum1);  %上下料
        signal = 1;
        cnc(7,cncNum1) = cnc(7,cncNum1) + 1;  %初始判定条件
        if cnc(7,cncNum1) > 1 %若该cnc不是初始化状态
            rgv(5) = cnc(6,cncNum1);  %记录rgv操作的前一个是哪一个物料
            flag = 1; % 表示rgv拿了一个物料
        end
        cnc(5,cncNum1) = t + cnc(3,cncNum1);  %cnc预计完成时间=上下料+工作时间
        cnc(6,cncNum1) = r;  %被加工物料的编号
        r = r + 1;
    end
    

    
    %3.rgv在第一道工序的cnc处取物料后,寻找最近的第二道工序cnc
    dist = 4;
    if cnc(7,cncNum1) > 1 && flag == 1  %如果第一道工序的cnc不是初始状态,且rgv携带了半成品物料
        for i=ls2
            if cnc(2,i) == 0  %如果第二道工序cnc空闲
                if abs(cnc(1,i)-rgv(1))<dist  %找到距离最近的cnc并返回cnc编号
                    dist = abs(cnc(1,i)-rgv(1));
                    cncNum2 = i;
                    value = cnc(1,i);
                    step2 = abs(cnc(1,i)-rgv(1));
                end
            end
        end
        if step2 ~= 0 && cnc(2,cncNum2)==0 %rgv移动到最近的第二道工序cnc处
            t = t + speedRgv(step2);
            rgv(1) = value;
            signal = 1;
        end
    end
    
    
    %4.rgv对第二道工序进行上下料操作
    if  cnc(7,cncNum1) > 1 && cnc(2,cncNum2)==0 && flag == 1  %第二道工序cnc空闲,第一道工序cnc不为初始状态,rgv上有半成品物料
        cnc(2,cncNum2) = 1; 
        flag = 0;
        %记录加工cnc的编号
        case_1_result(rgv(5),5) = cncNum2;
        case_1_result(rgv(5),6) = t;
        cnc(6,cncNum2) = rgv(5); %正在被加工物料的编号
        t = t + cnc(4,cncNum2);  %上下料
        signal = 1;
        cnc(5,cncNum2) = t + cnc(3,cncNum2);  %第二道工序cnc预计完成时间=上下料+工作时间
        if cnc(7,cncNum2) > 0 
            t = t + rgv(3);  %时间=上下料+清洗时间
        end
        cnc(7,cncNum2) = cnc(7,cncNum2) + 1;
    end
    
    
    %5.所有的cnc均忙碌,rgv在等待
    for i = 1:8
        if t >= cnc(5,i) && cnc(5,i) ~= 0
            cnc(2,i) = 0;
        end
    end
    
    if signal == 0
        t = t +1; %若rgv在原地等待
     else
         continue;
    end

end
 

%计算下料开始时间,即改cnc的下一次上料时间
for i = 1:800
    for j =i+1:800
        if case_1_result(i,2)==case_1_result(j,2)
            case_1_result(i,4)=case_1_result(j,3);
            break;
        end
    end
    for k =i+1:800
        if case_1_result(i,5)==case_1_result(k,5)
            case_1_result(i,7)=case_1_result(k,6);
            break;
        end
    end
end

%全局搜索判优使用
%   for i = 1:800
%       if case_1_result(i,7)==0
%           set = i;
%           break;
%       end
%   end   
%   if tmp<set   
%       tmp = set;
%       xx = ii;  %特征
%   end
% end
% disp('ls1:');
% disp(f(xx,1:4));
% disp('ls2:');
% disp(f(xx,5:8));

数据文件如下:

2_cnc_1.txt:
1	1	2	2	3	3	4	4
0	0	0	0	0	0	0	0
378	400	378	400	378	400	378	400
28	31	28	31	28	31	28	31
0       0       0       0       0       0       0       0
0       0       0       0       0       0       0       0
0       0       0       0       0       0       0       0

2_rgv_1.txt:
1
0
25
0
0

2_speedRgv_1.txt:
20
33
46

 

四.对带故障排除的CNC分析求解

        情况三要求考虑机器故障的情况,产生故障的实现方法如下,设置三个变量:1)可能故障时间t1:0到CNC加工完成一个一道工序的物料所需时间之间的随机整数;2)维修时间t2:600到1200之间的随机整数,对应10~20分钟维修时间;3)故障概率p:从均匀分布U(0,1)中随机取一个数小于等于0.01的概率,对应1%。

        每一次CNC运行前,判断若p发生,则CNC工作至t1时刻发生故障,再维修t2的时间后,该CNC再次以空闲状态投入使用,并记录本次操作的物料发生异常。

        由于代码重合度过高,此处只提供故障判断和处理的代码,添加到CNC上下料操作后即可。

if probability() == 1
            fault = unidrnd(cnc(3,1));  %在工作时间内随机产生一个时间点
            tBroken = 600 + unidrnd(600);  %维修时间在10~20分钟之间
            disp('发生故障!');
            r = r - 1;
            case_1_result(r,4) = inf;  %未正常下料标记
            case_1_result(r,6) = t + fault;  %故障开始时间
            case_1_result(r,7) = t + fault + tBroken;  %故障结束的时间
            case_1_result(r,5) = inf;  %发生故障的标志
            r = r + 1;
            cnc(5,cncNum) = t + fault + tBroken;  %cnc故障:cnc预计人工修理完成时间
        else
            cnc(5,cncNum) = t + cnc(3,cncNum);  %正常情况:cnc预计完成时间=上下料+工作时间
            cnc(6,cncNum) = cnc(6,cncNum) + 1;
        end
%百分之一概率生成函数
function [key] = probability()
R=rand(1,1000);
if(R(100)<=0.01)
    key = 1;
else
    key = 0;
end
end

 五.使用RGV预判建立预判模型

        默认情况下RGV收到CNC信号才会移动,因此提出基于RGV的预判模型,使RGV在等待时根据CNC工作情况,预先移动到下一要操作的CNC处,从而提高系统的运行效率。

        关于RGV在等待时选择下一操作CNC时的判断变量:

        S = RGV从当前位置移动到目标CNC处所花的时间t1 + 目标CNC的剩余完成时间t2。

        遍历每一个CNC,选出S值最小的CNC作为下一操作CNC。

以一道工序的情况为例,给出预判下的改进模型代码:

clear all;clc;
%cnc: 
% 第一行:cnc位置常量
% 第二行:cnc工作变量,空闲为0,忙碌为1
% 第三行:cnc工作时间,为常量560
% 第四行:cnc上下料时间
% 第五行:cnc预计完成时间
% 第六行:cnc加工物料数
cnc = load ('1_cnc_1.txt');
cnc(6,:)=-1;
%rgv:
% 第一行:rgv初始位置变量,初始为1
% 第二行:rgv工作变量,进行上下料或清洗作业,空闲为0,忙碌为1
% 第三行:rgv一次清洗作业时间
% 第四行:rgv预计完成时间
rgv = load ('1_rgv_1.txt');

%speedRgv:
%移动1~3个单位所需时间
speedRgv = load('1_speedRgv_1.txt');

case_1_result = (1:800)';
t = 0;
r = 1;  %仅计数用
wait = 0;
while t <= 28800  %以秒为计数单位
    
    %1.在rgv和cnc均空闲状态下,找到距离最近的cnc编号
    dist = 4; 
    signal = 0;
        for i=1:8
            if cnc(2,i) == 0  %如果cnc空闲
                if abs(cnc(1,i)-rgv(1))<dist  %找到距离最近的cnc并返回cnc编号
                    dist = abs(cnc(1,i)-rgv(1));
                    cncNum = i;
                    value = cnc(1,i);  %记录cnc位置以传递给rgv
                    step = abs(cnc(1,i)-rgv(1));  %rgv走的步数的绝对值
                end
            end
        end
        if step ~= 0 && cnc(2,cncNum) == 0  %rgv移动到最近的cnc处
            t = t + speedRgv(step);
            rgv(1) = value;
            signal = 1;
        end
        if wait == 1  %rgv在等待
            for i = 1:8
                step1 = abs(cnc(1,i)-rgv(1));
                if  step1 ~= 0
                    s(1,i) = speedRgv(step1);%第一行:运动时间
                else
                    s(1,i) = 0;
                end
                s(2,i) = cnc(5,i) - t;%第二行:剩余完成时间
                s(3,i) = s(1,i) + s(2,i);
                [minNum,line] = min(s(3,:));
            end
            t = t + s(1,line);
            rgv(1) = ceil(line/2);
            signal = 1;
            wait = 0;
        end
    %2.上下料和清洗操作
    if  cnc(2,cncNum) == 0
        cnc(2,cncNum) = 1; 
        rgv(2) = 1;  
        %记录加工cnc的编号
        case_1_result(r,2) = cncNum;
        case_1_result(r,3) = t;
        t = t + cnc(4,cncNum);  %上下料
        signal = 1;
        cnc(5,cncNum) = t + cnc(3,cncNum);  %cnc预计完成时间=上下料+工作时间
        cnc(6,cncNum) = cnc(6,cncNum) + 1; 
        if cnc(5,cncNum) ~= 0
            t = t + rgv(3);  %清洗作业完成时间=上下料+清洗时间
        end  
        r = r + 1; 
    end
    
    %3.更改cnc状态为空闲
    for i = 1:8
        if t >= cnc(5,i) && cnc(5,i) ~= 0
            cnc(2,i) = 0;
        end
    end

    if signal == 0
        t = t +1;
        wait = 1;
    else
        continue;
    end
    
end
 

%计算下料开始时间,即改cnc的下一次上料时间
for i = 1:800
    for j =i+1:800
        if case_1_result(i,2)==case_1_result(j,2)
            case_1_result(i,4)=case_1_result(j,3);
            break;
        end
    end
end
    

 

六. 小结

      此文仅对本次数模国赛的解题做一个总结希望此文能帮助到有需要的朋友。最后,不得不说这个比赛的写作非常考验数学功底了,一大堆公式看的眼花,所以非常感谢建模小姐姐带飞~

      关于数据文件,

生成数据:链接:https://pan.baidu.com/s/1x-7l2INpEkZPWB1bBBH41A 密码:ga49

 

2020.4  更新下结果,拿了省一,导师说差一点送国家级评选。

新上传了完整的论文、代码和输出结果表格。

本文最后一次更新了,今年就毕业啦,感谢大家的关注。

论文+代码+数据:https://download.csdn.net/download/qq_41148224/12367708

  • 43
    点赞
  • 187
    收藏
    觉得还不错? 一键收藏
  • 27
    评论
您好!您提到了RGV动态调度MATLAB代码。RGV动态调度是一种用于机器人手臂在工业生产线上执行任务的调度算法。虽然我无法提供完整的MATLAB代码,但我可以给您一些关于RGV动态调度算法的基本信息和思路,以便您可以自己实现该算法。 RGV动态调度算法的目标是最大化生产线上的任务完成数量,同时最小化任务完成时间。以下是一个简单的实现思路: 1. 确定RGV的移动策略:RGV可以在生产线上移动,并且可以选择不同的任务处理方式。您可以考虑使用贪心算法或者其他启发式方法来决定RGV的移动策略。 2. 确定任务的处理策略:任务可以按照不同的优先级进行处理。您可以根据任务的优先级、处理时间以及RGV当前位置等因素来决定任务的处理顺序。 3. 设计状态表示:为了实现动态调度,您需要定义合适的状态表示来跟踪RGV当前的位置、任务状态以及其他相关信息。 4. 实现调度算法:根据RGV的移动策略和任务处理策略,使用MATLAB编写代码来实现调度算法。您可以使用循环和条件语句来控制RGV的移动和任务处理。 当然,RGV动态调度算法的具体实现会受到您的具体需求和约束条件的影响,比如生产线上的任务数量、RGV的移动速度等等。因此,您可能需要根据您的实际情况对上述思路进行相应的调整和扩展。 希望这些信息能对您有所帮助!如果
评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值