#
Junjie
2 天以前 6cf4a3e2ba925e75b60f13bb8ebc5e92d37809b2
src/main/java/com/zy/common/utils/ShuttleOperaUtils.java
@@ -4,21 +4,22 @@
import com.core.common.SpringUtils;
import com.core.exception.CoolException;
import com.zy.asrs.entity.BasShuttle;
import com.zy.asrs.entity.DeviceConfig;
import com.zy.asrs.service.BasShuttleService;
import com.zy.asrs.service.DeviceConfigService;
import com.zy.asrs.utils.Utils;
import com.zy.common.model.MapNode;
import com.zy.common.model.NavigateNode;
import com.zy.common.model.enums.NavigationMapType;
import com.zy.core.News;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.dispatcher.ShuttleDispatchUtils;
import com.zy.core.enums.MapNodeType;
import com.zy.core.enums.ShuttleRunDirection;
import com.zy.core.enums.SlaveType;
import com.zy.core.model.ShuttleSlave;
import com.zy.core.model.command.ShuttleAssignCommand;
import com.zy.core.model.command.ShuttleCommand;
import com.zy.core.model.protocol.ShuttleProtocol;
import com.zy.core.properties.SlaveProperties;
import com.zy.core.thread.ShuttleThread;
import com.zy.system.entity.Config;
import com.zy.system.service.ConfigService;
@@ -45,15 +46,15 @@
    @Autowired
    private ConfigService configService;
    @Autowired
    private SlaveProperties slaveProperties;
    @Autowired
    private ShuttleDispatchUtils shuttleDispatchUtils;
    @Autowired
    private DeviceConfigService deviceConfigService;
    public synchronized List<ShuttleCommand> getStartToTargetCommands(String startLocNo, String endLocNo, Integer mapType, ShuttleAssignCommand assignCommand, ShuttleThread shuttleThread) {
        return getStartToTargetCommands(startLocNo, endLocNo, mapType, null, assignCommand, shuttleThread);
    public synchronized List<ShuttleCommand> getStartToTargetCommands(String startLocNo, String endLocNo, List<NavigationMapType> mapTypes, ShuttleAssignCommand assignCommand, ShuttleThread shuttleThread) {
        return getStartToTargetCommands(startLocNo, endLocNo, mapTypes, null, assignCommand, shuttleThread);
    }
    public synchronized List<ShuttleCommand> getStartToTargetCommands(String startLocNo, String endLocNo, Integer mapType, List<int[]> whites, ShuttleAssignCommand assignCommand, ShuttleThread shuttleThread) {
    public synchronized List<ShuttleCommand> getStartToTargetCommands(String startLocNo, String endLocNo, List<NavigationMapType> mapTypes, List<int[]> whites, ShuttleAssignCommand assignCommand, ShuttleThread shuttleThread) {
        ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
        if (shuttleProtocol == null) {
            return null;
@@ -61,7 +62,7 @@
        Integer shuttleNo = shuttleProtocol.getShuttleNo();
        //获取小车移动速度
        Integer runSpeed = Optional.ofNullable(basShuttleService.selectOne(new EntityWrapper<BasShuttle>().eq("shuttle_no", shuttleNo)).getRunSpeed()).orElse(1000);
        List<NavigateNode> nodeList = navigateUtils.calc(startLocNo, endLocNo, mapType, Utils.getShuttlePoints(shuttleNo, Utils.getLev(startLocNo)), whites);
        List<NavigateNode> nodeList = navigateUtils.calc(startLocNo, endLocNo, mapTypes, Utils.getShuttlePoints(shuttleNo, Utils.getLev(startLocNo)), whites);
        if (nodeList == null) {
            News.error("{} dash {} can't find navigate path!", startLocNo, endLocNo);
            shuttleThread.offerSystemMsg("{} dash {} can't find navigate path!", startLocNo, endLocNo);
@@ -89,11 +90,14 @@
            lockNode.add(node.clone());
        }
        long startTime = System.currentTimeMillis();
        List<ShuttleCommand> commands = new ArrayList<>();
        //获取分段路径
        ArrayList<ArrayList<NavigateNode>> data = navigateUtils.getSectionPath(nodeList);
        List<List<NavigateNode>> data = navigateUtils.getSectionPath(nodeList);
        long endTime = System.currentTimeMillis();
        News.info("getSection path time:{}", (endTime - startTime));
        //将每一段路径分成command指令
        for (ArrayList<NavigateNode> nodes : data) {
        for (List<NavigateNode> nodes : data) {
            //开始路径
            NavigateNode startPath = nodes.get(0);
@@ -111,74 +115,17 @@
        }
        assignCommand.setNodes(allNode);//当前任务所占用的节点list
        assignCommand.setMapTypes(mapTypes);
        boolean result = navigateMapUtils.writeNavigateNodeToRedisMap(Utils.getLev(startLocNo), shuttleNo, lockNode, true);//锁定路径
        if (!result) {
            News.error("{} dash {} can't lock path!", startLocNo, endLocNo);
            shuttleThread.offerSystemMsg("{} dash {} can't lock path!", startLocNo, endLocNo);
            return null;//路径锁定失败
        //小车移动连续下发指令
        boolean shuttleMoveCommandsContinuously = false;
        Config shuttleMoveCommandsContinuouslyConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "shuttleMoveCommandsContinuously"));
        if (shuttleMoveCommandsContinuouslyConfig != null) {
            if (shuttleMoveCommandsContinuouslyConfig.getValue().equals("Y")) {
                shuttleMoveCommandsContinuously = true;
            }
        }
        return commands;
    }
    public synchronized List<ShuttleCommand> shuttleInOutLiftCommand(String startLocNo, String endLocNo, Integer mapType, 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, mapType, 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<>();
        //获取分段路径
        ArrayList<ArrayList<NavigateNode>> data = navigateUtils.getSectionPath(nodeList);
        //将每一段路径分成command指令
        for (ArrayList<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
        assignCommand.setShuttleMoveCommandsContinuously(shuttleMoveCommandsContinuously);
        return commands;
    }
@@ -260,13 +207,15 @@
                continue;
            }
            HashMap<String, Integer> carMap = findCarMap();
            String targetLocNo = null;
            for (NavigateNode node : outerNodes) {
                String dispatchLocNo = NavigatePositionConvert.nodeToLocNo(node);
                if (carMap.containsKey(dispatchLocNo)) {
                    continue;
                //获取内圈节点
                List<NavigateNode> avoidInnerNodes = getInnerNodes(dispatchLocNo, innerCircle, new ArrayList<>());
                //计算内圈是否有小车
                List<Integer> avoidNodesCar = findNodesCar(avoidInnerNodes);
                if(!avoidNodesCar.isEmpty()) {
                   continue;
                }
                targetLocNo = dispatchLocNo;
                break;
@@ -283,8 +232,11 @@
    private HashMap<String, Integer> findCarMap() {
        HashMap<String, Integer> carMap = new HashMap<>();
        for (ShuttleSlave slave : slaveProperties.getShuttle()) {
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, slave.getId());
        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;
            }
@@ -297,7 +249,7 @@
                continue;
            }
            carMap.put(currentLocNo, slave.getId());
            carMap.put(currentLocNo, device.getDeviceNo());
        }
        return carMap;
    }
@@ -324,14 +276,14 @@
        NavigateNode currentNode = new NavigateNode(pointArr[0], pointArr[1]);
        currentNode.setZ(lev);
        List<List<MapNode>> lists = navigateMapData.getJsonData(lev, -1, null, null);//获取完整地图
        List<List<MapNode>> lists = navigateMapData.getJsonData(lev, NavigationMapType.getMapTypes(NavigationMapType.NONE), null, null);//获取完整地图
        int[][] map = navigateMapData.parseJsonDataArr(lists);
        int nodeValue = map[pointArr[0]][pointArr[1]];
        currentNode.setNodeValue(nodeValue);
        for (int i = 0; i < outerCircle; i++) {
            int idx = i + 1;
            List<NavigateNode> list = extend_nodes(map, currentNode, idx);
            List<NavigateNode> list = extend_outer_nodes(map, currentNode, idx);
            if (list.isEmpty()) {
                continue;
            }
@@ -365,14 +317,14 @@
        currentNode.setZ(lev);
        innerNodes.add(currentNode);
        List<List<MapNode>> lists = navigateMapData.getJsonData(lev, -1, null, null);//获取完整地图
        List<List<MapNode>> lists = navigateMapData.getJsonData(lev, NavigationMapType.getMapTypes(NavigationMapType.NONE), null, null);//获取完整地图
        int[][] map = navigateMapData.parseJsonDataArr(lists);
        int nodeValue = map[pointArr[0]][pointArr[1]];
        currentNode.setNodeValue(nodeValue);
        for (int i = 0; i < innerCircle; i++) {
            int idx = i + 1;
            List<NavigateNode> list = extend_nodes(map, currentNode, idx);
            List<NavigateNode> list = extend_inner_nodes(map, currentNode, idx);
            if (list.isEmpty()) {
                continue;
            }
@@ -395,7 +347,7 @@
        return innerNodes;
    }
    private List<NavigateNode> extend_nodes(int[][] map, NavigateNode startNode, int innerCircleIdx) {
    private List<NavigateNode> extend_inner_nodes(int[][] map, NavigateNode startNode, int innerCircleIdx) {
        //默认地图母轨方向x
        String mapDirection = "x";
        ConfigService configService = SpringUtils.getBean(ConfigService.class);
@@ -502,6 +454,50 @@
        return nodes;
    }
    private List<NavigateNode> extend_outer_nodes(int[][] map, NavigateNode startNode, int innerCircleIdx) {
        ArrayList<NavigateNode> nodes = new ArrayList<>();
        int x = startNode.getX();
        int y = startNode.getY();
        int z = startNode.getZ();
        if (is_valid(map, x + innerCircleIdx, y)) {
            NavigateNode node = new NavigateNode(x + innerCircleIdx, y);
            node.setNodeValue(map[x + innerCircleIdx][y]);
            node.setZ(z);
            if (node.getNodeValue().equals(startNode.getNodeValue())) {
                nodes.add(node);
            }
        }
        if (is_valid(map, x - innerCircleIdx, y)) {
            NavigateNode node = new NavigateNode(x - innerCircleIdx, y);
            node.setNodeValue(map[x - innerCircleIdx][y]);
            node.setZ(z);
            if (node.getNodeValue().equals(startNode.getNodeValue())) {
                nodes.add(node);
            }
        }
        if (is_valid(map, x, y + innerCircleIdx)) {
            NavigateNode node = new NavigateNode(x, y + innerCircleIdx);
            node.setNodeValue(map[x][y + innerCircleIdx]);
            node.setZ(z);
            if (node.getNodeValue().equals(startNode.getNodeValue())) {
                nodes.add(node);
            }
        }
        if (is_valid(map, x, y - innerCircleIdx)) {
            NavigateNode node = new NavigateNode(x, y - innerCircleIdx);
            node.setNodeValue(map[x][y - innerCircleIdx]);
            node.setZ(z);
            if (node.getNodeValue().equals(startNode.getNodeValue())) {
                nodes.add(node);
            }
        }
        return nodes;
    }
    private boolean is_valid(int[][] map, int x, int y) {
        if (x < 0 || x >= map.length
                || y < 0 || y >= map[0].length) {