如何简化输送机的分拣

daizhicun
daizhicun 这家伙很懒,还没有设置简介

0 人点赞了该文章 · 1532 浏览

近年,电商的崛起,给自动化分拣带来了井喷的发展;而分拣往往又是料箱输送机控制的难点;
不像简单的左拐右拐的分支处理;
分拣一般要去几十个滑道口,所以这一段要做记忆,跟踪;
而且也要和上位做合理简单的通讯方式;
如果方法不当,系统就会做的复杂,调试成本高,出问题不容易发现;


这里主要分两种:
   1.普通的滚筒,光电分拣的那种;
   2.高速分拣的,比较流行的是滑块式的;

先说第二种,从控制角度来说,滑块式的控制是最简单的, 因为运行是同步的,所以 直接通过编码器就能控制;
滑块式的控制思路是:
  1.滑块分拣一般是一个环,这个环上比如共有50个滑块位置,我们就在DB块上定义50个单位;
         数据                                                                   DB地址
       ---------------------------------------------- ---------------- ------      --         
        1号滑块条码(PLC写入)                                   S7:[CV]DB11,DWORD0        
        1号滑块进入读码区域的编码器值PLC写入)     S7:[CV]DB11,WORD5
         1号滑块的目标位置(WCS写入)                        S7:[CV]DB11,BYTE7
        1号滑块分拨的编码器值 (PLC写入)                 S7:[CV]DB11,WORD8

        2号滑块条码(PLC写入)                                  S7:[CV]DB11,DWORD10
      2号滑块进入读码区域的编码器值PLC写入)     S7:[CV]DB11,WORD15
       2号滑块的目标位置(WCS写入)                      S7:[CV]DB11,BYTE17
        2号滑块分拨的编码器值(PLC写入)               S7:[CV]DB11,WORD18

        ......

     2.在环上某个固定位置安装读码器,一旦某个滑块进入读码区,系统根据编码器的定位,能够知道是第几号滑块,
         plc把当前的编码器值写入,用来编辑进入时刻的编码值,可以理解成计数的初始值,当读取条码后,再以把条码值写入到上面对应位置的DB块里;
     3.上位系统一旦发现该滑块的DB块里有了条码信息,会立刻根据该条码对应的订单信息,进行滑道分配,比如分配到第8号滑道,写入到相应的DB块;
     4.电控系统一旦发现上位系统提供了目标位置,立刻以读取到条码那个时刻的编码器值为依据,根据到8号滑道的距离,计算出增加的编码器的值,写入到相应的DB块;
     5.电控系统实时对比当前编码器的值 和 50个DB单元中的分拨编码器值,一旦发现相等,就里面对相应的滑块发出分拨动作,
        同时清除这个DB块;

以上是我想到的最简单的方式;
     1.控制简单;
     2.和上位系统交互简单;

这种通讯方式,颠覆了一个以前固化的错误思维: 上位系统无法实时和高速分拣做实时通讯;
    
很多人都以为,如果3万箱/小时的高速分拣,那就是1秒钟10箱的速度,跟“飞“一样,肉眼都看不清的,
再跟计算机“慢慢”的通讯,交互,肯定来不及;
所以算了把,上位系统既然来不及反应,那就在条码上写死滑道好了,比如条码的前两位代表滑道号;
但是这样局限性太大了,很多分配逻辑都是动态的;而且如果是周转箱是载体的话,条码是固定重复利用的;
怎么可能在条码里就确定了分道信息;这个做法在大部分项目了是不现实的;

    于是又有人提出,把条码和去向信息提前发给plc,比如plc自身容量可以记录2万个条码信息,这样读条码的时候,
plc根据条码检索提前得到的去向信息,进行高速判断;这个方法更不可取;
      1.交互太复杂;
      2.流程太死板,wcs分配很多时候是动态的,根据实时的滑道完成情况和订单分类来动态分配的;所以没法提前给;
      3.对plc要求搞,也许本来用西门子s7-300就搞定的,由于需要大存储容量,并且要高速检索,可能需要s7-400或更高的配置;
      4.plc检索2万个条码和去向的信息的速度真的能快于电脑吗?
          条码和去向,plc需要高速的存储插入,这个插入有两种方法:
            1是排序插入,目的是检索的时候,可以用2分法,快速的检索,性能是log2(n) 这种对数的效率;
              但是排序插入成本太高了,每次插入,都要把大量的数据点后循环挪位置,
              最多每插入一箱,就要做2万个单元同时转移,我不知道plc要消耗多少时间,可能要秒级了吧,这个我想电控程序一般不会这么写;
            2.不做排序插入,那里空就插入到那里,这样插入数据是方便了,但是检索的时候,就要全局扫描,性能是o(n);
         但是上位电脑不一样,数据是堆存放的,一般会做哈希或B+树索引检索的;
          也就是说在plc和上位电脑的CPU运算能力一样强大的情况下,电脑因为有优化算法支撑,速度比plc那种不带优化算法的,要快上数千倍;
           再加上本身电脑cpu运算能力要远强于plc,所以检索数据速度在数据量大的情况下,快上数万倍,相差4,5个数量级也是可能的;


