Junjie
2023-04-04 c08e857d010676d45ff5f4fc022613b974563d43
src/main/java/com/zy/core/thread/ShuttleThread.java
@@ -10,7 +10,6 @@
import com.core.exception.CoolException;
import com.zy.asrs.entity.BasShuttle;
import com.zy.asrs.entity.BasShuttleOpt;
import com.zy.asrs.mapper.BasShuttleMapper;
import com.zy.asrs.service.BasShuttleOptService;
import com.zy.asrs.service.BasShuttleService;
import com.zy.common.model.NavigateNode;
@@ -25,6 +24,7 @@
import com.zy.core.enums.*;
import com.zy.core.model.ShuttleSlave;
import com.zy.core.model.Task;
import com.zy.core.model.command.LiftCommand;
import com.zy.core.model.command.ShuttleAssignCommand;
import com.zy.core.model.command.ShuttleCommand;
import com.zy.core.model.protocol.ShuttleProtocol;
@@ -168,8 +168,11 @@
                    shuttleProtocol.setPakMk(true);
                }
                //四向穿梭车空闲、有任务且标记为true,需要执行任务的下一条指令
                if (shuttleProtocol.getBusyStatusType() == ShuttleStatusType.IDLE && shuttleProtocol.getTaskNo() != 0 && shuttleProtocol.getPakMk()) {
                //四向穿梭车空闲、有任务、标记为true、存在任务指令,需要执行任务的下一条指令
                if (shuttleProtocol.getBusyStatusType() == ShuttleStatusType.IDLE
                        && shuttleProtocol.getTaskNo() != 0
                        && shuttleProtocol.getPakMk()
                        && shuttleProtocol.getAssignCommand() != null) {
                    //执行下一步指令
                    executeWork(shuttleProtocol.getAssignCommand());
                }
@@ -227,7 +230,7 @@
                basShuttle.setPakMk(shuttleProtocol.getPakMk());
                if (shuttleService.updateById(basShuttle)) {
                    OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId()));
                    log.info(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId()));
