自动化立体仓库 - WCS系统
Junjie
2023-05-11 d3696ce1ba6071f264aa3db8cc94bf090094a906
src/main/java/com/zy/core/thread/ShuttleThread.java
@@ -16,11 +16,9 @@
import com.zy.asrs.service.BasShuttleOptService;
import com.zy.asrs.service.BasShuttleService;
import com.zy.asrs.service.LocMastService;
import com.zy.asrs.utils.Utils;
import com.zy.common.model.NavigateNode;
import com.zy.common.utils.CommonUtils;
import com.zy.common.utils.NavigatePositionConvert;
import com.zy.common.utils.NavigateUtils;
import com.zy.common.utils.RedisUtil;
import com.zy.common.utils.*;
import com.zy.core.News;
import com.zy.core.ThreadHandler;
import com.zy.core.cache.MessageQueue;
@@ -394,9 +392,10 @@
    //分配任务
    private void assignWork(ShuttleAssignCommand assignCommand) {
        if (!assignCommand.getAuto()) {
            List<NavigateNode> allNode = new ArrayList<>();
            List<ShuttleCommand> commands = new ArrayList<>();
            ShuttleCommand command = new ShuttleCommand();
            LocMastService locMastService = SpringUtils.getBean(LocMastService.class);
            NavigateMapData navigateMapData;
            switch (assignCommand.getTaskMode()) {
                case 1://入库
                case 2://出库
@@ -404,7 +403,12 @@
                    //计算小车起点到中点所需命令
                    LocMast currentLocMast = locMastService.queryByQrCode(shuttleProtocol.getCurrentCode().toString());
                    List<NavigateNode> firstMastResult = NavigateUtils.calc(currentLocMast.getLocNo(), assignCommand.getSourceLocNo(), ShuttleTaskModeType.PAK_IN.id);
                    //所使用的路径进行锁定禁用
                    navigateMapData = new NavigateMapData(Utils.getLev(currentLocMast.getLocNo()));
                    navigateMapData.writeNavigateNodeToRedisMap(firstMastResult, true);////所使用的路径进行锁定禁用
                    if (firstMastResult != null) {
                        allNode.addAll(firstMastResult);//将节点进行保存
                        //获取分段路径
                        ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(firstMastResult);
                        //将每一段路径分成command指令
@@ -415,58 +419,29 @@
                            NavigateNode endPath = nodes.get(nodes.size() - 1);
                            Integer allDistance = NavigateUtils.getCurrentPathAllDistance(nodes);//计算当前路径行走总距离
                            ShuttleCommand command1 = new ShuttleCommand();
                            command1.setCommandWord((short) 1);
                            command1.setStartCodeNum(NavigatePositionConvert.xyToPosition(startPath.getX(), startPath.getY(), 1));
                            command1.setMiddleCodeNum((short) 1);
                            command1.setDistCodeNum(NavigatePositionConvert.xyToPosition(endPath.getX(), endPath.getY(), 1));
                            command1.setStartToDistDistance(allDistance);
                            command1.setRunDirection(ShuttleRunDirection.get(startPath.getDirection()).id);
                            command1.setForceMoveDistance(0);
                            command1.setIOControl((short) 0);
                            command1.setRunSpeed((short) 1000);
                            command1.setCommandEnd((short) 1);
                            commands.add(command1);
                            //正常移动命令
                            Short startCode = NavigatePositionConvert.xyToPosition(startPath.getX(), startPath.getY(), 1);//开始二维码
                            Short distCode = NavigatePositionConvert.xyToPosition(endPath.getX(), endPath.getY(), 1);//目标二维码
                            commands.add(getMoveCommand(startCode,distCode,allDistance,ShuttleRunDirection.get(startPath.getDirection()).id));
                        }
                        //托盘顶升
                        ShuttleCommand command2 = new ShuttleCommand();
                        command2.setCommandWord((short) 2);
                        command2.setStartCodeNum((short) 0);
                        command2.setMiddleCodeNum((short) 0);
                        command2.setDistCodeNum((short) 0);
                        command2.setStartToDistDistance(0);
                        command2.setMiddleToDistDistance(0);
                        command2.setRunDirection((short) 0);
                        command2.setForceMoveDistance(0);
                        command2.setPalletLift((short) 1);
                        command2.setRunSpeed((short) 0);
                        command2.setCommandEnd((short) 1);
                        commands.add(command2);
                        commands.add(getPalletCommand((short) 1));
                    }else {
                        //没有计算到路径,可能存在小车位置就是起点位置
                        if (currentLocMast.getLocNo().equals(assignCommand.getSourceLocNo())) {
                            //小车位置就是起点位置,无需移动,直接顶升
                            //托盘顶升
                            ShuttleCommand command2 = new ShuttleCommand();
                            command2.setCommandWord((short) 2);
                            command2.setStartCodeNum((short) 0);
                            command2.setMiddleCodeNum((short) 0);
                            command2.setDistCodeNum((short) 0);
                            command2.setStartToDistDistance(0);
                            command2.setMiddleToDistDistance(0);
                            command2.setRunDirection((short) 0);
                            command2.setForceMoveDistance(0);
                            command2.setPalletLift((short) 1);
                            command2.setRunSpeed((short) 0);
                            command2.setCommandEnd((short) 1);
                            commands.add(command2);
                            commands.add(getPalletCommand((short) 1));
                        }
                    }
                    //计算中点到终点路径
                    List<NavigateNode> secMastResult = NavigateUtils.calc(assignCommand.getSourceLocNo(), assignCommand.getLocNo(), ShuttleTaskModeType.PAK_IN.id);
                    navigateMapData.writeNavigateNodeToRedisMap(firstMastResult, true);////所使用的路径进行锁定禁用
                    if (secMastResult != null) {
                        allNode.addAll(secMastResult);//将节点进行保存
                        //获取分段路径
                        ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(secMastResult);
                        //将每一段路径分成command指令
@@ -477,120 +452,51 @@
                            NavigateNode endPath = nodes.get(nodes.size() - 1);
                            Integer allDistance = NavigateUtils.getCurrentPathAllDistance(nodes);//计算当前路径行走总距离
                            ShuttleCommand command1 = new ShuttleCommand();
                            command1.setCommandWord((short) 1);
                            command1.setStartCodeNum(NavigatePositionConvert.xyToPosition(startPath.getX(), startPath.getY(), 1));
                            command1.setMiddleCodeNum((short) 1);
                            command1.setDistCodeNum(NavigatePositionConvert.xyToPosition(endPath.getX(), endPath.getY(), 1));
                            command1.setStartToDistDistance(allDistance);
                            command1.setRunDirection(ShuttleRunDirection.get(startPath.getDirection()).id);
                            command1.setForceMoveDistance(0);
                            command1.setIOControl((short) 0);
                            command1.setRunSpeed((short) 1000);
                            command1.setCommandEnd((short) 1);
                            commands.add(command1);
                            //正常移动命令
                            Short startCode = NavigatePositionConvert.xyToPosition(startPath.getX(), startPath.getY(), 1);//开始二维码
                            Short distCode = NavigatePositionConvert.xyToPosition(endPath.getX(), endPath.getY(), 1);//目标二维码
                            commands.add(getMoveCommand(startCode, distCode, allDistance, ShuttleRunDirection.get(startPath.getDirection()).id));
                        }
                        //托盘下降
                        ShuttleCommand command2 = new ShuttleCommand();
                        command2.setCommandWord((short) 2);
                        command2.setStartCodeNum((short) 0);
                        command2.setMiddleCodeNum((short) 0);
                        command2.setDistCodeNum((short) 0);
                        command2.setStartToDistDistance(0);
                        command2.setMiddleToDistDistance(0);
                        command2.setRunDirection((short) 0);
                        command2.setForceMoveDistance(0);
                        command2.setPalletLift((short) 2);
                        command2.setRunSpeed((short) 0);
                        command2.setCommandEnd((short) 1);
                        commands.add(command2);
                        commands.add(getPalletCommand((short) 2));
                    }
                    break;
                case 3://托盘顶升
                case 4://托盘下降
                    command.setCommandWord((short) 2);
                    command.setStartCodeNum((short) 0);
                    command.setMiddleCodeNum((short) 0);
                    command.setDistCodeNum((short) 0);
                    command.setStartToDistDistance(0);
                    command.setMiddleToDistDistance(0);
                    command.setRunDirection((short) 0);
                    command.setForceMoveDistance(0);
                    command.setPalletLift(assignCommand.getTaskMode() == 3 ? (short)1 : (short)2);
                    command.setRunSpeed((short) 0);
                    command.setCommandEnd((short) 1);
                    commands.add(command);
                    commands.add(getPalletCommand(assignCommand.getTaskMode() == 3 ? (short) 1 : (short) 2));
                    break;
                case 5://强制左移
                case 6://强制右移
                case 7://强制上移
                case 8://强制下移
                    command.setCommandWord((short) 3);
                    command.setStartCodeNum((short) 0);
                    command.setMiddleCodeNum((short) 0);
                    command.setDistCodeNum((short) 0);
                    command.setStartToDistDistance(600);
                    command.setRunDirection((short) (assignCommand.getTaskMode() - 4));
                    command.setForceMoveDistance(600);
                    command.setIOControl((short) 0);
                    command.setCommandEnd((short) 1);
                    command.setRunSpeed((short) 1000);
                    commands.add(command);
                    commands.add(getForceMoveCommand((short) (assignCommand.getTaskMode() - 4)));
                    break;
                case 9://状态复位
                    command.setCommandWord((short) 6);
                    command.setStartCodeNum((short) 0);
                    command.setMiddleCodeNum((short) 0);
                    command.setDistCodeNum((short) 0);
                    command.setStartToDistDistance(0);
                    command.setMiddleToDistDistance(0);
                    command.setRunDirection((short) 0);
                    command.setPalletLift((short) 0);
                    command.setPalletLift((short) 0);
                    command.setForceMoveDistance(0);
                    command.setChargeSwitch((short) 0);
                    command.setIOControl((short) 0);
                    command.setRunSpeed((short) 0);
                    command.setCommandEnd((short) 1);
                    commands.add(command);
                    ShuttleCommand reset = getResetCommand();
                    commands.add(reset);
                    break;
                case 10://向正方向(左)寻库位
                    command.setCommandWord((short) 4);
                    command.setRunDirection((short) 1);
                    command.setStartToDistDistance(3000);
                    command.setRunSpeed((short) 1000);
                    command.setCommandEnd((short) 1);
                    commands.add(command);
                    commands.add(getFindLocCommand((short) 1));
                    break;
                case 11://向负方向(右)寻库位
                    command.setCommandWord((short) 4);
                    command.setRunDirection((short) 2);
                    command.setStartToDistDistance(3000);
                    command.setRunSpeed((short) 1000);
                    command.setCommandEnd((short) 1);
                    commands.add(command);
                    commands.add(getFindLocCommand((short) 2));
                    break;
                case 12://向正方向(前)寻库位
                    command.setCommandWord((short) 4);
                    command.setRunDirection((short) 4);
                    command.setStartToDistDistance(3000);
                    command.setRunSpeed((short) 1000);
                    command.setCommandEnd((short) 1);
                    commands.add(command);
                    commands.add(getFindLocCommand((short) 4));
                    break;
                case 13://向负方向(后)寻库位
                    command.setCommandWord((short) 4);
                    command.setRunDirection((short) 3);
                    command.setStartToDistDistance(3000);
                    command.setRunSpeed((short) 1000);
                    command.setCommandEnd((short) 1);
                    commands.add(command);
                    commands.add(getFindLocCommand((short) 3));
                    break;
                case 14://移动到目标库位
                    LocMast locMast = locMastService.queryByQrCode(shuttleProtocol.getCurrentCode().toString());
                    List<NavigateNode> result = NavigateUtils.calc(locMast.getLocNo(), assignCommand.getLocNo(), ShuttleTaskModeType.PAK_IN.id);
                    //所使用的路径进行锁定禁用
                    navigateMapData = new NavigateMapData(Utils.getLev(locMast.getLocNo()));
                    navigateMapData.writeNavigateNodeToRedisMap(result, true);////所使用的路径进行锁定禁用
                    if (result != null) {
                        allNode.addAll(result);//将节点进行保存
                        //获取分段路径
                        ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(result);
                        //将每一段路径分成command指令
@@ -603,29 +509,19 @@
                            LocMast distLocMast = locMastService.queryByLoc(assignCommand.getLocNo());
                            String qrCodeValue = distLocMast.getQrCodeValue();
                            command.setCommandWord((short) 1);
                            command.setStartCodeNum(shuttleProtocol.getCurrentCode());
                            command.setMiddleCodeNum((short) 1);
                            command.setDistCodeNum((short) Integer.parseInt(qrCodeValue));
                            command.setStartToDistDistance(allDistance);
                            command.setRunSpeed((short) 1000);
                            command.setRunDirection(ShuttleRunDirection.get(startPath.getDirection()).id);
                            command.setForceMoveDistance(0);
                            command.setIOControl((short) 0);
                            command.setCommandEnd((short) 1);
                            commands.add(command);
                            //正常移动命令
                            commands.add(getMoveCommand(shuttleProtocol.getCurrentCode(),(short) Integer.parseInt(qrCodeValue),allDistance,ShuttleRunDirection.get(startPath.getDirection()).id));
                        }
                    }
                    break;
                case 15://充电开关
                    command.setCommandWord((short) 8);
                    command.setIOControl((short) 4);
                    command.setCommandEnd((short) 1);
                    commands.add(command);
                    commands.add(getChargeSwitchCommand());
                    break;
                default:
            }
            assignCommand.setCommands(commands);
            assignCommand.setNodes(allNode);//当前任务所占用的节点list
        }
        ShuttleRedisCommand redisCommand = new ShuttleRedisCommand();