其实,我想说的,就算上位WCS系统反应很慢,哪怕慢到1,2秒才能"慢吞吞“的把去向写入,都问题不大;
为什么?
     首先,对于高速分拣,数据运算逻辑肯定要做的相对简单,用完的数据会及时清理;
     在很多场景下,我做过测试,在百万条(假如有100万箱的条码)数据下,
        分配1个料箱所花费的逻辑运算时间,应该在0.1ms,也就是万分之一秒的时间;
    所以wcs和plc消耗的事件主要在网络通讯上;这个我测算下来,一个通讯来回,一般在5ms左右完成;
  性能不差, 10ms足够一次分配了,不过没关系,我们就放大100倍,假设wcs每次分配需要1秒种;   而且网络不稳定,偶尔有个小延时,这个是有可能的,这就导致可能偶尔会延时2~3秒;

   根据通讯协议的定义方式:
        1.当plc读取条码的时候,会把条码写入到相应滑块号的位置,就算wcs没有及时反馈去向,
          没关系,继续往前走(和电机同步运行的,也不可能停),夸张一点,过了2秒后,WCS才慢吞吞的反馈了去向,分配的是8滑道;
          但是8滑道距离读码器的位置有几十米呢,这个时刻,滑块刚走到6号滑道位置,所以这个分配仍然有效;万一此刻滑块超过了8滑道也没关系,
          大不了兜一圈就 进入了; 这就颠覆了,很多人认为料箱在到达第一个滑道口之前必须给出去向否者剔除 这种设计僵硬的思路;
          这就像海枯石烂,实在等不下去了才放弃;如果有50个滑道,那么分配到1滑道的概率是2%;很多分配到后面滑道的,其实延时个几秒
          根本无所谓的;

         2. wcs会批量上传,如果因为网络延时,或其它原因,输送线上“刷”的一下子,过了10几箱,plc都把条码写到了DB块相应的位置;
            那么等WCS反应过来的时候,也会“刷”一下子把这10几去向同时写入DB块;

  所以根据以上两点: 1.plc一直做去向“等待”不放弃; 2.wcs会批量处理去向分配; 那么就算电脑差一些,plc差一些,网络再差一些,也问题
不大,很多时候,思路才是最重要的,再强大的硬件也只是景上添花的;想想10年前的硬件配置,比现在相差甚远,不照样运行的很稳定;

这里有3个注意点:
  1.编码器的编码值不可能无限制的写下去,应该有个范围,比如16个字节的word,那么范围就是0~65535;
    所以当   计算的目标位置的编码值<料箱进入读码区那个时刻的编码值    的时候,要给目标位置的编码值+65536再去判断;
  2.通过编码器的当前值,就能知道这个时刻各个滑块的具体位置,但是,运行时间长了,难免会导致偏差越来越大,
     所以应该给某个滑块,比如1号滑块上安装反光板;再某个固定位置,比如就是读码器的位置,安装一个光电,当1这个标记反光板的滑块和光电对上时,
      plc程序里,要把这个时刻的编码器的编码值和滑块位置关系做校正;以防止累计误差;
   3.滑块真正分拨的时候, 未必要100% 实现目标位置的编码值=当前编码值,这个也太精确了,plc也不可能再编码器每次+1,循环对比一次,
      这个频率估计1秒就要几十万次,没有必要;而且plc一个周期估计也要几十毫秒;所以几十毫秒对比一次的话,就不可能绝对想等了;
     只要 两个值相减 的绝对值在一个很小的范围,就可以分拨了;



