#
Junjie
22 小时以前 6694bb8752aced4b818f2976442d66ae3a52e9e8
#
12个文件已修改
569 ■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/ShuttleController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/utils/Utils.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/utils/NavigateMapData.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/utils/ShuttleOperaUtils.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/action/ShuttleAction.java 36 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/RedisKeyType.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/command/ShuttleAssignCommand.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/command/ShuttleRedisCommand.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/ShuttleThread.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/TrafficControlThread.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/impl/NyShuttleThread.java 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/impl/TrafficControlImplThread.java 252 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/ShuttleController.java
@@ -348,7 +348,7 @@
        } else if (shuttleTaskModeType == ShuttleTaskModeType.RESET) {
            //复位
            TrafficControlThread trafficControlThread = (TrafficControlThread) SlaveConnection.get(SlaveType.TrafficControl, 1);
            trafficControlThread.cancelTrafficControl(shuttleProtocol.getShuttleNo(), shuttleProtocol.getTaskNo());
            trafficControlThread.forceCancelTrafficControl(shuttleProtocol.getShuttleNo());
            shuttleThread.setSyncTaskNo(0);//工作号清空
            shuttleThread.setProtocolStatus(ShuttleProtocolStatusType.IDLE);//任务状态-空闲
src/main/java/com/zy/asrs/utils/Utils.java
@@ -84,7 +84,7 @@
        return null;
    }
    //获取除白名单外的指定楼层全部穿梭车xy坐标点
    //获取穿梭车xy坐标点
    public static int[] getShuttlePoint(Integer shuttleNo) {
        //获取穿梭车所在节点位置
        ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo);
@@ -147,6 +147,34 @@
        return list;
    }
    public static ShuttleThread searchShuttle(String locNo) {
        DeviceConfigService deviceConfigService = SpringUtils.getBean(DeviceConfigService.class);
        List<DeviceConfig> shuttleList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
                .eq("device_type", String.valueOf(SlaveType.Shuttle)));
        for (DeviceConfig device : shuttleList) {
            //获取穿梭车所在节点位置
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, device.getDeviceNo());
            if (shuttleThread == null) {
                continue;
            }
            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
            if (shuttleProtocol == null) {
                continue;
            }
            String currentLocNo = shuttleProtocol.getCurrentLocNo();
            if (currentLocNo == null) {
                continue;
            }
            if (currentLocNo.equals(locNo)) {
                return shuttleThread;
            }
        }
        return null;
    }
    //检测楼层是否有可用穿梭车
    public static boolean checkLevHasShuttle(Integer lev) {
        DeviceConfigService deviceConfigService = SpringUtils.getBean(DeviceConfigService.class);
src/main/java/com/zy/common/utils/NavigateMapData.java
@@ -202,10 +202,10 @@
                lists = loadPathLock(lists, lev);
            }
            if(mapType.equals(NavigationMapType.TRAFFIC_CONTROL)) {
                //加载交通管制
                lists = loadTrafficControl(lists, lev);
            }
//            if(mapType.equals(NavigationMapType.TRAFFIC_CONTROL)) {
//                //加载交通管制
//                lists = loadTrafficControl(lists, lev);
//            }
        }
        //加载白名单节点
@@ -444,77 +444,6 @@
                    lists.set(row, list);
                }
            }
