#
Junjie
8 小时以前 6e02d92c3b9c240fa78a343b67ddf0db12d840e6
#
10个文件已修改
397 ■■■■■ 已修改文件
src/main/java/com/zy/asrs/service/impl/ForkMainServiceImpl.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java 90 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/utils/NavigateUtils.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/utils/ShuttleOperaUtils.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/News.java 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/action/ShuttleAction.java 136 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/RedisKeyType.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/task/ShuttleExecuteScheduler.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/impl/TrafficControlImplThread.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/shuttleNew.html 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/ForkMainServiceImpl.java
@@ -187,10 +187,10 @@
            }
            //检测障碍物车
            boolean checkObstacle = shuttleOperaUtils.checkObstacle(wrkMast.getLocNo(), new ArrayList<Integer>() {{
            int checkObstacle = shuttleOperaUtils.checkObstacle(wrkMast.getLocNo(), new ArrayList<Integer>() {{
                add(shuttleProtocol.getShuttleNo());
            }}, new ArrayList<>());
            if (checkObstacle) {
            if (checkObstacle > 0) {
                News.info("{}任务,避障范围有小车,等待障碍小车调离中", wrkMast.getWrkNo());
                return false;
            }
@@ -378,10 +378,10 @@
            //判断小车是否到达货物库位
            if (!shuttleProtocol.getCurrentLocNo().equals(wrkMast.getSourceLocNo())) {
                //检测障碍物车
                boolean checkObstacle = shuttleOperaUtils.checkObstacle(wrkMast.getSourceLocNo(), new ArrayList<Integer>() {{
                int checkObstacle = shuttleOperaUtils.checkObstacle(wrkMast.getSourceLocNo(), new ArrayList<Integer>() {{
                    add(shuttleProtocol.getShuttleNo());
                }}, new ArrayList<>());
                if (checkObstacle) {
                if (checkObstacle > 0) {
                    News.info("{}任务,避障范围有小车,等待障碍小车调离中", wrkMast.getWrkNo());
                    return false;
                }
@@ -520,10 +520,10 @@
            }
            //检测障碍物车
            boolean checkObstacle = shuttleOperaUtils.checkObstacle(wrkMast.getLocNo(), new ArrayList<Integer>() {{
            int checkObstacle = shuttleOperaUtils.checkObstacle(wrkMast.getLocNo(), new ArrayList<Integer>() {{
                add(shuttleProtocol.getShuttleNo());
            }}, new ArrayList<>());
            if (checkObstacle) {
            if (checkObstacle > 0) {
                News.info("{}任务,避障范围有小车,等待障碍小车调离中", wrkMast.getWrkNo());
                return false;
            }
@@ -1390,10 +1390,10 @@
            }
            //检测障碍物车
            boolean checkObstacle = shuttleOperaUtils.checkObstacle(basShuttleCharge.getWaitLocNo(), new ArrayList<Integer>() {{
            int checkObstacle = shuttleOperaUtils.checkObstacle(basShuttleCharge.getWaitLocNo(), new ArrayList<Integer>() {{
                add(shuttleProtocol.getShuttleNo());
            }}, new ArrayList<>());
            if (checkObstacle) {
            if (checkObstacle > 0) {
                News.info("{}任务,避障范围有小车,等待障碍小车调离中", wrkMast.getWrkNo());
                return false;
            }
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -182,10 +182,10 @@
            }
            //检测障碍物车
            boolean checkObstacle = shuttleOperaUtils.checkObstacle(wrkMast.getLocNo(), new ArrayList<Integer>() {{
            int checkObstacle = shuttleOperaUtils.checkObstacle(wrkMast.getLocNo(), new ArrayList<Integer>() {{
                add(shuttleProtocol.getShuttleNo());
            }}, new ArrayList<>());
            if (checkObstacle) {
            if (checkObstacle > 0) {
                News.info("{}任务,避障范围有小车,等待障碍小车调离中", wrkMast.getWrkNo());
                return false;
            }
@@ -373,10 +373,10 @@
            //判断小车是否到达货物库位
            if (!shuttleProtocol.getCurrentLocNo().equals(wrkMast.getSourceLocNo())) {
                //检测障碍物车
                boolean checkObstacle = shuttleOperaUtils.checkObstacle(wrkMast.getSourceLocNo(), new ArrayList<Integer>() {{
                int checkObstacle = shuttleOperaUtils.checkObstacle(wrkMast.getSourceLocNo(), new ArrayList<Integer>() {{
                    add(shuttleProtocol.getShuttleNo());
                }}, new ArrayList<>());
                if (checkObstacle) {
                if (checkObstacle > 0) {
                    News.info("{}任务,避障范围有小车,等待障碍小车调离中", wrkMast.getWrkNo());
                    return false;
                }
@@ -515,10 +515,10 @@
            }
            //检测障碍物车
            boolean checkObstacle = shuttleOperaUtils.checkObstacle(wrkMast.getLocNo(), new ArrayList<Integer>() {{
            int checkObstacle = shuttleOperaUtils.checkObstacle(wrkMast.getLocNo(), new ArrayList<Integer>() {{
                add(shuttleProtocol.getShuttleNo());
            }}, new ArrayList<>());
            if (checkObstacle) {
            if (checkObstacle > 0) {
                News.info("{}任务,避障范围有小车,等待障碍小车调离中", wrkMast.getWrkNo());
                return false;
            }
@@ -1387,10 +1387,10 @@
            }
            //检测障碍物车
            boolean checkObstacle = shuttleOperaUtils.checkObstacle(basShuttleCharge.getWaitLocNo(), new ArrayList<Integer>() {{
            int checkObstacle = shuttleOperaUtils.checkObstacle(basShuttleCharge.getWaitLocNo(), new ArrayList<Integer>() {{
                add(shuttleProtocol.getShuttleNo());
            }}, new ArrayList<>());
            if (checkObstacle) {
            if (checkObstacle > 0) {
                News.info("{}任务,避障范围有小车,等待障碍小车调离中", wrkMast.getWrkNo());
                return false;
            }
@@ -1489,7 +1489,7 @@
            }
            //搜索最近且无故障提升机
            LiftStaProtocol recentLiftStation = liftDispatchUtils.getRecentLiftStation(shuttleProtocol.getShuttleNo(), Utils.getLev(wrkMast.getLocNo()));
            LiftStaProtocol recentLiftStation = liftDispatchUtils.getRecentLiftStation(shuttleProtocol.getShuttleNo(), Utils.getLev(shuttleProtocol.getCurrentLocNo()));
            if(recentLiftStation == null) {
                News.info("{}号小车,{}目标库位,没有可用空闲输送站点", shuttleProtocol.getShuttleNo(), wrkMast.getLocNo());
                return false;
@@ -1499,12 +1499,6 @@
            if(targetLiftSta == null) {
                return false;
            }
            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo()); // 四向穿梭车编号
            assignCommand.setTaskMode(ShuttleTaskModeType.MOVE_LOC_NO.id);//小车移库任务
            assignCommand.setTaskNo(wrkMast.getWrkNo());//任务号
            assignCommand.setAuto(true);//自动模式
            //计算近点位置
            String endLocation = navigateUtils.calcEndLocation(shuttleProtocol.getCurrentLocNo(), recentLiftStation.getLocNo(), NavigationMapType.getMapTypes(NavigationMapType.NORMAL), null, null, 1);
@@ -1523,6 +1517,14 @@
                wrkMastService.updateById(wrkMast);
                return true;
            }
            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo()); // 四向穿梭车编号
            assignCommand.setTaskMode(ShuttleTaskModeType.MOVE_LOC_NO.id);//小车移库任务
            assignCommand.setTaskNo(wrkMast.getWrkNo());//任务号
            assignCommand.setSourceLocNo(shuttleProtocol.getCurrentLocNo());//源库位
            assignCommand.setLocNo(endLocation);
            assignCommand.setAuto(true);//自动模式
            //获取小车到近点行走命令
            List<ShuttleCommand> commands = shuttleOperaUtils.getStartToTargetCommands(shuttleProtocol.getCurrentLocNo(), endLocation, NavigationMapType.getMapTypes(NavigationMapType.NORMAL, NavigationMapType.SHUTTLE), assignCommand, shuttleThread);
@@ -1624,8 +1626,9 @@
                return false;
            }
            Object object = redisUtil.get(RedisKeyType.LIFT_MOVE_TO_SHUTTLE_LIMIT.key + wrkMast.getWrkNo());
            int targetLev = Utils.getLev(shuttleProtocol.getCurrentLocNo());
            if (liftProtocol.getLev() != targetLev) {
            if (object == null || liftProtocol.getLev() != targetLev) {
                //获取提升机命令
                LiftCommand liftCommand = liftThread.getMoveCommand(wrkMast.getWrkNo(), liftProtocol.getLev(), targetLev);
                ArrayList<LiftCommand> commands = new ArrayList<>();
@@ -1640,17 +1643,22 @@
                //下发任务
                liftAction.assignWork(wrkMast.getLiftNo(), assignCommand);
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}号提升机在{}层,提升机不在小车层,调度移动中", wrkMast.getWrkNo(), liftProtocol.getLev(), wrkMast.getLiftNo());
                redisUtil.set(RedisKeyType.LIFT_MOVE_TO_SHUTTLE_LIMIT.key + wrkMast.getWrkNo(), "lift_moving", 60 * 3);
                return false;
            }
            String liftLocNo = liftThread.getCurrentLocNo();
            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo()); // 四向穿梭车编号
            assignCommand.setTaskMode(ShuttleTaskModeType.MOVE_LOC_NO.id);//小车移库任务
            assignCommand.setTaskNo(wrkMast.getWrkNo());//任务号
            assignCommand.setSourceLocNo(shuttleProtocol.getCurrentLocNo());//源库位
            assignCommand.setLocNo(liftLocNo);
            assignCommand.setAuto(true);//自动模式
            //获取小车到提升机行走命令
            List<ShuttleCommand> commands = shuttleOperaUtils.getStartToTargetCommands(shuttleProtocol.getCurrentLocNo(), liftThread.getCurrentLocNo(), NavigationMapType.getNormalWithDevice(), assignCommand, shuttleThread, "inLift");
            List<ShuttleCommand> commands = shuttleOperaUtils.getStartToTargetCommands(shuttleProtocol.getCurrentLocNo(), liftLocNo, NavigationMapType.getNormalWithDevice(), assignCommand, shuttleThread, "inLift");
            if (commands == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车,路径计算失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;//路径解锁失败
@@ -1761,25 +1769,57 @@
                return false;
            }
            if (Utils.getLev(shuttleProtocol.getCurrentLocNo()) != Utils.getLev(wrkMast.getLocNo())) {
                Object object = redisUtil.get(RedisKeyType.SHUTTLE_UPDATE_LOCATION.key + shuttleProtocol.getShuttleNo());
                if(object != null) {
                    return false;
                }
                ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
                assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo()); // 四向穿梭车编号
                assignCommand.setTaskMode(ShuttleTaskModeType.UPDATE_LOCATION.id);//更新坐标
                assignCommand.setTaskNo(wrkMast.getWrkNo());//任务号
                assignCommand.setAuto(true);//自动模式
                assignCommand.setSourceLocNo(shuttleProtocol.getCurrentLocNo());//源库位
                assignCommand.setLocNo(wrkMast.getLocNo());//目标库位
                //更新小车坐标
                ShuttleCommand command = shuttleThread.getUpdateLocationCommand(wrkMast.getWrkNo(), wrkMast.getLocNo());
                ArrayList<ShuttleCommand> commands = new ArrayList<>();
                commands.add(command);
                assignCommand.setCommands(commands);
                //下发任务
                shuttleAction.assignWork(shuttleProtocol.getShuttleNo(), assignCommand);
                redisUtil.set(RedisKeyType.SHUTTLE_UPDATE_LOCATION.key + shuttleProtocol.getShuttleNo(), "update", 10);
                return false;
            }
            String targetLocNo = navigateUtils.calcFirstLocation(shuttleProtocol.getCurrentLocNo(), wrkMast.getLocNo(), NavigationMapType.getMapTypes(NavigationMapType.NORMAL), null, null, 5);
            if (targetLocNo == null) {//出提升机近点计算失败
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车,出提升机近点计算失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;
            }
            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo()); // 四向穿梭车编号
            assignCommand.setTaskMode(ShuttleTaskModeType.UPDATE_LOCATION.id);//更新坐标
            assignCommand.setTaskMode(ShuttleTaskModeType.MOVE_LOC_NO.id);//小车移库任务
            assignCommand.setTaskNo(wrkMast.getWrkNo());//任务号
            assignCommand.setAuto(true);//自动模式
            assignCommand.setSourceLocNo(shuttleProtocol.getCurrentLocNo());//源库位
            assignCommand.setLocNo(wrkMast.getLocNo());//目标库位
            assignCommand.setLocNo(targetLocNo);//目标库位
            //更新小车坐标
            ShuttleCommand command = shuttleThread.getUpdateLocationCommand(wrkMast.getWrkNo(), wrkMast.getLocNo());
            ArrayList<ShuttleCommand> commands = new ArrayList<>();
            commands.add(command);
            //获取小车到近点命令
            List<ShuttleCommand> commands = shuttleOperaUtils.getStartToTargetCommands(shuttleProtocol.getCurrentLocNo(), targetLocNo, NavigationMapType.getMapTypes(NavigationMapType.NORMAL), assignCommand, shuttleThread);
            if (commands == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车,路径计算失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;//路径计算失败
            }
            assignCommand.setCommands(commands);
            wrkMast.setWrkSts(WrkStsType.MOVE_OUT_LIFT.sts);//小车迁出提升机中
            wrkMast.setSystemMsg("");//清空消息
            wrkMast.setModiTime(now);
            if (wrkMastService.updateById(wrkMast)) {
                //下发任务
                shuttleAction.assignWork(shuttleProtocol.getShuttleNo(), assignCommand);
src/main/java/com/zy/common/utils/NavigateUtils.java
@@ -231,6 +231,29 @@
        return findTargetLocation(endPath);
    }
    public String calcFirstLocation(String startPoint, String endPoint, List<NavigationMapType> mapTypes, List<int[]> shuttlePoints, List<int[]> whites, int firstPathNumber) {
        //计算路径
        List<NavigateNode> navigateNodes = calc(startPoint, endPoint, mapTypes, shuttlePoints, whites);
        if (navigateNodes == null) {
            News.error("{} dash {} can't find navigate path!", startPoint, endPoint);
            return null;
        }
        //获取分段路径
        List<List<NavigateNode>> partList = this.getSectionPath(navigateNodes);
        List<NavigateNode> firstList = partList.get(0);
        NavigateNode targetNode = null;
        if(firstList.size() <= firstPathNumber){
            targetNode = firstList.get(firstList.size() - 1);
        }else {
            targetNode = firstList.get(firstPathNumber);
        }
        String locNo = NavigatePositionConvert.nodeToLocNo(targetNode);
        return locNo;
    }
    public String findTargetLocation(List<List<NavigateNode>> partList) {
        List<NavigateNode> nodes = partList.get(partList.size() - 1);
        NavigateNode targetNode = nodes.get(0);
src/main/java/com/zy/common/utils/ShuttleOperaUtils.java
@@ -59,6 +59,8 @@
    }
    public synchronized List<ShuttleCommand> getStartToTargetCommands(String startLocNo, String endLocNo, List<NavigationMapType> mapTypes, List<int[]> whites, ShuttleAssignCommand assignCommand, ShuttleThread shuttleThread, String moveType) {
        long getStartTime = System.currentTimeMillis();
        ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
        if (shuttleProtocol == null) {
            return null;
@@ -99,7 +101,7 @@
        //获取分段路径
        List<List<NavigateNode>> data = navigateUtils.getSectionPath(nodeList);
        long endTime = System.currentTimeMillis();
        News.info("getSection path time:{}", (endTime - startTime));
        News.info("[RCS Debug] getSection path time:{}", (endTime - startTime));
        //将每一段路径分成command指令
        for (int i = 0; i < data.size(); i++) {
            List<NavigateNode> nodes = data.get(i);
@@ -141,6 +143,8 @@
            }
        }
        assignCommand.setShuttleMoveCommandsContinuously(shuttleMoveCommandsContinuously);
        News.info("{}任务,{}小车,{} - {} 路径命令包计算成功,耗时:{}ms", assignCommand.getTaskNo(), shuttleProtocol.getShuttleNo(), startLocNo, endLocNo, System.currentTimeMillis() - startTime);
        return commands;
    }
@@ -168,8 +172,11 @@
        return commands;
    }
    //检测障碍物车
    public synchronized boolean checkObstacle(String locNo, List<Integer> whiteShuttles, List<NavigateNode> whiteNodes) {
    /**
     * 检测障碍物车
     * @return 0:无障碍 1:有障碍调度成功 2:有障碍调度失败
     */
    public synchronized int checkObstacle(String locNo, List<Integer> whiteShuttles, List<NavigateNode> whiteNodes) {
        int innerCircle = 0;
        int outerCircle = 3;
        Config avoidInnerCircleConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "avoidInnerCircle"));
@@ -202,7 +209,7 @@
        List<NavigateNode> innerNodes = getInnerNodes(locNo, innerCircle, whiteShuttlePointList);
        List<Integer> nodesCar = findNodesCar(innerNodes);
        if (nodesCar.isEmpty()) {
            return false;//内圈中无车
            return 0;//内圈中无车
        }
        //获取外圈节点
@@ -239,10 +246,11 @@
            if (targetLocNo == null) {
                continue;
            }
            shuttleDispatchUtils.dispatchShuttle(null, targetLocNo, shuttleNo);
            boolean dispatched = shuttleDispatchUtils.dispatchShuttle(null, targetLocNo, shuttleNo);
            return dispatched ? 1 : 2;
        }
        return true;//内圈中有车
        return 2;//内圈中有车
    }
    private HashMap<String, Integer> findCarMap() {
src/main/java/com/zy/core/News.java
@@ -1,8 +1,13 @@
package com.zy.core;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.SpringUtils;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.service.WrkMastService;
import com.zy.common.utils.RedisUtil;
import com.zy.core.enums.RedisKeyType;
import com.zy.system.entity.Config;
import com.zy.system.service.ConfigService;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Array;
@@ -98,16 +103,94 @@
    }
    public static void info(String format, Object... arguments) {
        if (format.contains("[RCS Debug]")) {
            ConfigService configService = SpringUtils.getBean(ConfigService.class);
            if(configService != null) {
                boolean show = true;
                Config config = configService.selectOne(new EntityWrapper<Config>().eq("code", "rcsDebugShowLog"));
                if(config != null) {
                    show = config.getValue().equals("true");
                }
                if (!show) {
                    return;
                }
            }
        }
        RedisUtil redisUtil = null;
        try {
            redisUtil = SpringUtils.getBean(RedisUtil.class);
            if(redisUtil != null) {
                Object object = redisUtil.get(RedisKeyType.LOG_LIMIT.key + format);
                if (object != null) {
                    return;
                }
                redisUtil.set(RedisKeyType.LOG_LIMIT.key + format, "lock", 3);
            }
        }catch (Exception e) {}
        log.info(format, arguments);
        offer(NewsLevel.INFO, format, arguments);
    }
    public static void warn(String format, Object... arguments) {
        if (format.contains("[RCS Debug]")) {
            ConfigService configService = SpringUtils.getBean(ConfigService.class);
            if(configService != null) {
                boolean show = true;
                Config config = configService.selectOne(new EntityWrapper<Config>().eq("code", "rcsDebugShowLog"));
                if(config != null) {
                    show = config.getValue().equals("true");
                }
                if (!show) {
                    return;
                }
            }
        }
        RedisUtil redisUtil = null;
        try {
            redisUtil = SpringUtils.getBean(RedisUtil.class);
            if(redisUtil != null) {
                Object object = redisUtil.get(RedisKeyType.LOG_LIMIT.key + format);
                if (object != null) {
                    return;
                }
                redisUtil.set(RedisKeyType.LOG_LIMIT.key + format, "lock", 3);
            }
        }catch (Exception e) {}
        log.warn(format, arguments);
        offer(NewsLevel.WARN, format, arguments);
    }
    public static void error(String format, Object... arguments) {
        if (format.contains("[RCS Debug]")) {
            ConfigService configService = SpringUtils.getBean(ConfigService.class);
            if(configService != null) {
                boolean show = true;
                Config config = configService.selectOne(new EntityWrapper<Config>().eq("code", "rcsDebugShowLog"));
                if(config != null) {
                    show = config.getValue().equals("true");
                }
                if (!show) {
                    return;
                }
            }
        }
        RedisUtil redisUtil = null;
        try {
            redisUtil = SpringUtils.getBean(RedisUtil.class);
            if(redisUtil != null) {
                Object object = redisUtil.get(RedisKeyType.LOG_LIMIT.key + format);
                if (object != null) {
                    return;
                }
                redisUtil.set(RedisKeyType.LOG_LIMIT.key + format, "lock", 3);
            }
        }catch (Exception e) {}
        log.error(format, arguments);
        offer(NewsLevel.ERROR, format, arguments);
    }
src/main/java/com/zy/core/action/ShuttleAction.java
@@ -119,10 +119,10 @@
            return false;
        }
        News.info("execute check command {},{}", shuttleNo, taskNo);
        News.info("[RCS Debug] Execute check command {},{}", shuttleNo, taskNo);
        //检测命令
        int checked = checkCommand(redisCommand, shuttleNo);
        News.info("execute check command complete {},{}", shuttleNo, taskNo);
        News.info("[RCS Debug] Execute check command complete {},{}", shuttleNo, taskNo);
        if (checked == 0) {
            return false;
        }
@@ -171,24 +171,19 @@
            Object object = redisUtil.get(RedisKeyType.TRAFFIC_CONTROL_LOCK_APPLY.key + shuttleNo);
            if (object == null) {
                //申请管制
                News.info("execute apply control {},{}", shuttleNo, taskNo);
                News.info("[RCS Debug] Execute apply control {},{}", shuttleNo, taskNo);
                redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_LOCK_APPLY.key + shuttleNo, "lock", 10);
                applyTrafficControl(commands, nodes, shuttleNo, taskNo);
                News.info("execute apply control complete {},{}", shuttleNo, taskNo);
                News.info("[RCS Debug] Execute apply control complete {},{}", shuttleNo, taskNo);
            }
            News.info("execute query control {},{}", shuttleNo, taskNo);
            News.info("[RCS Debug] Execute query control {},{}", shuttleNo, taskNo);
            //查询管制
            boolean apply = queryTrafficControl(shuttleNo, taskNo);
            News.info("execute query control complete {},{}", shuttleNo, taskNo);
            News.info("[RCS Debug] Execute query control complete {},{}", shuttleNo, taskNo);
            if(!apply){
                return false;//申请失败
            }
//            //检测路径是否冲突
//            int conflict = searchShuttlePathConflict(nodes, shuttleNo);
//            if(conflict == 2){
//                return false;//检测后有冲突
//            }
            if (checked == 2) {
                nodes.remove(0);
@@ -203,10 +198,10 @@
            }
        }
        News.info("execute send command {},{}", shuttleNo, taskNo);
        News.info("[RCS Debug] Execute send command {},{}", shuttleNo, taskNo);
        // 下发命令
        CommandResponse response = write(command, shuttleNo);
        News.info("execute send command complete {},{}", shuttleNo, taskNo);
        News.info("[RCS Debug] Execute send command complete {},{}", shuttleNo, taskNo);
        //保存命令日志
        BasShuttleOpt basShuttleOpt = new BasShuttleOpt();
@@ -342,16 +337,24 @@
            // 系统任务
            if (assignCommand.getAuto()) {
                if (!assignCommand.getCharge()) {
                    //对主线程抛出等待确认状态waiting
                    shuttleThread.setProtocolStatus(ShuttleProtocolStatusType.WAITING);
                } else {
                    shuttleThread.setProtocolStatus(ShuttleProtocolStatusType.CHARGING_WAITING);
                if (assignCommand.getTaskMode() == ShuttleTaskModeType.UPDATE_LOCATION.id) {//更新坐标无需等待确认
                    //直接复位空闲状态
                    shuttleThread.setProtocolStatus(ShuttleProtocolStatusType.IDLE);
                    //任务号清零
                    shuttleThread.setSyncTaskNo(0);
                    //标记复位
                    shuttleThread.setPakMk(true);
                    News.info("四向穿梭车更新坐标任务执行完成,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(endCommand));
                }else {
                    if (!assignCommand.getCharge()) {
                        //对主线程抛出等待确认状态waiting
                        shuttleThread.setProtocolStatus(ShuttleProtocolStatusType.WAITING);
                    } else {
                        shuttleThread.setProtocolStatus(ShuttleProtocolStatusType.CHARGING_WAITING);
                    }
                    News.info("四向穿梭车任务执行下发完成等待执行结束,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(endCommand));
                }
                News.info("四向穿梭车任务执行下发完成等待执行结束,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(endCommand));
                // 手动任务
            } else {
            } else {// 手动任务
                //手动模式不抛出等待状态,直接复位空闲状态
                shuttleThread.setProtocolStatus(ShuttleProtocolStatusType.IDLE);
                //任务号清零
@@ -430,9 +433,9 @@
                return false;
            }
            //上报交管
            News.info("execute check command report traffic {},{}", shuttleNo, shuttleProtocol.getTaskNo());
            News.info("[RCS Debug] Execute check command report traffic {},{}", shuttleNo, shuttleProtocol.getTaskNo());
            trafficControlThread.trafficReport(command.getNodesDeepCopy(), shuttleNo, shuttleProtocol.getTaskNo());
            News.info("execute check command report traffic complete {},{}", shuttleNo, shuttleProtocol.getTaskNo());
            News.info("[RCS Debug] Execute check command report traffic complete {},{}", shuttleNo, shuttleProtocol.getTaskNo());
            String currentLocNo = shuttleProtocol.getCurrentLocNo();
            if (currentLocNo == null) {
@@ -528,91 +531,6 @@
        redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_CANCEL_LIST.key + shuttleNo + "_" + taskNo, model);
        return true;
    }
//    /**
//     * 搜索小车路径是否存在冲突
//     * 0:未检测 1:检测无冲突 2:检测有冲突
//     */
//    public int searchShuttlePathConflict(List<NavigateNode> nodeList, Integer shuttleNo) {
//        ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo);
//        if (shuttleThread == null) {
//            return 0;
//        }
//
//        ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
//        if (shuttleProtocol == null) {
//            return 0;
//        }
//
//        int lev = Utils.getLev(shuttleProtocol.getCurrentLocNo());
//
//        TrafficControlThread trafficControlThread = (TrafficControlThread) SlaveConnection.get(SlaveType.TrafficControl, 1);
//        if (trafficControlThread == null) {
//            return 2;
//        }
//        HashMap<String, List<Integer>> nodeMap = trafficControlThread.getNodesMapByLev(lev);
//        if (nodeMap == null || nodeMap.isEmpty()) {
//            return 2;
//        }
//
//        List<String> conflictLocList = new ArrayList<>();
//        for (NavigateNode node : nodeList) {
//            String locNo = Utils.getLocNo(node.getX(), node.getY(), lev);
//            if(!nodeMap.containsKey(locNo)) {
//                return 2;
//            }
//
//            List<Integer> shuttleNos = nodeMap.get(locNo);
//            if (shuttleNos.size() > 1) {
//                //路径存在多车,冲突
//                conflictLocList.add(locNo);
//            }
//        }
//
//        if (conflictLocList.isEmpty()) {
//            //无冲突,解除交通管制
//            shuttleThread.setTrafficControl(false, null);
//            return 1;//检测后无冲突
//        }
//
//        //路径存在冲突,检测可执行车辆是否为当前小车
//        //上报小车状态-交通管制中
//        shuttleThread.setTrafficControl(true, nodeList);
//
//        HashMap<String, Integer> deviceMap = trafficControlThread.getDeviceMap();
//        if(deviceMap == null) {
//            return 2;
//        }
//
//        boolean detected = false;
////            for (Map.Entry<String, Integer> entry : deviceMap.entrySet()) {
////                List<String> mainList = JSON.parseArray(entry.getKey(), String.class);
////                Integer device = entry.getValue();
////                if(result) {
////                    //判断管制车辆是否匹配
////                    if(shuttleNo.equals(device)) {
////                        detected = true;
////                        break;
////                    }
////                }
////            }
//
//        for (Map.Entry<String, Integer> entry : deviceMap.entrySet()) {
//            String key = entry.getKey();
//            Integer value = entry.getValue();
//            if(shuttleNo.equals(value)) {
//                //判断管制车辆是否匹配
//                detected = true;
//                break;
//            }
//        }
//
//        if (detected) {
//            return 1;//检测后无冲突,交通管制已允许此小车运行
//        }
//
//        return 2;//检测后有冲突
//    }
    //演示模式
    public synchronized void demo(Integer shuttleNo) {
src/main/java/com/zy/core/enums/RedisKeyType.java
@@ -19,6 +19,11 @@
    //小车重新规划路径频率
    SHUTTLE_RESTART_CALC_PATH("shuttle_restart_calc_path_"),
    //小车更新楼层坐标频率
    SHUTTLE_UPDATE_LOCATION("shuttle_update_location_"),
    //提升机移动至小车层频率
    LIFT_MOVE_TO_SHUTTLE_LIMIT("lift_move_to_shuttle_LIMIT_"),
    //交管信息
    TRAFFIC_CONTROL_MAP("traffic_control_map"),
@@ -46,6 +51,8 @@
    DEVICE_CONFIG("deviceConfig"),
    //虚拟设备配置文件
    FAKE_DEVICE_CONFIG("fakeDeviceConfig"),
    LOG_LIMIT("log_limit_"),
    ;
    public String key;
src/main/java/com/zy/core/task/ShuttleExecuteScheduler.java
@@ -70,7 +70,7 @@
                            if (taskNo != 0) {
                                //存在任务需要执行
                                long startTime = System.currentTimeMillis();
                                News.info("execute {},{}", deviceConfig.getDeviceNo(), taskNo);
                                News.info("[RCS Debug] Execute {},{}", deviceConfig.getDeviceNo(), taskNo);
                                // 在循环中使用
                                boolean result = TimeoutExecutor.executeWithTimeout(
                                        () -> shuttleAction.executeWork(deviceConfig.getDeviceNo(), taskNo),
@@ -78,7 +78,7 @@
                                        TimeUnit.SECONDS
                                );
                                Thread.sleep(100);
                                News.info("execute end {},{},{}", deviceConfig.getDeviceNo(), taskNo, System.currentTimeMillis() - startTime);
                                News.info("[RCS Debug] Execute end {},{},{}", deviceConfig.getDeviceNo(), taskNo, System.currentTimeMillis() - startTime);
                            }
                        }
                    }catch (Exception e){
src/main/java/com/zy/core/thread/impl/TrafficControlImplThread.java
@@ -174,10 +174,14 @@
                        Long idleTime = pathIdleShuttleMap.get(shuttleProtocol.getShuttleNo());
                        if((System.currentTimeMillis() - idleTime) > 1000 * 10) {
                            //检测障碍物车
                            boolean checkObstacle = shuttleOperaUtils.checkObstacle(shuttleProtocol.getCurrentLocNo(), new ArrayList<Integer>() {{
                            int checkObstacle = shuttleOperaUtils.checkObstacle(shuttleProtocol.getCurrentLocNo(), new ArrayList<Integer>() {{
                                add(shuttleNo);
                            }}, totalNodeList);
                            pathIdleShuttleMap.remove(shuttleProtocol.getShuttleNo());
                            if (checkObstacle == 2) {
                                pathShuttleThread.restartCalcPath();
                            }
                        }
                    }else {
                        pathIdleShuttleMap.put(shuttleProtocol.getShuttleNo(), System.currentTimeMillis());
@@ -198,6 +202,10 @@
                }
                if(totalLocList.contains(locNo)) {
                    String first = totalLocList.get(0);
                    if(first.equals(locNo)) {//filter first node
                       continue;
                    }
                    return false;
                }
            }
@@ -211,7 +219,7 @@
        applyRecordsMap.remove(shuttleNo);
        redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_SUCCESS_APPLY.key + shuttleNo + "_" + taskNo, 1, 60 * 60);
        News.info("receipt traffic {},{}", shuttleNo, taskNo);
        News.info("[RCS Debug] receipt traffic {},{}", shuttleNo, taskNo);
        return true;
    }
@@ -335,7 +343,7 @@
    public synchronized boolean operateTrafficControl(OperateTrafficControlParam param) {
        long startTime = System.currentTimeMillis();
        String operaType = param.getOperaType();
        News.info("Operate Traffic Control is Start " + operaType);
        News.info("[RCS Debug] Operate Traffic Control is Start " + operaType);
        boolean result = false;
        if (operaType.equals("add")) {
@@ -354,7 +362,7 @@
                        new ArrayList<>(model.getTotalNodeList())
                ))
                .collect(Collectors.toList());
        News.info("Operate Traffic Control is end " + (System.currentTimeMillis() - startTime) + "ms");
        News.info("[RCS Debug] Operate Traffic Control is end " + (System.currentTimeMillis() - startTime) + "ms");
        return result;
    }
src/main/webapp/views/shuttleNew.html
@@ -571,7 +571,7 @@
                    requestParam.shuttleTaskMode = 17;
                }else if (type == 'writeTaskNo') {
                    requestParam.workNo = this.controlData.taskNo;
                    requestParam.pakMk = null;
                    requestParam.pakMk = "Y";
                    $.ajax({
                        url: baseUrl + "/shuttle/detl/update",