上面所说的高速分拣,其实很多厂家自己都集成了上位系统,我们往往不能直接和plc做底层交互;而是和他们自带的上位系统做交互;
       可以通过批量socket通讯方式,也可以把数据直接批量写入他们的数据库;
      虽然从我的角度来说,不喜欢隔了一层隔靴搔痒,
      但是对于厂家来说,还是有必要的,因为厂家面对的大部分都是应用层面的工程师,所以封装一下也是为了保障;




下面说说最常见的普通的滚筒依靠光电分拣思路
     我想到的改进有2点:
       1.跟踪方式的改进,队列改链表;
       2.通讯的改进,和上面一样,数据完全共享;

1.跟踪方式的改进:
     咨询过很多plc工程师,都是用的数组排队的方法,
     都是每进入一个新箱子,就会把线体上的正在分拣的箱子的DB块全部向后挪一个位置;
    当线体上中间某个箱子滑出时,再把它后面的箱子的DB块全部全部向前挪一个位置;
    这就导致,线体箱子的信息在DB块里不停的移来移去;

    计算机课程里,有一个重要的科目是数据结构,里面考试的重点就是链表;
    在数据库的设计里,数据的存放,检索,也是大量使用链表;
    其实,在数据处理上,很多地方链表要比队列方便和优化很多;
    队列的最大缺点,就是数据存储位置要不断变化,这给很多地方带来不方便;

    先说一下队列跟踪的思路:
         1.入口读码器读取条码A;plc通知上位wms;
         2.wcs提供去向;
         3.PLC将线体上已经分配但是未分拣剔出的箱子的信息在DB块上全体向后挪一个位置,让新条码A和对应的去向放在第一个位置;
         4.当3号滑道口的光电(senser)被箱子挡住的时候,PLC捕获到这个信息,就从队列里找出目标位置是3号滑道的排队的第一个箱子(去3号口的箱子可能有多个),让3号口的机械装置分拨,
             同时把箱子信息从DB块里清除,把排队在后面的箱子信息的DB块位置全部向前移一个;


  再说一下链表跟踪的思路:  
         1.入口读码器读取条码A3;plc通知上位wms;
         2.wcs提供去向;
         3.PLC将在数据块了从上到下找出第一个空余的位置写入,同时将条码A3的填入的DB块的地址记录下来,填写到它的上一个箱子A2的下一个箱子的地址位置;
            这样形成了一个单链表; A1->A2->A3;  当第个箱子A1进入时,他是光杆司令,当A2进入时,A1就有了小弟,A2所在的DB块的地址记录在A1的下一位置里;
            同理,A3来了,A2就有了小弟...; 最后是 A1->A2->A3->A4->A5...,一个个手牵手关联着;
            关键是:plc要记住“老大”是谁,即这里的A1,这样才能顺藤摸瓜,从头遍历,就像破案子,要找到源头;如果A1剔出了,就要A2做“老大”,以此类推;
          4.当3号滑道口的光电(senser)被箱子挡住的时候,PLC捕获到这个信息,就从“老大”开始对比,如果不是,就根据老大的下一位置的地址,找到老二,以此类推,
             只到遍历到最后一个没有下一位置的料箱信息算结束;
             比如老五的目标位置正好是3号滑道,那就把老五db块数据清除,“赶出”链表,让老四直接跟老六牵手;当然,如果“老大”的去向就是3号,那么直接把老大的DB清除,
            同时记住现在老二做了老大,下次遍历直接从老二开始;

   这样看下来,链表实际上要比队列稍微复杂一些:
       1.它要有一个地方记录链表的首地址,即知道“老大”的位置,才能遍历查找;一旦"老大"清除,还要重新换老大,这个地方需要程序记忆的;
       2.数据块上要比队列多定义一个前后关联的地址;
       3.链表需要大量的变址处理,程序的可读性可能变差,
         特别梯形图,设计的初衷是擅长做数字电路的与或非的处理,做大量的循环和变址可读性可能不好;
         STL类似汇编的那种,别人读取来,估计要半条命;所以做电控的,很多宁愿重写,也不愿意去看别人纷繁复杂的梯形图或STL;
         所以对付这样的逻辑运算,最好还使用SCL这种类似pascal的高级语言吧。应该能节约不少开发和调试成本;
        十几年前,在一家电气公司,那时候流行DSP(类似现在的ARM), 我们用它做二次回路的信号检测,用FFT的傅里叶变换采样,
         那时候已经有了keil C ,可以用C语言开发,但是同事不习惯,都是做汇编出身的,偏要用汇编,写了大半年,我用高级语言2天就能弄出来了;
         效率相差100倍;开发也就算了,再搞个调试,优化,用汇编不是要人命吗,所以不知道为什么电控里,高级语言好像不那么流行;
         那些梯形图或STL适合做简单的输入输出处理和简单的数据推移跟踪,如果真的做很复杂的运算和判断,估计真是把大量时间都浪费了;
         现在是互联网快速改进迭代升级的时代,好在工控一直相对落后几个节拍,不是很敏感;


   链表最大的好处就是:料箱从条码读入 到 分拨剔除 这个时间内存放的地址是不会变的,这个好处其实是大大的,后面就可以体现了;