//            HashMap<String, Integer> deviceMap = trafficControlThread.getDeviceMap();
//            if(deviceMap == null) {
//                throw new CoolException("get traffic control device map error");
//            }
//
//            for (Map.Entry<String, Integer> entry : deviceMap.entrySet()) {
//                String key = entry.getKey();
//                Integer shuttleNo = entry.getValue();
//                if (shuttleNo <= 0) {
//                    continue;
//                }
//
//                Object object = redisUtil.get(RedisKeyType.SHUTTLE_FLAG.key + shuttleNo);
//                if (object == null) {
//                    continue;
//                }
//
//                int taskNo = Integer.parseInt(String.valueOf(object));
//
//                Object obj = redisUtil.get(RedisKeyType.SHUTTLE_WORK_FLAG.key + taskNo);
//                if (obj == null) {
//                    continue;
//                }
//
//                ShuttleRedisCommand redisCommand = null;
//                try {
//                    redisCommand = objectMapper.readValue(String.valueOf(obj), ShuttleRedisCommand.class);
//                } catch (IOException e) {
//                    throw new RuntimeException(e);
//                }
//
//                if (redisCommand == null) {
//                    continue;
//                }
//
//                ShuttleAssignCommand assignCommand = redisCommand.getAssignCommand();
//                List<ShuttleCommand> commands = assignCommand.getCommands();
//
//                List<NavigateNode> controlLocList = new ArrayList<>();
//                for (ShuttleCommand command : commands) {
//                    if (command.getComplete()) {
//                        continue;
//                    }
//
//                    if (command.getMode() == ShuttleCommandModeType.MOVE.id) {
//                        List<NavigateNode> nodes = command.getNodes();
//                        for (NavigateNode node : nodes) {
//                            if(!controlLocList.contains(node)) {
//                                controlLocList.add(node);
//                            }
//                        }
//                    }
//                }
//
//                for (NavigateNode node : controlLocList) {
//                    int row = node.getX();
//                    int bay = node.getY();
//
//                    List<MapNode> list = lists.get(row);
//                    MapNode mapNode = list.get(bay);
//
//                    //节点设置成Disable
//                    mapNode.setValue(MapNodeType.DISABLE.id);
//
//                    //更新list
//                    list.set(bay, mapNode);
//                    lists.set(row, list);
//                }
//
//            }
        } catch (Exception e) {
            e.printStackTrace();
        }
src/main/java/com/zy/common/utils/ShuttleOperaUtils.java
@@ -115,6 +115,7 @@
        }
        assignCommand.setNodes(allNode);//当前任务所占用的节点list
        assignCommand.setMapTypes(mapTypes);
        //小车移动连续下发指令
        boolean shuttleMoveCommandsContinuously = false;
@@ -125,67 +126,6 @@
            }
        }
        assignCommand.setShuttleMoveCommandsContinuously(shuttleMoveCommandsContinuously);
        return commands;
    }
    public synchronized List<ShuttleCommand> shuttleInOutLiftCommand(String startLocNo, String endLocNo, List<NavigationMapType> mapTypes, ShuttleAssignCommand assignCommand, ShuttleThread shuttleThread) {
        NavigateNode startNode = NavigatePositionConvert.locNoToNode(startLocNo);
        NavigateNode endNode = NavigatePositionConvert.locNoToNode(endLocNo);
        List<NavigateNode> unlockPath = new ArrayList<>();
        unlockPath.add(startNode);
        unlockPath.add(endNode);
        ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
        if (shuttleProtocol == null) {
            return null;
        }
        Integer shuttleNo = shuttleProtocol.getShuttleNo();
        //所使用的路径进行锁定/解锁
        boolean lockResult = navigateMapUtils.writeNavigateNodeToRedisMap(Utils.getLev(endLocNo), shuttleProtocol.getShuttleNo(), unlockPath, false);//所使用的路径进行解锁
        if (!lockResult) {
            News.error("{} dash {} can't find unlock path!", startLocNo, endLocNo);
            shuttleThread.offerSystemMsg("{} dash {} can't find unlock path!", startLocNo, endLocNo);
            return null;//解锁失败
        }
        //获取小车移动速度
        Integer runSpeed = Optional.ofNullable(basShuttleService.selectOne(new EntityWrapper<BasShuttle>().eq("shuttle_no", shuttleNo)).getRunSpeed()).orElse(1000);
        List<NavigateNode> nodeList = navigateUtils.calc(startLocNo, endLocNo, mapTypes, Utils.getShuttlePoints(shuttleNo, Utils.getLev(startLocNo)), null);
        if (nodeList == null) {
            News.error("{} dash {} can't find navigate path!", startLocNo, endLocNo);
            shuttleThread.offerSystemMsg("{} dash {} can't find navigate path!", startLocNo, endLocNo);
            return null;
        }
        List<NavigateNode> allNode = new ArrayList<>();
        for (NavigateNode node : nodeList) {
            allNode.add(node.clone());
        }
        List<ShuttleCommand> commands = new ArrayList<>();
        //获取分段路径
        List<List<NavigateNode>> data = navigateUtils.getSectionPath(nodeList);
        //将每一段路径分成command指令
        for (List<NavigateNode> nodes : data) {
            //开始路径
            NavigateNode startPath = nodes.get(0);
            //目标路径
            NavigateNode endPath = nodes.get(nodes.size() - 1);
            Integer allDistance = navigateUtils.getCurrentPathAllDistance(nodes);//计算当前路径行走总距离
            //通过xy坐标小车二维码
            String startCodeNum = NavigatePositionConvert.xyToPosition(startPath.getX(), startPath.getY(), startPath.getZ());
            //通过xy坐标小车二维码
            String distCodeNum = NavigatePositionConvert.xyToPosition(endPath.getX(), endPath.getY(), endPath.getZ());
            //获取移动命令
            ShuttleCommand command = shuttleThread.getMoveCommand(assignCommand.getDeviceTaskNo(), startCodeNum, distCodeNum, allDistance, ShuttleRunDirection.get(startPath.getDirection()).id.intValue(), runSpeed, nodes);
            command.setNodes(nodes);//将行走节点添加到每一步命令中
            commands.add(command);
        }
        assignCommand.setNodes(allNode);//当前任务所占用的节点list
        return commands;
    }
