Junjie
2023-04-14 b5dad5bca39b68fdaaaf844e38fcc55e94bb34f1
src/main/java/com/zy/core/thread/ShuttleThread.java
@@ -8,9 +8,11 @@
import com.core.common.DateUtils;
import com.core.common.SpringUtils;
import com.core.exception.CoolException;
import com.zy.asrs.entity.BasDevp;
import com.zy.asrs.entity.BasShuttle;
import com.zy.asrs.entity.BasShuttleOpt;
import com.zy.asrs.entity.LocMast;
import com.zy.asrs.service.BasDevpService;
import com.zy.asrs.service.BasShuttleOptService;
import com.zy.asrs.service.BasShuttleService;
import com.zy.asrs.service.LocMastService;
@@ -27,8 +29,11 @@
import com.zy.core.enums.*;
import com.zy.core.model.ShuttleSlave;
import com.zy.core.model.Task;
import com.zy.core.model.command.LiftAssignCommand;
import com.zy.core.model.command.LiftCommand;
import com.zy.core.model.command.ShuttleAssignCommand;
import com.zy.core.model.command.ShuttleCommand;
import com.zy.core.model.protocol.LiftProtocol;
import com.zy.core.model.protocol.ShuttleProtocol;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
@@ -198,6 +203,20 @@
                    executeWork(shuttleProtocol.getAssignCommand());
                }
                //检测是否有提升机锁定标记,有则检测提升机是否到位,是否能走下一步命令
                if (shuttleProtocol.getBusyStatusType() == ShuttleStatusType.IDLE
                        && shuttleProtocol.getTaskNo() != 0
                        && shuttleProtocol.getAssignCommand() != null) {
                    Object o = redisUtil.get("wrk_no_" + shuttleProtocol.getAssignCommand().getTaskNo());
                    if (o != null) {
                        HashMap map = JSON.parseObject(o.toString(), HashMap.class);
                        if (map.containsKey("liftSecurityMk") && Boolean.parseBoolean(map.get("liftSecurityMk").toString())) {
                            //执行下一步指令
                            executeWork(shuttleProtocol.getAssignCommand());
                        }
                    }
                }
                //将四向穿梭车状态保存至数据库
                BasShuttleService shuttleService = SpringUtils.getBean(BasShuttleService.class);
                BasShuttle basShuttle = shuttleService.selectById(shuttleProtocol.getShuttleNo());
@@ -271,6 +290,18 @@
            return false;
        }
        BasShuttleService shuttleService = SpringUtils.getBean(BasShuttleService.class);
        if (shuttleService == null) {
            News.error("系统错误");
            return false;
        }
        BasShuttle basShuttle = shuttleService.selectById(slave.getId().shortValue());
        if (basShuttle == null) {
            News.error("四向穿梭车不存在");
            return false;
        }
        command.setShuttleNo(slave.getId().shortValue());
        // 开始任务
        short[] array = new short[17];
@@ -305,6 +336,7 @@
            array[7] = middleToDistDistances[1];
        }
        array[8] = basShuttle.getRunSpeed().shortValue();//四向穿梭车运行速度,从系统数据库读出
        if (command.getRunDirection() != null) {
            //小车运行方向
            array[8] = command.getRunDirection();
@@ -631,14 +663,18 @@
            return false;
        }
        //将标记置为false(防止重发)
        shuttleProtocol.setPakMk(false);
        Object o = redisUtil.get("wrk_no_" + assignCommand.getTaskNo());
        if (o == null) {
            return false;
        }
        HashMap map = JSON.parseObject(o.toString(), HashMap.class);
        if (!checkLiftStation(assignCommand)) {//检测是否有提升机站点,有则调度提升机
            return false;
        }
        //将标记置为false(防止重发)
        shuttleProtocol.setPakMk(false);
        List<ShuttleCommand> errorCommands =  JSON.parseArray(map.get("errorCommands").toString(),ShuttleCommand.class);
        if (errorCommands.size() > 0) {
@@ -765,6 +801,16 @@
                    );
                    shuttleOptService.insert(opt);
                }
                if (map.containsKey("liftSecurityMk") && Boolean.parseBoolean(map.get("liftSecurityMk").toString())) {
                    //曾锁定过提升机,需要进行解锁
                    LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, 1);
                    LiftProtocol liftProtocol = liftThread.getLiftProtocol();
                    if (liftProtocol != null) {
                        liftProtocol.setSecurityMk(false);
                    }
                }
                //删除redis
                redisUtil.del("wrk_no_" + map.get("wrk_no").toString());