所以我个人还是倾向于链表的方式;
   现在各种地方主流的设计,也是数据固定存储;
   比如硬盘的数据,写入后,除非硬盘整理,数据位置一般就固定了; 数据库的数据也是;
  因为地址往往代表了一个身份的识别,如果数据不停的变化位置,会给很多地方程序处理带来不方便,而且在数据量大的时候,不停移动数据位置,是非常损失性能的;



   2.通讯的改进
如果用队列,WCS和PLC根本无法共享DB块,为什么? 因为箱子的DB块位置不固定,就像老鼠一样串来串去; 当WCS获取条码A在100地址的时候,刚想把去向紧接着写入101地址;
     PLC居然把A条码的位置挪到107地址了;这样WCS和PLC就无法共享DB块;除非PLC做等待,等WCS去向填入以后,才能挪位置;但是队列的机制不允许;
         所以用队列的方法,WCS和PLC的交互,只能单独用另外一块地址做交互,这就给plc带来了复杂性;一般就一个条码地址做通讯,这就不好了,万一wcs偶尔反应迟钝,后一个箱子
   有来了,覆盖掉前面一个,所以安全起见,最好做多个,但是多个也复杂;怎么弄都没有直接共享DB块使用起来爽;

           所以,一旦用了链表,WCS和PLC数据直接共享,就像上面高速分拣的机制一样,WCS反应迟钝也无所谓了,因为可以批量写入,而且只要写入的时刻,箱子还没经过目标位置,

都不算晚,这样对大家的“要求“都降低了;


总结:
    1.以上光电跟踪,只是说了最基本的逻辑,其实里面还有不少注意点;
       比如:要结合编码器,做延时的预估,万一有点箱子被人拿走,或光电漏判断(两个箱子连着没拉开),需要把异常数据剔除队列或链表;
                 当然有些公司,为了偷懒,嫌光电跟踪麻烦,直接通过编码器,甚至直接根据速度做倒计时判断,这个肯定不准的;箱子会在滚筒上打滑的,这个判断太不靠谱了;
    2.真的有人在线体上手工拿走一箱,比如把“老五”拿走(前面的老四,老三...不受影响),那接下来的老六会被误当作老五,老七被当作老六;包括新投入的老二十会被当作老十九,
      后面就会永远错位一个,
      所以异常校验机制非常重要;最简单的方法,如果通过编码器计算的距离和光电跟踪反馈的距离有很大的出入,那么整个线体的箱子全部作废,全部剔除到最后,
      在线体清空后,线体重启,链表或队列全部清空,这个现象也经常遇到,有的项目现场,一旦跟踪错了,重启才能恢复;这个感觉不太好;
      不建议这么做,用户体验有点差;还是每个都把光电和编码器结合起来判断好,比如3号光电挡住时,发现队列或链表的第一个去3号滑道分拨的箱子明显时间不对,就放弃这个,清除它,
     从第二个开始判断,因为第一个可能被人工拿走,或跟随其他箱子误动作在其他滑道提前走掉了;

    3.其实核心思路,就是wcs和plc尽量不分家,数据块共享,以此带来的各种交互,监控带来的方便性;
    4.彼此"宽容",PLC不需要wcs快速相应,只要不到万不得已,wcs延时一点时间也无妨;同时wcs也不需要plc做的那么精确,只要给出条码就行,时间早点迟点也无所谓;
       两者不做无谓的繁琐的通讯;

发布于 2020-10-13 14:09

免责声明:

本文由 daizhicun 原创发布于 大董知识库 ,著作权归作者所有。

登录一下,更多精彩内容等你发现,贡献精彩回答,参与评论互动

登录! 还没有账号?去注册

暂无评论

All Rights Reserved Powered BY WeCenter V4.1.0 © 2023 京ICP备16065701号