GdbStationPicker在 DB 中定义工位状态和计算结果,例如:
在 OB1 或设备主 FB 中调用:
一个小例子:
假设物料当前位置 sourcePos = 1180。
当前 1 号工位位置 500,距离 680;2 号工位位置 1000,距离 180;3 号工位位置 1500,距离 320;4 号工位位置 2000,距离 820。
如果 2 号和 3 号都可用,程序会选择 2 号,因为 180 比 320 更近。
如果 2 号已经占用,程序会跳过 2 号,选择 3 号。
如果所有工位都不可用,函数返回 0,同时 valid 为 FALSE。
代码测试:
调试时可以用监控表做几组输入,观察 SelectedIndex、Valid 和 MinDistance。
全部工位 Ready,全部未占用,sourcePos 放在 1180,确认选择距离最近的工位。
把最近工位 Occupied 置 TRUE,确认程序会自动选择第二近的可用工位。
把某个工位 Blocked 置 TRUE,确认它不会参与选择。
把 request 置 FALSE,确认返回 0,valid 为 FALSE。
把 count 改成 4,确认 5 到 8 号工位不会参与选择。
这几个测试做完,基本能确认计算逻辑没有跑偏。
工程注意事项:
第一,函数输出的是“推荐值”,不是最终命令。
PLC 程序里经常有一个坑:刚算出 SelectedIndex,下一扫描周期工位状态变了,SelectedIndex 也变了。如果你已经开始执行动作,就不应该让推荐值继续飘。
更稳妥的做法是:在顺控步骤开始时,把 SelectedIndex 锁存到 CurrentTargetStation。后续动作都用锁存值,直到本次任务结束。
第二,平局规则要讲清楚。
如果两个工位距离一样,本例会选择编号小的那个。因为代码里用的是 distance < bestDistance,而不是 distance <= bestDistance。这个细节看起来小,但调试时很重要。
第三,位置单位要统一。
sourcePos 和 stationPos 要用同一个单位。都用 mm,就都用 mm;都用编码器脉冲,就都用脉冲。不要一个用 mm,一个用脉冲,程序不会骂人,设备会。
第四,Blocked 不只是故障。
Blocked 可以表示故障屏蔽,也可以表示人工禁用、维护模式、工位未启用、工艺不匹配。把它单独作为一个输入,比把所有条件揉进 Ready 更清楚。
常见问题:
第一,把选择算法写在一堆 IF 里。
8 个工位还勉强能看,16 个、32 个就很难维护。数组加 FOR 循环,是 SCL 在这类场景里的优势。
第二,没有处理“没有可用工位”。
返回 0 和 valid := FALSE 一定要有。上层程序看到无效结果时,应等待、报警或进入无目标状态,而不是继续给某个默认工位发命令。
第三,把推荐工位当成实时目标。
推荐值可以实时变化,目标值不应该随便跳。动作一旦开始,就要有清楚的状态边界。
第四,所有条件都写成一个 Ready。
Ready、Occupied、Blocked 分开写,调试时一眼就知道工位为什么不能选。现场查问题,靠的就是这种可读性。
老炮儿建议:
如果是缓存线或分拣口,优先把“选择算法”和“动作顺控”拆开,算法只负责推荐,顺控负责执行。
如果要兼顾工位负载均衡,可以在距离相同或距离接近时,再加入使用次数、等待时间等权重。
如果项目对节拍要求高,可以把工位数量上限固定下来,避免写成没有边界的大循环。
如果选择结果要给 HMI 显示,建议同时显示 SelectedIndex、MinDistance 和 StationAvailable 数组,调试会舒服很多。
总结:
本例用 SCL 写了一个最近空闲工位分配器。
它的核心思想很简单:先筛选可用工位,再计算距离,最后找最小值。
这类小算法不一定华丽,但很适合 PLC 工程。它能让程序从“能跑”往“好调、好改、好解释”走一步。
自动化项目里很多有趣的算法,最后都不是为了炫技,而是为了让设备少走弯路,让调试少绕圈。
实例分享链接:
https://pan.quark.cn/s/c2713ce10da4
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!