Junjie
2023-06-19 c4355edf683197a67e127c796e8f93650cc2a302
src/main/java/com/zy/core/thread/ShuttleThread.java
@@ -12,6 +12,7 @@
import com.zy.asrs.service.*;
import com.zy.asrs.utils.Utils;
import com.zy.common.model.NavigateNode;
import com.zy.common.model.enums.NavigationMapType;
import com.zy.common.utils.*;
import com.zy.core.News;
import com.zy.core.ThreadHandler;
@@ -365,6 +366,11 @@
        OperateResult result = modbusTcpNet.Write("0", array);;
        if (result != null && result.IsSuccess) {
            try {
                Thread.sleep(3000);//命令下发后休眠1s
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            News.info("四向穿梭车命令下发[id:{}] >>>>> {}", slave.getId(), JSON.toJSON(command));
            OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(command)));
            return true;
@@ -414,7 +420,7 @@
                    //小车移动到提升机口,计算路径
                    //计算小车起点到中点所需命令
                    LocMast currentLocMast = locMastService.queryByQrCode(shuttleProtocol.getCurrentCode().toString());
                    List<NavigateNode> firstMastResult = NavigateUtils.calc(currentLocMast.getLocNo(), assignCommand.getSourceLocNo(), ShuttleTaskModeType.PAK_IN.id);
                    List<NavigateNode> firstMastResult = NavigateUtils.calc(currentLocMast.getLocNo(), assignCommand.getSourceLocNo(), NavigationMapType.NORMAL.id);//小车到中点,处于无货状态,使用正常通道地图
                    if (firstMastResult != null) {
                        allNode.addAll(firstMastResult);//将节点进行保存
@@ -450,7 +456,7 @@
                    }
                    //计算中点到终点路径
                    List<NavigateNode> secMastResult = NavigateUtils.calc(assignCommand.getSourceLocNo(), assignCommand.getLocNo(), ShuttleTaskModeType.PAK_IN.id);
                    List<NavigateNode> secMastResult = NavigateUtils.calc(assignCommand.getSourceLocNo(), assignCommand.getLocNo(), NavigationMapType.DFX.id);//小车从中点到终点,处于有货状态,使用DFX地图
                    if (secMastResult != null) {
                        allNode.addAll(secMastResult);//将节点进行保存
@@ -478,15 +484,14 @@
                        commands.add(getPalletCommand((short) 2));
                    }
                    navigateMapData = new NavigateMapData(Utils.getLev(currentLocMast.getLocNo()));
                    if (firstMastResult != null) {
                        //所使用的路径进行锁定禁用
                        navigateMapData.writeNavigateNodeToRedisMap(firstMastResult, true);////所使用的路径进行锁定禁用
                    if (firstMastResult == null || secMastResult == null) {
                        throw new CoolException(MessageFormat.format( "四向穿梭车出入库路径搜索失败 ===>> [id:{0}] [ip:{1}] [port:{2}]", slave.getId(), slave.getIp(), slave.getPort()));
                    }
                    if (secMastResult != null) {
                        navigateMapData.writeNavigateNodeToRedisMap(secMastResult, true);////所使用的路径进行锁定禁用
                    }
                    navigateMapData = new NavigateMapData(Utils.getLev(currentLocMast.getLocNo()));
                    //所使用的路径进行锁定禁用
                    navigateMapData.writeNavigateNodeToRedisMap(firstMastResult, true);////所使用的路径进行锁定禁用
                    navigateMapData.writeNavigateNodeToRedisMap(secMastResult, true);////所使用的路径进行锁定禁用
                    break;
                case 3://托盘顶升
                case 4://托盘下降
@@ -525,8 +530,8 @@
                    //如果穿梭车在提升机内,移动时需要先下发出提升机命令
                    if (liftProtocol.getBarcode().intValue() == shuttleProtocol.getCurrentCode().intValue()) {
                        //穿梭车出提升机
                        Short liftLev = liftProtocol.getPositionArrivalFeedback();//提升机位置
                        String liftSiteLocNo = Utils.levToOutInStaLocNo(liftLev.intValue());
                        Short liftArrival = liftProtocol.getPositionArrivalFeedback();//提升机位置反馈
                        String liftSiteLocNo = Utils.liftArrivalToOutInStaLocNo(liftArrival);
                        LocMast locMast1 = locMastService.selectById(liftSiteLocNo);
                        ShuttleCommand moveCommand = getMoveCommand(liftProtocol.getBarcode(), Short.parseShort(locMast1.getQrCodeValue()), 1400, ShuttleRunDirection.BOTTOM.id, liftProtocol.getBarcode(), 1400, runSpeed);
                        commands.add(moveCommand);
@@ -536,7 +541,7 @@
                    }
                    LocMast locMast = locMastService.queryByQrCode(startQr);
                    List<NavigateNode> result = NavigateUtils.calc(locMast.getLocNo(), assignCommand.getLocNo(), ShuttleTaskModeType.PAK_IN.id);
                    List<NavigateNode> result = NavigateUtils.calc(locMast.getLocNo(), assignCommand.getLocNo(), NavigationMapType.NONE.id);//手动命令-移动命令,使用无过滤地图
                    if (result != null) {
                        //所使用的路径进行锁定禁用
@@ -572,7 +577,7 @@
                    int lev = Utils.getLev(locMast1.getLocNo());//穿梭车当前高度
                    String liftSiteLocNo = Utils.levToOutInStaLocNo(lev);//当前楼层站点库位号
                    LocMast liftSitelocMast = locMastService.selectById(liftSiteLocNo);
                    List<NavigateNode> result1 = NavigateUtils.calc(locMast1.getLocNo(), liftSiteLocNo, ShuttleTaskModeType.PAK_IN.id);
                    List<NavigateNode> result1 = NavigateUtils.calc(locMast1.getLocNo(), liftSiteLocNo, NavigationMapType.NONE.id);//移动到提升机,使用无过滤地图
                    Short endStartCode = null;
                    if (result1 != null) {
@@ -675,7 +680,7 @@
                    shuttleProtocol.setPakMk(true);
                    return true;
                }else {
                    List<NavigateNode> result = NavigateUtils.calc(locMast.getLocNo(), distLocMast.getLocNo(), ShuttleTaskModeType.PAK_IN.id);
                    List<NavigateNode> result = NavigateUtils.calc(locMast.getLocNo(), distLocMast.getLocNo(), NavigationMapType.DFX.id);//错误恢复,使用DFX地图
                    if (result != null) {
                        //获取分段路径
                        ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(result);
@@ -745,6 +750,41 @@
        LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, 1);
        LiftProtocol liftProtocol = liftThread.getLiftProtocol();
        //判断小车当前二维码是否为提升机二维码
        if (shuttleProtocol.getCurrentCode().intValue() == liftProtocol.getBarcode().intValue()) {
            //小车当前命令起始位置就是提升机二维码,说明小车需要向提升机外移动,则需要判断状态是否满足
            if (command.getStartCodeNum().intValue() == liftProtocol.getBarcode().intValue()){
                //提升机是否空闲,提升机是否到达目标楼层,目标楼层是否给出提升机到位信号位
                if (!liftProtocol.isIdle()) {
                    return false;//提升机忙,禁止下发命令
                }
                Short distCodeNum = command.getDistCodeNum();//目标二维码
                BasDevpService basDevpService = SpringUtils.getBean(BasDevpService.class);
                BasDevp basDevp = basDevpService.queryByQrCode(distCodeNum.intValue());//目标站点
                if (basDevp == null) {
                    return false;//找不到目标站,禁止下发命令
                }
                int lev = Utils.getLev(basDevp.getLocNo());//目标二维码所在楼层
                int liftLev = liftProtocol.getLev().intValue();//提升机所在楼层
                if (liftLev != lev) {
                    return false;//提升机不在目标楼层,禁止下发命令
                }
                //获取目标站信息
                SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1);
                StaProtocol staProtocol = devpThread.getStation().get(basDevp.getDevNo());
                if (staProtocol == null) {
                    return false;//站点信息不存在,禁止下发命令
                }
                if (!staProtocol.isLiftArrival()) {
                    return false;//站点提升机到位信号false,禁止下发命令
                }
            }
        }
        //下发命令
        if (!write(command)) {
@@ -752,6 +792,24 @@
            return false;
        } else {
            News.info("四向穿梭车命令下发成功,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(command));
            //保存数据到数据库做流水
            BasShuttleOptService shuttleOptService = SpringUtils.getBean(BasShuttleOptService.class);
            if (shuttleOptService != null) {
                BasShuttleOpt opt = new BasShuttleOpt(
                        assignCommand.getTaskNo().intValue(),
                        assignCommand.getShuttleNo().intValue(),
                        new Date(),
                        ShuttleTaskModeType.get(assignCommand.getTaskMode()).desc,
                        assignCommand.getSourceLocNo(),
                        assignCommand.getLocNo(),
                        null,
                        null,
                        null,
                        JSON.toJSONString(command)
                );
                shuttleOptService.insert(opt);
            }
            //判断数据是否执行完成
            if (commandStep < size - 1) {
@@ -763,23 +821,6 @@
                redisUtil.set("shuttle_wrk_no_" + redisCommand.getWrkNo(), JSON.toJSONString(redisCommand));
            }else {
                //已执行完成
                //保存数据到数据库做流水
                BasShuttleOptService shuttleOptService = SpringUtils.getBean(BasShuttleOptService.class);
                if (shuttleOptService != null) {
                    BasShuttleOpt opt = new BasShuttleOpt(
                            assignCommand.getTaskNo().intValue(),
                            assignCommand.getShuttleNo().intValue(),
                            new Date(),
                            ShuttleTaskModeType.get(assignCommand.getTaskMode()).desc,
                            assignCommand.getSourceLocNo(),
                            assignCommand.getLocNo(),
                            null,
                            null,
                            null,
                            JSON.toJSONString(assignCommand)
                    );
                    shuttleOptService.insert(opt);
                }
                if (redisCommand.getLiftSecurityMk()) {
                    //曾锁定过提升机,需要进行解锁
@@ -814,7 +855,7 @@
                    }else {
                        shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.CHARGING_WAITING);
                    }
                    News.info("四向穿梭车任务执行完成等待确认中,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(command));
                    News.info("四向穿梭车任务执行下发完成等待执行结束,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(command));
                }
            }
@@ -906,7 +947,7 @@
        String shuttleLocNo = shuttleProtocol.getCurrentLocNo();//二维码对应库位号
        Integer shuttleLocNoLev = shuttleLocNo == null ? 0 : Utils.getLev(shuttleLocNo);//库位号对应层高
        //判断提升机是否在目标楼层
        //判断穿梭车和提升机是否在目标楼层
        if (shuttleLocNoLev >= 2) {
            shuttleLocNoLev++;
        }
@@ -916,7 +957,7 @@
            SiemensDevpThread siemensDevpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1);
            StaProtocol staProtocol = siemensDevpThread.getStation().get(siteNo);
            if (staProtocol.isLiftArrival()
                && liftProtocol.getPositionArrivalFeedback().intValue() == shuttleLocNoLev) {
                && liftProtocol.getPositionArrivalFeedback$() == shuttleLocNoLev) {
                //输送线反馈提升机到位且提升机楼层反馈为同一层,直接放行
                return true;
            }
@@ -1046,7 +1087,7 @@
     * 正常移动命令,默认移动速度1000
     */
    public ShuttleCommand getMoveCommand(Short startCodeNum, Short distCodeNum, Integer startToDistDistance, Short runDirection, Short middleCodeNum, Integer middleToDistDistance) {
        return getMoveCommand(startCodeNum, distCodeNum, startToDistDistance, runDirection, middleCodeNum, middleToDistDistance, 1000);
        return getMoveCommand(startCodeNum, distCodeNum, startToDistDistance, runDirection, middleCodeNum, middleToDistDistance, 500);
    }
    /**