//                    log.info(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId()));
                }
            }else {
@@ -343,24 +346,94 @@
    }
    //分配任务
    private void assignWork(ShuttleAssignCommand assignCommand) throws Exception {
    private void assignWork(ShuttleAssignCommand assignCommand) {
        //将此map存入redis中
        HashMap<String, Object> map = new HashMap<>();
        //计算路径
        List<NavigateNode> calc = NavigateUtils.calc(assignCommand.getSourceLocNo(), assignCommand.getDistLocNo(), assignCommand.getTaskMode().intValue());
        if (calc != null) {
            //获取分段路径
            ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(calc);
            //路径数据
            map.put("path", data);
            //路径次数
            map.put("pathSize", data.size());
        }else {
            if (assignCommand.getTaskMode() == ShuttleTaskModeType.PAK_IN.id.shortValue() || assignCommand.getTaskMode() == ShuttleTaskModeType.PAK_OUT.id.shortValue()) {
                //属于入库出库,必须要计算路径,则抛出异常
                throw new Exception("未能找到运行路径");
//        if (assignCommand.getTaskMode() == ShuttleTaskModeType.PAK_IN.id.shortValue()
//                || assignCommand.getTaskMode() == ShuttleTaskModeType.PAK_OUT.id.shortValue()) {
//            //入库或出库模式,计算路径
//            //计算路径
//            List<NavigateNode> calc = NavigateUtils.calc(assignCommand.getSourceLocNo(), assignCommand.getLocNo(), assignCommand.getTaskMode().intValue());
//            if (calc != null) {
//                //获取分段路径
//                ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(calc);
//                //路径数据
//                map.put("path", data);
//                //路径次数
//                map.put("pathSize", data.size());
//            }else {
//                if (assignCommand.getTaskMode() == ShuttleTaskModeType.PAK_IN.id.shortValue() || assignCommand.getTaskMode() == ShuttleTaskModeType.PAK_OUT.id.shortValue()) {
//                    //属于入库出库,必须要计算路径,则抛出异常
//                    throw new Exception("未能找到运行路径");
//                }
//            }
//        }
        if (!assignCommand.getAuto()) {
            List<ShuttleCommand> commands = new ArrayList<>();
            ShuttleCommand command = new ShuttleCommand();
            switch (assignCommand.getTaskMode()) {
                case 1://入库
                case 2://出库
                    //小车移动到提升机口,计算路径
                    //计算小车起点到中点所需命令
                    List<NavigateNode> calc = NavigateUtils.calc(assignCommand.getSourceLocNo(), assignCommand.getLocNo(), ShuttleTaskModeType.PAK_IN.id);
                    if (calc != null) {
                        //获取分段路径
                        ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(calc);
                        //将每一段路径分成command指令
                        for (ArrayList<NavigateNode> nodes : data) {
                            //开始路径
                            NavigateNode startPath = nodes.get(0);
                            //目标路径
                            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()));
                            command1.setMiddleCodeNum((short) 0);
                            command1.setDistCodeNum(NavigatePositionConvert.xyToPosition(endPath.getX(), endPath.getY()));
                            command1.setStartToDistDistance(allDistance);
                            command1.setMiddleToDistDistance(1000);
                            command1.setRunDirection(ShuttleRunDirection.get(startPath.getDirection()).id);
                            command1.setPalletLift((short) 1);
                            command1.setForceMoveDistance(1000);
                            command1.setChargeSwitch((short) 2);
                            command1.setIOControl((short) 0);
                            command1.setRunSpeed((short) 1000);
                            command1.setRadarTmp((short) 0);
                            command1.setCommandEnd((short) 1);
                            commands.add(command1);
                        }
                    }
                    break;
                case 3://托盘顶升
                case 4://托盘下降
                    command.setCommandWord((short) 2);
                    command.setPalletLift(assignCommand.getTaskMode() == 3 ? (short)1 : (short)2);
                    command.setCommandEnd((short) 1);
                    commands.add(command);
                    break;
                case 5://强制左移
                case 6://强制右移
                case 7://强制上移
                case 8://强制下移
                    command.setCommandWord((short) 3);
                    command.setForceMoveDistance(1000);
                    command.setRunDirection((short) (assignCommand.getTaskMode() - 4));
                    command.setCommandEnd((short) 1);
                    commands.add(command);
                    break;
                case 9://状态复位
                    command.setCommandWord((short) 0);
                    command.setCommandEnd((short) 1);
                    commands.add(command);
                    break;
                default:
            }
            assignCommand.setCommands(commands);
        }
        //四向穿梭车号
@@ -373,6 +446,7 @@
        map.put("assignCommand", assignCommand);
        shuttleProtocol.setTaskNo(assignCommand.getTaskNo());
        shuttleProtocol.setAssignCommand(assignCommand);
        shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.WORKING);
        //任务数据保存到redis
        redisUtil.set("wrk_no_" + assignCommand.getTaskNo(), JSON.toJSONString(map));
        //执行下发任务
@@ -380,89 +454,35 @@
    }
    //执行下发的指令
    private void executeWork(ShuttleAssignCommand assignCommand) {
    private boolean executeWork(ShuttleAssignCommand assignCommand) {
        //读取redis数据
        if (assignCommand == null) {
            return false;
        }
        //将标记置为false(防止重发)
        shuttleProtocol.setPakMk(false);
        Object o = redisUtil.get("wrk_no_" + assignCommand.getTaskNo());
        if (o == null) {
            return false;
        }
        HashMap map = JSON.parseObject(o.toString(), HashMap.class);
        List<ShuttleCommand> commands = assignCommand.getCommands();
        //当前步序
        int commandStep = Integer.parseInt(map.get("commandStep").toString());
        //path路径数目
        int size = 0;
        //下发命令
        ShuttleCommand command = new ShuttleCommand();
        switch (assignCommand.getTaskMode()) {
            case 1://入库
            case 2://出库
                //当前路径数据
                Object data = map.get("path");
                ArrayList pathList = JSON.parseObject(data.toString(), ArrayList.class);
                //取第一条路径
                Object o1 = pathList.get(commandStep);
                ArrayList objectPath = JSON.parseObject(o1.toString(), ArrayList.class);
                ArrayList<NavigateNode> path = new ArrayList<>();
                for (Object o2 : objectPath) {
                    NavigateNode navigateNode = JSON.parseObject(o2.toString(), NavigateNode.class);
                    path.add(navigateNode);
                }
                Integer allDistance = NavigateUtils.getCurrentPathAllDistance(path);//计算当前路径行走总距离
        int size = commands.size();
                size = Integer.parseInt(map.get("pathSize").toString());
                //开始路径
                NavigateNode startPath = path.get(0);
                //目标路径
                NavigateNode endPath = path.get(path.size() - 1);
        //取出命令
        ShuttleCommand command = commands.get(commandStep);
                command.setCommandWord((short) 1);
                command.setStartCodeNum(NavigatePositionConvert.xyToPosition(startPath.getX(), startPath.getY()));
                command.setMiddleCodeNum((short) 0);
                command.setDistCodeNum(NavigatePositionConvert.xyToPosition(endPath.getX(), endPath.getY()));
                command.setStartToDistDistance(allDistance);
                command.setMiddleToDistDistance(1000);
                command.setRunDirection(ShuttleRunDirection.get(startPath.getDirection()).id);
                command.setPalletLift((short) 1);
                command.setForceMoveDistance(1000);
                command.setChargeSwitch((short) 2);
                command.setIOControl((short) 0);
                command.setRunSpeed((short) 1000);
                command.setRadarTmp((short) 0);
                break;
            case 3://托盘顶升
            case 4://托盘下降
                command.setCommandWord((short) 2);
                command.setPalletLift(assignCommand.getTaskMode() == 3 ? (short)1 : (short)2);
                command.setCommandEnd((short) 1);
                break;
            case 5://强制左移
            case 6://强制右移
            case 7://强制上移
            case 8://强制下移
                command.setCommandWord((short) 3);
                command.setForceMoveDistance(1000);
                command.setRunDirection((short) (assignCommand.getTaskMode() - 4));
                command.setCommandEnd((short) 1);
                break;
            case 9://状态复位
                command.setCommandWord((short) 0);
                //设置四向穿梭车为空闲状态
                shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.IDLE);
                //任务号清零
                shuttleProtocol.setTaskNo((short) 0);
                //标记复位
                shuttleProtocol.setPakMk(true);
                break;
            default:
        }
        command.setCommandEnd((short) 1);
        //下发命令
        if (!write(command)) {
            News.error("四向穿梭车命令下发失败,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(command));
            return false;
        } else {
            News.info("四向穿梭车命令下发成功,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(command));
            //将标记置为false(防止重发)
            shuttleProtocol.setPakMk(false);
            //判断数据是否执行完成
            if (commandStep < size - 1) {
@@ -483,24 +503,40 @@
                            new Date(),
                            ShuttleTaskModeType.get(assignCommand.getTaskMode()).desc,
                            assignCommand.getSourceLocNo(),
                            assignCommand.getDistLocNo(),
                            assignCommand.getLocNo(),
                            null,
                            null,
                            null,
                            JSON.toJSONString(command)
                            JSON.toJSONString(assignCommand)
                    );
                    shuttleOptService.insert(opt);
                }
                //删除redis
                redisUtil.del("wrk_no_" + map.get("wrk_no").toString());
                //对主线程抛出等待确认状态waiting
                shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.WAITING);
                if (!assignCommand.getAuto()) {
                    //手动模式不抛出等待状态,直接复位
                    if (assignCommand.getTaskMode() == 9) {
                        //设置四向穿梭车为空闲状态
                        shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.IDLE);
                        //任务号清零
                        shuttleProtocol.setTaskNo((short) 0);
                        //标记复位
                        shuttleProtocol.setPakMk(true);
                        //任务指令清零
                        shuttleProtocol.setAssignCommand(null);
                    }
                    News.info("四向穿梭车手动任务执行完成,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(command));
                }else {
                    //对主线程抛出等待确认状态waiting
                    shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.WAITING);
                    News.info("四向穿梭车任务执行完成等待确认中,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(command));
                }
                News.info("四向穿梭车任务执行完成等待确认中,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(command));
            }
        }
        return true;
    }
    /******************************************************************************************/