堆垛机 货位分配 和 入库调度 的优化
立体库最关键的点:库存不要乱; 要想库存不乱,最关键的是入库要准确,因为“病从口入”;
要想入库准确,有两个节点比较关键:
1.分配货位时机;
2.托盘到达入库口的时候,如何调度;
先说第1点:
分配货位的时机
这个时机处理,经过这些年,一共经历了6个阶段
1.入库托盘登记时分配:
在托盘码垛(货物和物料绑定)的时候,把具体的排列层的位置预先分配好,并且在货位表的该位置上做一个锁的标记,以免其他托盘登记的时候,再次分配到该货位上;
2.过第一个读码器(BCR)时分配:
因为操作员可能在线下登记,所以登记时分配货位,有个很大的风险,万一操作员没有把该托盘放到线体上就拿走了,这个货位因为被预定了,就死掉了,永远不会被释放了;
所以在托盘进过第一个BCR的时候,再分配,托盘被中途拿走的概率就低很多了;
3.到达堆垛机入口时分配:
过了第一个BCR就把货位分配号感觉太“死”了,万一输送线上有多个BCR,托盘经过第二个BCR的时候,发现事先分配的那个巷道的堆垛机出了故障,就要重新分配,重新分配就需要释放原来的,实现起来比较麻烦;所以过第一个BCR只是分配巷道,而不分配具体的货位;这样托盘经过其他BCR的时候,如果发现对应的堆垛机故障或线路拥堵,可以更换巷道;
当托盘到达堆垛机入口的时候,再分配货位,这样就避免了重复分配的复杂度,简化了程序实现难度,而且也更灵活;如果电控“不慎”跟踪错误,或者人工手动将托盘送到入口,只要将输送机上的托盘号数据写正确,就可以正常入库;
4.到达入口并且堆垛机空闲时分配:
托盘虽然到达入口了,但是也许堆垛机此刻正在做其他任务,这些任务可能做到一半的堆垛机就发生故障,这时候,就可能人工将该托盘转移到其他堆垛机入口,这样就导致已经分配的货位死在里面;
当然,可以人自动释放该货位,不过处理起来比较麻烦,要做很多判断;
所以等堆垛机空闲了,万事俱备,不欠东风,货位分配和调度堆垛机动作做在一起,这样就安全很多了;
5.到达入口并且堆垛机空闲时分配(不锁住预分配货位):
就算堆垛机动作时候的分配货位,在堆垛机取货的时候,也可能发生故障,也可能人工把托盘拿到其他堆垛机上,同样会造成已经分配的货位死在里面,当然也可以做自动释放,但是还是程序麻烦啊,
所以干脆分配货位的时候,就不用锁货位了,这样终于感觉世界安静了,开始感觉有风险,因为分配货位要预先锁住的做法已经延续很多年了,突然取消自己都不适应,没有锁感觉不安全,万一两个托盘分配到到一个货位怎么办?但是你是在调度的时刻在分配的,这个时机也是唯一的,所以细想一下,也是没有风险的;
无论出现什么异常,只要入库没有最终完成,中途出现任何异常,都不需要做“撤销”处理,大家都知道,逆向流程很多时候要比正向流程复杂很多;如今,在任何设备异常情况下,入库的分配都不管逆向的处理,是不是感觉“松”了一个口气;
6.堆垛机放货的分配(同样不锁住预分配货位):
有些堆垛机的控制模式,是分段的,取货的时候,给堆垛机发一个取货指令,放货的时候,再给堆垛机发一个放货指令;
这样,只要发现入口有货,不管三七二十一,先让堆垛机取到再说,取货完成时,再给托盘分配一个货位,这样分配的逻辑放到放货的动作去做了;
因为取货的逻辑比较复杂,要考虑各种硬件设备状态和任务的情况综合考虑选取一个任务执行,而放货的逻辑相对就比较简单,所以把货位分配放到放货逻辑中,程序复杂度也更降低了;
同样,只要堆垛机最终动作没做完,中途任何故障,都不需要做任何逻辑上的撤销处理;
说了上面6个阶段,其实最主要想说的,就是分配货位不做锁的处理会让系统在异常的时候,更加灵活的处理;这是切肤之痛,以前几乎每个项目都遇到“已分配”的货位烂在系统里很久,原因各种各样,
之前,我都做“智能”的判断是否“自动”释放,这个逻辑非常复杂的,当时我的思路是:托盘经过BCR的时候,判断是否已经分配了货位(理论上是不可能的,所有可能人工干预在堆垛机入口因为故障拿走),
如果有就“可能”要释放,为什么是“可能”,因为客户的托盘条码有可能贴重复了,要分清李逵还时李鬼很麻烦,我的判断原则是如果半小时内,该托盘在之前的入口出现过堆垛机或输送机的故障,而且按照线路顺序,托盘确实可能走到该BCR,这就释放之前货位,但是这也是取得“高概率”事件;而且程序写起来挺复杂的;所以预分配货位在异常情况下的释放,一直是困扰我的一个难题;
当然你可以说,让客户自己手动去释放,这是一个偷懒的做法;把问题抛给客户,出了问题算客户的,这样不地道;
这就像:你跟别人借钱,不写借条(不做货位锁定),等到期了,没能力偿还,就可以耍赖;
再说第2点:
托盘到达入库口的时候,如何调度;
1.以前的做法:通过任务调度,如果托盘到达入口,硬件满足了,但是万一这个托盘没有任务数据,就不能调度;
比如你在入口随便放一个没有任务的托盘号,堆垛机时不会调度的,这就有问题了,堆垛机的调度最关键的是要做“永动机”,也就是在任何情况下,都不能让入口堵住
所以:对于托盘到达堆垛机入口的时候,当系统发现时一个“莫名其妙”的托盘的时候,就需要生成虚拟任务,否者堆垛机没法调度;
这个虚拟任务生成起来,甚是麻烦:
1.要捕获托盘到达入口的事件,才能知道这个消息;如果和PLC交互没做好,这个事件可能遗漏;
2.生成的虚拟任务,有的时候不能使用真实的PLC提供的条码,因为万一这个条码的任务正在被其他堆垛机调度,会导致用一个托盘在两个位置(这种情原因:1.电控跟踪问题;2托盘条码重复),
甚至该条码在货架上已经有了,都要生成虚拟任务,所以这就很麻烦;
对于这种虚拟任务,我统计过,常见的有4种:
1.条码未识别,很多人想用99999之类的固定条码生成虚拟任务,这是不行的,因为同时两个站台都可能未识别,同一个托盘同时只能有一个被调度的任务;
2.库存内已经有的条码;
3. 多个入库站台的条码同时重复;
4. 当前入口托盘和其他正在调度的堆垛机的条码重复;
这几种情况,就要考虑做虚拟任务,避开冲突,甚至麻烦;
2.现在的做法:
以前托盘在入口的时候,既然要可能生成虚拟任务,以满足让堆垛机调度;
这种方法,实在复杂,当然你可以说,托盘在入口的时候,没有任务或者有异常或冲突的任务的时候,就让托盘停着不动,让人工干预,这是懒人的做法;
现在思路又变了,入库调度,不看任务,只看入口的物理跟踪的托盘;
只要入口有条码并且可入,那么就 必须调度;
如果是半循环的堆垛机,就直接去取货,取到后,如果满足条件,就正常分配货位放货,否者调度到出库站台;
如果是全循环的堆垛机,就匹配该托盘任务,匹配正常,就正常运作,匹配失败(无任务,冲突等)就给出库站台,然后发出from to 指令;
现在这个做法,就更贴切物理条件,只要入口有货,就必然调度,而不是必须要有任务;
虽然也是很小的改进,但是彻底解放了:托盘到达入口站台的逻辑处理;
以前这个地方要做很多判断,要可能生成虚拟任务,虚拟任务生成了,如果在执行失败,该虚拟任务就不能被删除;导致虚拟任务的残留;
所以换一个思路,把以任务为基准的入库调度 改成 以入口跟踪条码的硬件条件为基准,一些异常的处理,就豁然开朗了;
问答环节:
1.问一下,如果这样应用,是WMS分配货位还是WCS或设备系统分配库位,最终回传WMS?
答:我一般都是 wms/wcs 系统二合一,所以就无缝处理;
不过也经常和wms独立商合作; 这种情况,我这边一般有两种方法:
1.所有的立体库的堆垛机货位,统一由wcs管理,对于wms来说,他就一个统一的大货位;
这样wms每次发货的时候,只要告诉wcs托盘号;具体从那里出库,wcs来生成;
2. 货位仍然是wcs来分配,wms下发托盘登记信息给wcs后,wcs一路运行到最后一步,堆垛机上架成功后,再把货位告诉wms;
2.立体库一般都是多纵深的库位,楼主是一纵深作为一个库位来管理,还是多纵深作为一个库位来管理?
如果是一个纵深一个库位来管理,那么可以考虑6的方案比较合适,如果是多纵深作为一个库位来管,那么分配库位就有问题,同时有WCS来分配库位总感觉不是很合理,可能是涉及到库存不需要管批次的情况。
仓库内部既然是通过 码盘与货物绑定一对一关系,那么就必须保证托盘码唯一,在收货确认时就需要保证托盘码的唯一性,而不应是货物要上架时来验证,同时不能控制有托盘码就直接过BCR,没任务直接到出货口,如果同时有出库作业的话,现场很容易误认为这是正常的出库托盘,而插错货。
答:
1.立体库一般都是多纵深的库位,楼主是一纵深作为一个库位来管理,还是多纵深作为一个库位来管理?如果是一个纵深一个库位来管理,那么可以考虑6的方案比较合适,如果是多纵深作为一个库位来管,那么分配库位就有问题,同时有WCS来分配库位总感觉不是很合理,可能是涉及到库存不需要管批次的情况。
--其实说wms/wcs谁去分配,这个说法本身并不是关键;关键是什么时机去分配;我做的系统基本都是2合1的,那么多伸位(一半双伸位),
最后一步,具体无货的分配,也是在堆垛机取货的那个时刻做的,不过会尽量和库存内相同物料相同批次尽量合并;
如果是只做wcs,那么算法可以让wms实现,但是调度的时机不变,wcs取货的时候调度wms的分配逻辑子函数;
2.仓库内部既然是通过 码盘与货物绑定一对一关系,那么就必须保证托盘码唯一,在收货确认时就需要保证托盘码的唯一性,而不应是货物要上架时来验证,同时不能控制有托盘码就直接过BCR,没任务直接到出货口,如果同时有出库作业的话,现场很容易误认为这是正常的出库托盘,而插错货。
--这个不矛盾,码盘登记的时候,本来需要判断库存的冲突性;
说白了,如果是2合1的系统,数据库是共享的(甚至是同一个数据库的同一个用户下),里面的逻辑函数也是共享的;
货位分配主要是时机问题,自由各种判断逻辑,任何环节都不能少。
No comment