src/main/java/com/zy/core/action/ShuttleAction.java
@@ -16,14 +16,12 @@
import com.zy.common.model.NavigateNode;
import com.zy.common.service.CommonService;
import com.zy.common.utils.NavigateMapUtils;
import com.zy.common.utils.NavigatePositionConvert;
import com.zy.common.utils.RedisUtil;
import com.zy.core.News;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.dispatcher.ShuttleDispatchUtils;
import com.zy.core.enums.*;
import com.zy.core.model.CommandResponse;
import com.zy.core.model.TrafficControlDataModel;
import com.zy.core.model.command.ShuttleAssignCommand;
import com.zy.core.model.command.ShuttleCommand;
import com.zy.core.model.command.ShuttleRedisCommand;
@@ -420,25 +418,8 @@
            if (trafficControlThread == null) {
                return false;
            }
            TrafficControlDataModel trafficControlDataModel = trafficControlThread.queryTrafficControl(shuttleNo);
            if (trafficControlDataModel != null) {
                //有管制信息,进行检测
                if (!trafficControlDataModel.getTaskNo().equals(shuttleProtocol.getTaskNo())) {
                    return false;//任务不一致
                }
                //检测是否到终点
                List<NavigateNode> totalNodeList = trafficControlDataModel.getTotalNodeList();
                NavigateNode trafficTargetNode = totalNodeList.get(totalNodeList.size() - 1);
                String trafficTargetLoc = Utils.getLocNo(trafficTargetNode.getX(), trafficTargetNode.getY(), trafficTargetNode.getZ());
                //判断小车是否到终点
                if(shuttleProtocol.getCurrentLocNo().equals(trafficTargetLoc)) {
                    //上报交管
                    trafficControlThread.trafficReport(command.getNodesDeepCopy(), shuttleNo, shuttleProtocol.getTaskNo());
                }
            }
            //上报交管
            trafficControlThread.trafficReport(command.getNodesDeepCopy(), shuttleNo, shuttleProtocol.getTaskNo());
            String currentLocNo = shuttleProtocol.getCurrentLocNo();
            if (targetPoints.contains(Utils.getRow(currentLocNo) + "-" + Utils.getBay(currentLocNo))) {
@@ -503,19 +484,12 @@
            return false;
        }
        NavigateNode startNode = nodeList.get(0);
        Long linePartFlag = startNode.getLinePartFlag();
        List<NavigateNode> totalNodeList = new ArrayList<>();
        for (ShuttleCommand command : commands) {
            if (command.getMode() == ShuttleCommandModeType.MOVE.id) {
                NavigateNode node = command.getNodes().get(0);
                Long nodeLinePartFlag = node.getLinePartFlag();
                if (nodeLinePartFlag.equals(linePartFlag)) {
                    List<NavigateNode> deepCopy = command.getNodesDeepCopy();
                    if (deepCopy != null) {
                        totalNodeList.addAll(deepCopy);
                    }
                List<NavigateNode> deepCopy = command.getNodesDeepCopy();
                if (deepCopy != null) {
                    totalNodeList.addAll(deepCopy);
                }
            }
        }
src/main/java/com/zy/core/enums/RedisKeyType.java
@@ -16,9 +16,11 @@
    //小车下发指令索引
    SHUTTLE_SEND_COMMAND_INDEX("shuttle_send_command_index_"),
    //小车重新规划路径频率
    SHUTTLE_RESTART_CALC_PATH("shuttle_restart_calc_path_"),
    //任务堵塞可用设备地图
    TASK_BLOCK_ENABLE_DEVICE_MAP("task_block_enable_device_map"),
    //交管信息
    TRAFFIC_CONTROL_MAP("traffic_control_map"),
    //地图锁定节点
    LOCK_MAP_NODES("lock_map_nodes_"),
src/main/java/com/zy/core/model/command/ShuttleAssignCommand.java
@@ -1,6 +1,7 @@
package com.zy.core.model.command;
import com.zy.common.model.NavigateNode;
import com.zy.common.model.enums.NavigationMapType;
import lombok.Data;
import java.io.Serializable;
@@ -77,6 +78,9 @@
     */
    private List<NavigateNode> nodes;
    //命令使用的地图类型
    private List<NavigationMapType> mapTypes;
    //小车移动连续下发指令
    private Boolean shuttleMoveCommandsContinuously;
src/main/java/com/zy/core/model/command/ShuttleRedisCommand.java
@@ -22,7 +22,4 @@
    //命令
    private ShuttleAssignCommand assignCommand;
    //提升机安全锁定标记
    private Boolean liftSecurityMk = false;
}
src/main/java/com/zy/core/thread/ShuttleThread.java
@@ -76,6 +76,8 @@
    JSONObject parseStatusToMsg(ShuttleProtocol shuttleProtocol);
    boolean restartCalcPath();
    //***************获取命令*****************
    ShuttleCommand getMoveCommand(Integer taskNo, String startCodeNum, String distCodeNum, Integer allDistance, Integer runDirection, Integer runSpeed, List<NavigateNode> nodes);//获取移动命令