@@ -798,6 +844,126 @@
    }
    /**
     * 检测是否有提升机站点,有则调度提升机
     */
    private boolean checkLiftStation(ShuttleAssignCommand assignCommand) {
        //读取redis数据
        if (assignCommand == null) {
            return false;
        }
        Object o = redisUtil.get("wrk_no_" + assignCommand.getTaskNo());
        if (o == null) {
            return false;
        }
        HashMap map = JSON.parseObject(o.toString(), HashMap.class);
        //当前步序
        int commandStep = Integer.parseInt(map.get("commandStep").toString());
        //检测是否存在提升机口的指令
        List<ShuttleCommand> commands = assignCommand.getCommands();
        BasDevpService basDevpService = SpringUtils.getBean(BasDevpService.class);
        ArrayList<Short> qrCodeValues = new ArrayList<>();
        for (BasDevp basDevp : basDevpService.selectList(null)) {
            //将所有提升机口二维码存入list
            qrCodeValues.add(Short.parseShort(basDevp.getQrCodeValue()));
        }
        //遍历所有指令,判断是否有到提升机口的指令,并获取到达该提升机口所需步序
        int step = 0;
        ShuttleCommand command = null;
        for (int i = 1; i < commands.size(); i++) {
            command = commands.get(i);
            if (qrCodeValues.contains(command.getDistCodeNum())) {
                //存在
                step = i + 1;
                break;
            }
        }
        if (step == 0) {
            //无需后续检测,直接放行
            return true;
        }
        //判断下一步是否为提升机口
        if (commandStep + 1 != step) {
            //下一步不是提升机口,跳过后续流程
            return true;
        }
        //拿到提升机线程
        LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, 1);
        if (liftThread == null) {
            return false;
        }
        LiftProtocol liftProtocol = liftThread.getLiftProtocol();
        if (liftProtocol == null) {
            return false;
        }
        //获取四向穿梭车当前楼层
        String shuttleLocNo = shuttleProtocol.getCurrentLocNo();//二维码对应库位号
        Integer shuttleLocNoLev = Integer.parseInt(shuttleLocNo.substring(shuttleLocNo.length() - 2, shuttleLocNo.length()));//库位号对应层高
        //程序走到这,表示提升机可能一直就在当前层,可能经过了移动到达了该层
        if (liftProtocol.getProtocolStatusType() == LiftProtocolStatusType.WAITING) {
            //提升机等待确认
            //设置提升机为空闲状态
            liftProtocol.setProtocolStatus(LiftProtocolStatusType.IDLE);
            //任务号清零
            liftProtocol.setTaskNo((short) 0);
            //标记复位
            liftProtocol.setPakMk(true);
            //任务指令清零
            liftProtocol.setAssignCommand(null);
            //提升机解锁
            liftProtocol.setLiftLock(false);
        }
        //判断提升机是否在目标楼层
        if (liftProtocol.getLev().intValue() == shuttleLocNoLev) {
            //同一层,直接放行
            return true;
        }
        //提升机和穿梭车处于不同楼层,需要进行调度
        if (!liftProtocol.isIdle()) {
            //提升机不是空闲
            return false;
        }
        //给提升机分配任务
        liftProtocol.setLiftLock(true);//锁定提升机
        liftProtocol.setTaskNo(shuttleProtocol.getTaskNo());//设置任务号
        liftProtocol.setShuttleNo(shuttleProtocol.getShuttleNo());//设置四向穿梭车号
        liftProtocol.setProtocolStatus(LiftProtocolStatusType.WORKING);//设置提升机状态为工作中
        liftProtocol.setSecurityMk(true);//标记置为true,防止其他任务占用当前提升机
        map.put("liftSecurityMk", true);//标记置为true,防止其他任务占用当前提升机
        //任务数据保存到redis
        redisUtil.set("wrk_no_" + assignCommand.getTaskNo(), JSON.toJSONString(map));
        //命令list
        ArrayList<LiftCommand> liftCommands = new ArrayList<>();
        LiftCommand liftCommand = new LiftCommand();
        liftCommand.setLiftNo(liftProtocol.getLiftNo());//提升机号
        liftCommand.setTaskNo(liftProtocol.getTaskNo());//任务号
        liftCommand.setRun((short) 1);//升降
        liftCommand.setDistPosition(shuttleLocNoLev.shortValue());//目标楼层(穿梭车所在楼层)
        liftCommand.setLiftLock(true);//锁定提升机
        liftCommands.add(liftCommand);//将命令添加进list
        LiftAssignCommand liftAssignCommand = new LiftAssignCommand();
        liftAssignCommand.setCommands(liftCommands);
        liftAssignCommand.setLiftNo(liftProtocol.getLiftNo());
        liftAssignCommand.setTaskNo(liftProtocol.getTaskNo());
        //下发任务
        MessageQueue.offer(SlaveType.Lift, liftProtocol.getLiftNo().intValue(), new Task(3, liftAssignCommand));
        return false;
    }
    /**
     * 复位并尝试修复错误
     */
    private boolean reset(ShuttleAssignCommand assignCommand) {