@@ -798,6 +694,11 @@
                        liftProtocol.setSecurityMk(false);
                    }
                }
                String locNo = shuttleProtocol.getLocNo() == null ? shuttleProtocol.getSourceLocNo() : shuttleProtocol.getLocNo();
                //解除锁定的库位路径
                NavigateMapData navigateMapData = new NavigateMapData(Utils.getLev(locNo));
                navigateMapData.writeNavigateNodeToRedisMap(redisCommand.getAssignCommand().getNodes(), false);
                //删除redis
                redisUtil.del("shuttle_wrk_no_" + redisCommand.getWrkNo());
@@ -974,29 +875,13 @@
        ShuttleCommand command = commands.get(commandStep - 1);
        //复位命令
        ShuttleCommand resetCommand = new ShuttleCommand();
        resetCommand.setCommandWord((short) 6);
        resetCommand.setStartCodeNum((short) 0);
        resetCommand.setMiddleCodeNum((short) 0);
        resetCommand.setDistCodeNum((short) 0);
        resetCommand.setStartToDistDistance(0);
        resetCommand.setMiddleToDistDistance(0);
        resetCommand.setRunDirection((short) 0);
        resetCommand.setPalletLift((short) 0);
        resetCommand.setPalletLift((short) 0);
        resetCommand.setForceMoveDistance(0);
        resetCommand.setChargeSwitch((short) 0);
        resetCommand.setIOControl((short) 0);
        resetCommand.setRunSpeed((short) 0);
        resetCommand.setCommandEnd((short) 1);
        ShuttleCommand resetCommand = getResetCommand();
        list.add(resetCommand);
        //车辆空闲,等待写入找库位命令
        //找库位命令
        ShuttleCommand searchCommand = new ShuttleCommand();
        searchCommand.setCommandWord((short) 4);
        short direction = 1;
        switch (command.getRunDirection()) {
        switch (command.getRunDirection()) {//转换运行方向
            case 1:
                direction = 2;
                break;
@@ -1012,11 +897,8 @@
            default:
                direction = 1;
        }
        searchCommand.setRunDirection(direction);//运行方向
        searchCommand.setStartToDistDistance(1200);
        searchCommand.setRunSpeed((short) 1000);
        searchCommand.setCommandEnd((short) 1);
        //找库位命令
        ShuttleCommand searchCommand = getFindLocCommand(direction, 1200, (short) 1000);
        list.add(searchCommand);
        //移动车辆,需要在执行完寻找定位点后再执行
@@ -1032,6 +914,119 @@
        return true;
    }
    /**
     * 获取托盘顶升命令
     * @param lift 1顶升,2下降
     */
    private ShuttleCommand getPalletCommand(Short lift) {
        ShuttleCommand command = new ShuttleCommand();
        command.setCommandWord((short) 2);
        command.setStartCodeNum((short) 0);
        command.setMiddleCodeNum((short) 0);
        command.setDistCodeNum((short) 0);
        command.setStartToDistDistance(0);
        command.setMiddleToDistDistance(0);
        command.setRunDirection((short) 0);
        command.setForceMoveDistance(0);
        command.setPalletLift(lift);
        command.setRunSpeed((short) 0);
        command.setCommandEnd((short) 1);
        return command;
    }
    /**
     * 正常移动命令
     * @return
     */
    private ShuttleCommand getMoveCommand(Short startCodeNum, Short distCodeNum, Integer startToDistDistance, Short runDirection) {
        ShuttleCommand command = new ShuttleCommand();
        command.setCommandWord((short) 1);
        command.setStartCodeNum(startCodeNum);
        command.setMiddleCodeNum((short) 1);
        command.setDistCodeNum(distCodeNum);
        command.setStartToDistDistance(startToDistDistance);
        command.setRunDirection(runDirection);
        command.setForceMoveDistance(0);
        command.setIOControl((short) 0);
        command.setRunSpeed((short) 1000);
        command.setCommandEnd((short) 1);
        return command;
    }
    /**
     * 强制移动命令
     * @param direction 移动方向 1左移,2右移,3前移,4后移
     */
    private ShuttleCommand getForceMoveCommand(Short direction) {
        ShuttleCommand command = new ShuttleCommand();
        command.setCommandWord((short) 3);
        command.setStartCodeNum((short) 0);
        command.setMiddleCodeNum((short) 0);
        command.setDistCodeNum((short) 0);
        command.setStartToDistDistance(600);
        command.setRunDirection(direction);
        command.setForceMoveDistance(600);
        command.setIOControl((short) 0);
        command.setCommandEnd((short) 1);
        command.setRunSpeed((short) 1000);
        return command;
    }
    /**
     * 状态复位命令
     */
    private ShuttleCommand getResetCommand() {
        ShuttleCommand command = new ShuttleCommand();
        command.setCommandWord((short) 6);
        command.setStartCodeNum((short) 0);
        command.setMiddleCodeNum((short) 0);
        command.setDistCodeNum((short) 0);
        command.setStartToDistDistance(0);
        command.setMiddleToDistDistance(0);
        command.setRunDirection((short) 0);
        command.setPalletLift((short) 0);
        command.setPalletLift((short) 0);
        command.setForceMoveDistance(0);
        command.setChargeSwitch((short) 0);
        command.setIOControl((short) 0);
        command.setRunSpeed((short) 0);
        command.setCommandEnd((short) 1);
        return command;
    }
    /**
     * 获取寻库位命令
     * @param direction 1:向正方向(左)寻库位,2:向负方向(右)寻库位,3:向负方向(后)寻库位,4:向正方向(前)寻库位
     */
    private ShuttleCommand getFindLocCommand(Short direction, Integer startToDistance, Short runSpeed) {
        ShuttleCommand command = new ShuttleCommand();
        command.setCommandWord((short) 4);
        command.setRunDirection(direction);
        command.setStartToDistDistance(startToDistance);
        command.setRunSpeed((short) runSpeed);
        command.setCommandEnd((short) 1);
        return command;
    }
    /**
     * 获取寻库位命令,默认移动距离3000,运行速度1000
     * @param direction 1:向正方向(左)寻库位,2:向负方向(右)寻库位,3:向负方向(后)寻库位,4:向正方向(前)寻库位
     */
    private ShuttleCommand getFindLocCommand(Short direction) {
        return getFindLocCommand(direction, 3000, (short) 1000);
    }
    /**
     * 获取充电开关命令
     */
    private ShuttleCommand getChargeSwitchCommand() {
        ShuttleCommand command = new ShuttleCommand();
        command.setCommandWord((short) 8);
        command.setIOControl((short) 4);
        command.setCommandEnd((short) 1);
        return command;
    }
    /******************************************************************************************/
    /**************************************** 测试专用 *****************************************/
    /*****************************************************************************************/