src/main/java/com/zy/core/thread/TrafficControlThread.java
@@ -24,6 +24,8 @@
    boolean cancelTrafficControl(Integer shuttleNo, Integer taskNo);
    boolean forceCancelTrafficControl(Integer shuttleNo);
    TrafficControlDataModel queryTrafficControl(Integer shuttleNo);
    List<TrafficControlDataModel> getAllTrafficControl();
src/main/java/com/zy/core/thread/impl/NyShuttleThread.java
@@ -20,8 +20,11 @@
import com.zy.common.utils.NavigateMapData;
import com.zy.common.utils.NavigatePositionConvert;
import com.zy.common.utils.RedisUtil;
import com.zy.common.utils.ShuttleOperaUtils;
import com.zy.core.News;
import com.zy.core.action.ShuttleAction;
import com.zy.core.model.DeviceCommandMsgModel;
import com.zy.core.model.command.ShuttleAssignCommand;
import com.zy.core.utils.DeviceMsgUtils;
import com.zy.core.cache.OutputQueue;
import com.zy.core.enums.*;
@@ -852,6 +855,94 @@
    }
    @Override
    public boolean restartCalcPath() {
        ConfigService configService = SpringUtils.getBean(ConfigService.class);
        if (configService == null) {
            return false;
        }
        ShuttleAction shuttleAction = SpringUtils.getBean(ShuttleAction.class);
        if (shuttleAction == null) {
            return false;
        }
        ShuttleOperaUtils shuttleOperaUtils = SpringUtils.getBean(ShuttleOperaUtils.class);
        if (shuttleOperaUtils == null) {
            return false;
        }
        ObjectMapper objectMapper = SpringUtils.getBean(ObjectMapper.class);
        if (objectMapper == null) {
            return false;
        }
        boolean trafficControlRestartCalcPath = false;
        Config trafficControlRestartCalcPathConfig = configService.selectOne(new EntityWrapper<Config>()
                .eq("code", "trafficControlRestartCalcPath")
        );
        if(trafficControlRestartCalcPathConfig != null) {
            trafficControlRestartCalcPath = trafficControlRestartCalcPathConfig.getValue().equals("Y") ? true : false;
        }
        if (!trafficControlRestartCalcPath) {
            return false;
        }
        if (shuttleProtocol.getTaskNo() == 0) {
            return false;
        }
        if (!this.isDeviceIdle()) {
            return false;
        }
        Object object = redisUtil.get(RedisKeyType.SHUTTLE_RESTART_CALC_PATH.key + shuttleProtocol.getShuttleNo());
        if (object != null) {
            return false;
        }
        Integer taskNo = shuttleProtocol.getTaskNo();
        Object obj = redisUtil.get(RedisKeyType.SHUTTLE_WORK_FLAG.key + taskNo);
        if (obj == null) {
            return false;
        }
        ShuttleRedisCommand redisCommand = null;
        try {
            redisCommand = objectMapper.readValue(String.valueOf(obj), ShuttleRedisCommand.class);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        if (redisCommand == null) {
            return false;
        }
        ShuttleAssignCommand assignCommand = redisCommand.getAssignCommand();
        String locNo = assignCommand.getLocNo();
        List<NavigationMapType> mapTypes = assignCommand.getMapTypes();
        if (locNo == null) {
            return false;
        }
        if (mapTypes == null) {
            return false;
        }
        String currentLocNo = shuttleProtocol.getCurrentLocNo();
        List<ShuttleCommand> commands = shuttleOperaUtils.getStartToTargetCommands(currentLocNo, locNo, mapTypes, assignCommand, this);
        if (commands == null) {
            return false;
        }
        assignCommand.setCommands(commands);
        //下发任务
        shuttleAction.assignWork(shuttleProtocol.getShuttleNo(), assignCommand);
        redisUtil.set(RedisKeyType.SHUTTLE_RESTART_CALC_PATH.key + shuttleProtocol.getShuttleNo(), true, 60);
        return true;
    }
    @Override
    public ShuttleCommand getMoveCommand(Integer taskNo, String startCodeNum, String distCodeNum, Integer allDistance, Integer runDirection, Integer runSpeed, List<NavigateNode> nodes) {
        NavigateMapData navigateMapData = SpringUtils.getBean(NavigateMapData.class);
        NyShuttleHttpCommand httpStandard = getHttpStandard(deviceConfig.getDeviceNo(), taskNo);
src/main/java/com/zy/core/thread/impl/TrafficControlImplThread.java
@@ -33,6 +33,9 @@
    private Long detectTime = System.currentTimeMillis();
    private HashMap<String, Integer> deviceMap = null;
    private HashMap<Integer, HashMap<String, List<Integer>>> levNodesMap = null;
    private HashMap<Integer,Long> applyRecordsMap = new HashMap<>();
    private HashMap<String, List<NavigateNode>> taskNodesMap = new HashMap<>();
    private List<TrafficControlDataModel> trafficControlDataList = new ArrayList<>();
@@ -42,6 +45,12 @@
    @Override
    public void run() {
        //从缓存恢复交管信息
        Object object = redisUtil.get(RedisKeyType.TRAFFIC_CONTROL_MAP.key);
        if(object != null) {
            trafficControlDataList = (List<TrafficControlDataModel>) object;
        }
//        List<Integer> shuttleNoList = new ArrayList<>();
//        while (true) {
//            try {
@@ -198,66 +207,66 @@
        detecting = false;
        detectTime = System.currentTimeMillis();
        //发布堵塞节点可用设备编号
        redisUtil.set(RedisKeyType.TASK_BLOCK_ENABLE_DEVICE_MAP.key, trafficControlDataList);
//        //发布堵塞节点可用设备编号
//        redisUtil.set(RedisKeyType.TASK_BLOCK_ENABLE_DEVICE_MAP.key, trafficControlDataList);
    }
    //分配堵塞节点可执行设备
    public void findDeviceByBlockList(List<List<String>> allLocList, List<List<Integer>> blockNodes) {
        HashMap<String, Integer> map = new HashMap<>();
        if (deviceMap == null) {
            Object object = redisUtil.get(RedisKeyType.TASK_BLOCK_ENABLE_DEVICE_MAP.key);
            if (object != null) {
                map = (HashMap<String, Integer>) object;
            }
        } else {
            map = deviceMap;
        }
        HashMap<String, Integer> newMap = new HashMap<>();
        for (int i = 0; i < blockNodes.size(); i++) {
            List<Integer> blockNode = blockNodes.get(i);
            List<String> locs = allLocList.get(i);
            String key = JSON.toJSONString(locs);
            Integer value = -1;
            if (map.containsKey(key)) {
                value = map.get(key);
                map.remove(key);
                if (value > 0) {
                    ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, value);
                    if (shuttleThread == null) {
                        continue;
                    }
                    ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
                    if (shuttleProtocol == null) {
                        continue;
                    }
                    if (shuttleProtocol.getTaskNo() == 0) {
                        value = searchDevice(locs, blockNode, newMap);
                    }
                    if (!shuttleProtocol.getTrafficControl()) {
                        value = searchDevice(locs, blockNode, newMap);
                    }
                }else {
                    value = searchDevice(locs, blockNode, newMap);
                }
            } else {
                value = searchDevice(locs, blockNode, newMap);
            }
            newMap.put(key, value);
        }
        deviceMap = newMap;
        //发布堵塞节点可用设备编号
        redisUtil.set(RedisKeyType.TASK_BLOCK_ENABLE_DEVICE_MAP.key, newMap);
    }
//    //分配堵塞节点可执行设备
//    public void findDeviceByBlockList(List<List<String>> allLocList, List<List<Integer>> blockNodes) {
//        HashMap<String, Integer> map = new HashMap<>();
//        if (deviceMap == null) {
//            Object object = redisUtil.get(RedisKeyType.TASK_BLOCK_ENABLE_DEVICE_MAP.key);
//            if (object != null) {
//                map = (HashMap<String, Integer>) object;
//            }
//        } else {
//            map = deviceMap;
//        }
//
//        HashMap<String, Integer> newMap = new HashMap<>();
//
//        for (int i = 0; i < blockNodes.size(); i++) {
//            List<Integer> blockNode = blockNodes.get(i);
//            List<String> locs = allLocList.get(i);
//
//            String key = JSON.toJSONString(locs);
//
//            Integer value = -1;
//            if (map.containsKey(key)) {
//                value = map.get(key);
//                map.remove(key);
//
//                if (value > 0) {
//                    ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, value);
//                    if (shuttleThread == null) {
//                        continue;
//                    }
//
//                    ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
//                    if (shuttleProtocol == null) {
//                        continue;
//                    }
//
//                    if (shuttleProtocol.getTaskNo() == 0) {
//                        value = searchDevice(locs, blockNode, newMap);
//                    }
//
//                    if (!shuttleProtocol.getTrafficControl()) {
//                        value = searchDevice(locs, blockNode, newMap);
//                    }
//                }else {
//                    value = searchDevice(locs, blockNode, newMap);
//                }
//            } else {
//                value = searchDevice(locs, blockNode, newMap);
//            }
//            newMap.put(key, value);
//        }
//
//        deviceMap = newMap;
//        //发布堵塞节点可用设备编号
//        redisUtil.set(RedisKeyType.TASK_BLOCK_ENABLE_DEVICE_MAP.key, newMap);
//    }
    public Integer searchDevice(List<String> locs, List<Integer> blockNode, HashMap<String, Integer> deviceMap) {
        NavigateUtils navigateUtils = null;
@@ -434,8 +443,24 @@
    @Override
    public synchronized boolean applyTrafficControl(List<NavigateNode> totalNodeList, List<NavigateNode> nodeList, Integer shuttleNo, Integer taskNo) {
        //发布堵塞节点可用设备编号
        redisUtil.set(RedisKeyType.TASK_BLOCK_ENABLE_DEVICE_MAP.key, trafficControlDataList);
        //更新交管信息
        redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_MAP.key, trafficControlDataList);
        NavigateNode startNode = totalNodeList.get(0);
        List<int[]> shuttlePoints = Utils.getShuttlePoints(shuttleNo, startNode.getZ());
        int[] currentShuttlePoint = Utils.getShuttlePoint(shuttleNo);
        if(currentShuttlePoint == null) {
            return false;
        }
        String currentShuttleLoc = Utils.getLocNo(currentShuttlePoint[0], currentShuttlePoint[1], startNode.getZ());
        List<String> shuttleLocList = new ArrayList<>();
        for (int[] shuttlePoint : shuttlePoints) {
            String locNo = Utils.getLocNo(shuttlePoint[0], shuttlePoint[1], startNode.getZ());
            shuttleLocList.add(locNo);
        }
        //检测车子是否存在管制
        for (int i = 0; i < trafficControlDataList.size(); i++) {
            TrafficControlDataModel controlDataModel = trafficControlDataList.get(i);
@@ -445,27 +470,14 @@
                    return false;
                }
                //任务总数量不一致
                if (totalNodeList.size() != controlDataModel.getTotalNodeList().size()) {
                    return false;
                }
                int startIdx = 0;
                int targetIdx = totalNodeList.size() - 1;
                NavigateNode applyStartNode = totalNodeList.get(startIdx);
                NavigateNode applyTargetNode = totalNodeList.get(targetIdx);
                NavigateNode controlStartNode = controlDataModel.getTotalNodeList().get(startIdx);
                NavigateNode controlTargetNode = controlDataModel.getTotalNodeList().get(targetIdx);
                //起点不同
                if(!NavigatePositionConvert.equalsNode(applyStartNode, controlStartNode)) {
                    return false;
                }
                //终点不同
                if(!NavigatePositionConvert.equalsNode(applyTargetNode, controlTargetNode)) {
                    return false;
                for (NavigateNode node : nodeList) {
                    String locNo = Utils.getLocNo(node.getX(), node.getY(), node.getZ());
                    if(shuttleLocList.contains(locNo)) {
                        ShuttleThread shuttleThread = Utils.searchShuttle(locNo);
                        if(shuttleThread != null) {
                            shuttleThread.restartCalcPath();
                        }
                    }
                }
                News.info("traffic running {},{}", shuttleNo, taskNo);
@@ -473,30 +485,45 @@
            }
        }
        NavigateNode startNode = totalNodeList.get(0);
        List<int[]> shuttlePoints = Utils.getShuttlePoints(shuttleNo, startNode.getZ());
        List<String> shuttleLocList = new ArrayList<>();
        for (int[] shuttlePoint : shuttlePoints) {
            String locNo = Utils.getLocNo(shuttlePoint[0], shuttlePoint[1], startNode.getZ());
            shuttleLocList.add(locNo);
        ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo);
        if (shuttleThread == null) {
            return false;
        }
        if (!applyRecordsMap.containsKey(shuttleNo)) {
            applyRecordsMap.put(shuttleNo, System.currentTimeMillis());
        }
        Long applyRecordTime = applyRecordsMap.get(shuttleNo);
        if ((System.currentTimeMillis() - applyRecordTime) > 1000 * 10) {
            shuttleThread.restartCalcPath();
        }
        List<String> totalLocList = new ArrayList<>();
        for (NavigateNode node : totalNodeList) {
            String locNo = Utils.getLocNo(node.getX(), node.getY(), node.getZ());
            if(shuttleLocList.contains(locNo)) {
               return false;//node has shuttle
            totalLocList.add(locNo);
        }
        //检测路径是否有小车
        for (String loc : totalLocList) {
            if(shuttleLocList.contains(loc)) {
                return false;//node has shuttle
            }
        }
        //检测节点是否被使用
        for (TrafficControlDataModel controlDataModel : trafficControlDataList) {
            List<NavigateNode> list = controlDataModel.getTotalNodeList();
            for (NavigateNode node1 : list) {
                for (NavigateNode node2 : totalNodeList) {
                    if (NavigatePositionConvert.equalsNode(node1, node2)) {
                        return false;
                    }
            for (int i = 0; i < list.size(); i++) {
                NavigateNode node = list.get(i);
                String locNo = Utils.getLocNo(node.getX(), node.getY(), node.getZ());
                if (i == 0 && currentShuttleLoc.equals(locNo)) {
                    continue;//..todo wait watch problem
                }
                if(totalLocList.contains(locNo)) {
                    return false;
                }
            }
        }
@@ -508,20 +535,36 @@
        model.setNodeList(nodeList);
        model.setTotalNodeList(totalNodeList);
        trafficControlDataList.add(model);
        applyRecordsMap.remove(shuttleNo);
        News.info("receipt traffic {},{}", shuttleNo, taskNo);
        return true;
    }
    @Override
    public boolean trafficReport(List<NavigateNode> nodeList, Integer shuttleNo, Integer taskNo) {
    public synchronized boolean trafficReport(List<NavigateNode> nodeList, Integer shuttleNo, Integer taskNo) {
        //检测车子是否存在管制
        for (int i = 0; i < trafficControlDataList.size(); i++) {
            TrafficControlDataModel controlDataModel = trafficControlDataList.get(i);
            if(shuttleNo.equals(controlDataModel.getShuttleNo())) {
                if(controlDataModel.getTaskNo().equals(taskNo)) {
                    List<NavigateNode> newTotalNodeList = new ArrayList<>();
                    List<NavigateNode> totalNodeList = controlDataModel.getTotalNodeList();
                    totalNodeList.removeAll(nodeList);
                    controlDataModel.setTotalNodeList(totalNodeList);
                    List<String> reportList = new ArrayList<>();
                    for (NavigateNode node : nodeList) {
                        reportList.add(Utils.getLocNo(node.getX(), node.getY(), node.getZ()));
                    }
                    for (NavigateNode node : totalNodeList) {
                        String locNo = Utils.getLocNo(node.getX(), node.getY(), node.getZ());
                        if(reportList.contains(locNo)) {
                            continue;
                        }
                        newTotalNodeList.add(node);
                    }
                    controlDataModel.setTotalNodeList(newTotalNodeList);
                    trafficControlDataList.set(i, controlDataModel);
                    return true;
                }
@@ -546,6 +589,19 @@
    }
    @Override
    public boolean forceCancelTrafficControl(Integer shuttleNo) {
        //检测车子是否存在管制
        for (int i = 0; i < trafficControlDataList.size(); i++) {
            TrafficControlDataModel controlDataModel = trafficControlDataList.get(i);
            if(shuttleNo.equals(controlDataModel.getShuttleNo())) {
                trafficControlDataList.remove(i);//取消管制
                return true;
            }
        }
        return false;
    }
    @Override
    public TrafficControlDataModel queryTrafficControl(Integer shuttleNo) {
        //检测车子是否存在管制
        for (int i = 0; i < trafficControlDataList.size(); i++) {