Junjie
2023-07-31 c4bcb806f606fc5080b40af20562d6837889f496
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -661,7 +661,7 @@
    /**
     * 入库  ===>>  四向穿梭车入库作业下发
     */
    public synchronized void shuttleIoInExecute() {
    public synchronized void shuttleInExecute() {
        // 根据输送线plc遍历
        for (DevpSlave devp : slaveProperties.getDevp()) {
            // 遍历入库站
@@ -675,235 +675,88 @@
                    staProtocol = staProtocol.clone();
                }
                Short workNo = staProtocol.getWorkNo();
                BasDevp basDevp = basDevpService.selectById(staProtocol.getSiteId());
                if (basDevp == null) {
                    continue;//站点信息不存在
                }
                // 判断是否满足入库条件,自动、有物、四向穿梭车可取信号
                if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.isShuttleTakeEnable()) {
                    WrkMast wrkMast = wrkMastMapper.selectRackInStep48(workNo, staProtocol.getSiteId());
                    if (wrkMast != null) {
                        if (wrkMast.getWrkSts() == 4 || wrkMast.getWrkSts() == 8) {
                            ShuttleThread shuttleThread = null;
                            ShuttleProtocol shuttleProtocol = null;
                            HashMap<String, Object> searchIdleShuttle = null;
                if (!(staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.isShuttleTakeEnable())) {
                    continue;
                }
                            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, 1);
                            LiftProtocol liftProtocol = liftThread.getLiftProtocol();
                WrkMast wrkMast = wrkMastMapper.selectRackInStep4(workNo, staProtocol.getSiteId());
                if (wrkMast == null) {
                    continue;
                }
                            if (wrkMast.getWrkSts() == 4) {
                                if (wrkMast.getShuttleNo() == null) {
                                    //寻找最近且空闲的四向穿梭车
                                    searchIdleShuttle = this.searchIdleShuttle(wrkMast);
                                    shuttleThread = (ShuttleThread) searchIdleShuttle.get("result");
                                    wrkMast.setShuttleNo(shuttleThread.getSlave().getId());//给工作档分配四向穿梭车号
                                    wrkMastMapper.updateById(wrkMast);
                                    shuttleProtocol = shuttleThread.getShuttleProtocol();
                                    if (!shuttleProtocol.isIdle()) {
                                        continue;
                                    }
                                }else {
                                    //直接使用任务保存中的小车
                                    shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
                                    shuttleProtocol = shuttleThread.getShuttleProtocol();
                                    if (!shuttleProtocol.isIdle(workNo)) {
                                        continue;
                                    }
                                }
                            }else if(wrkMast.getWrkSts() == 8){//状态8,需要向小车下发命令从提升机移动出去,需要判断提升机状是否空闲、提升机是否到达目标楼层、目标楼层站点是否存在、目标楼层站点是否给出提升机到位信号
                                //状态8,等待命令进行入库搬运动作
                                //判断提升机是否空闲
                                if (!liftProtocol.isIdleNoTask()) {
                                    try {
                                        Thread.sleep(1000);//休眠1s
                                    } catch (InterruptedException e) {
                                        throw new RuntimeException(e);
                                    }
                                    continue;//提升机忙
                                }
                                //判断提升机任务号和当前工作档任务号是否一致
                                if (liftProtocol.getTaskNo().intValue() != 0 && liftProtocol.getTaskNo().intValue() != wrkMast.getWrkNo()) {
                                    continue;
                                }
                                //判断提升机楼层是否到位,判断站点是否给出提升机到位信号
                                String locNo = wrkMast.getLocNo();
                                int lev = Utils.getLev(locNo);//目标二维码所在楼层
                                int liftLev = liftProtocol.getLev().intValue();//提升机所在楼层
                                if (liftLev != lev) {
                                    continue;//提升机不在目标楼层跳过
                                }
                                Integer staNo = Utils.levToOutInStaNo(lev >= 2 ? lev + 1 : lev);
                                //获取目标站信息
                                StaProtocol staProtocol1 = devpThread.getStation().get(staNo);
                                if (staProtocol1 == null) {
                                    continue;//站点信息不存在
                                }
                                if (!staProtocol1.isLiftArrival()) {
                                    continue;//站点提升机到位信号false
                                }
                                Integer shuttleNo = wrkMast.getShuttleNo();//四向穿梭车号
                                shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo);
                                shuttleProtocol = shuttleThread.getShuttleProtocol();
                                if (!shuttleProtocol.isIdle(workNo)) {
                                    continue;
                                }
                            }
                            if (shuttleThread == null) {
                                continue;
                            }
                            if (shuttleProtocol == null) {
                                continue;
                            }
                            wrkMast.setShuttleNo(shuttleProtocol.getShuttleNo().intValue());//给工作档分配四向穿梭车号
                            //分配任务号
                            shuttleProtocol.setTaskNo(wrkMast.getWrkNo().shortValue());
                            //分配源库位
                            shuttleProtocol.setSourceLocNo(wrkMast.getSourceLocNo());
                            //创建分配命令
                            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
                            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo());//四向穿梭车号
                            assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());//任务号
                            assignCommand.setTaskMode(ShuttleTaskModeType.PAK_IN.id.shortValue());//入出库模式
                            String currentLocNo = shuttleProtocol.getCurrentLocNo();
                            assignCommand.setSourceLocNo(currentLocNo);//源库位(小车当前位置)
                            String locNo = wrkMast.getLocNo();//当前工作档库位号
                            Integer currentLev = wrkMast.getWrkSts() == 4 ? Utils.getLev(currentLocNo) : liftProtocol.getLev();//小车当前层高
                            //提升机口站点库位号
                            String liftSiteLocNo = Utils.levToOutInStaLocNo(currentLev);
                            if (wrkMast.getWrkSts() == 4) {
                                if (currentLev == Utils.getLev(locNo)) {
                                    //小车和目标在同一楼层
                                    //直接计算车到提升机取货再到库位路径指令
                                    List<ShuttleCommand> commands = this.shuttleAssignCommand(wrkMast.getWrkSts() == 4 ? currentLocNo : liftSiteLocNo, liftSiteLocNo, locNo, assignCommand, shuttleThread);
                                    if (commands == null) {
                                        continue;//找不到路径等待下一次
                                    }
//                                    assignCommand.setCommands(commands);
                                    //分配目标库位
                                    shuttleProtocol.setLocNo(wrkMast.getLocNo());
                                    //目标库位
                                    assignCommand.setLocNo(wrkMast.getLocNo());
                                    wrkMast.setWrkSts(9L);//小车入库中
                                }else {
                                    //小车和目标不在同一楼层
                                    //小车移动到提升机口,计算路径
                                    List<ShuttleCommand> commands = this.shuttleAssignCommand(currentLocNo, liftSiteLocNo, NavigationMapType.NONE.id, assignCommand, shuttleThread);
                                    if (commands == null) {
                                        continue;//未找到路径
                                    }
                                    //获取当前小车所在楼层的站点信息
                                    BasDevp basDevp = basDevpService.queryByLocNo(liftSiteLocNo);
                                    Short endStartCode = Short.parseShort(basDevp.getQrCodeValue());//站点二维码
//                                    //增加移动进提升机命令
//                                    ShuttleCommand moveCommand = shuttleThread.getMoveCommand(endStartCode, liftProtocol.getBarcode(), 1600, ShuttleRunDirection.TOP.id, null, null, 500);
//                                    commands.add(moveCommand);
                                    //分配目标库位
                                    shuttleProtocol.setLocNo(liftSiteLocNo);
                                    //目标库位
                                    assignCommand.setLocNo(liftSiteLocNo);
//                                    assignCommand.setCommands(commands);
                                    wrkMast.setWrkSts(5L);//小车迁移状态
                                }
                            } else if (wrkMast.getWrkSts() == 8) {
                                //直接计算车到提升机取货再到库位路径指令
                                List<ShuttleCommand> commands = this.shuttleAssignCommand(wrkMast.getWrkSts() == 4 ? currentLocNo : liftSiteLocNo, liftSiteLocNo, locNo, assignCommand, shuttleThread);
                                if (commands == null) {
                                    continue;//找不到路径等待下一次
                                }
                                //此时车在提升机内部,下达一步指令让车移动到提升机口
                                Integer staNo = Utils.levToOutInStaNo(currentLev >= 2 ? currentLev + 1 : currentLev);//站点号
                                BasDevp basDevp = basDevpService.selectById(staNo);
//                                short startCode = liftProtocol.getBarcode();//提升机内部二维码
//                                Short distCode = Short.parseShort(basDevp.getQrCodeValue());//提升机口站点二维码
//                                Short runDirection = ShuttleRunDirection.BOTTOM.id;//运行方向
//                                //获取命令
//                                ShuttleCommand moveCommand = shuttleThread.getMoveCommand(startCode, distCode, 1600, runDirection, null, null, 500);
//                                commands.add(0, moveCommand);//将该指令添加到队头
//                                assignCommand.setCommands(commands);
                                //分配目标库位
                                shuttleProtocol.setLocNo(wrkMast.getLocNo());
                                //目标库位
                                assignCommand.setLocNo(wrkMast.getLocNo());
                                wrkMast.setWrkSts(9L);//小车入库中
                            }
//                            if (wrkMast.getWrkSts() == 8 || Boolean.parseBoolean(searchIdleShuttle.get("sameLay").toString())) {
//                                //同一层直接取货无需经过提升机
//                                //直接计算车到提升机取货再到库位路径指令
//                                List<ShuttleCommand> commands = this.shuttleAssignCommand(wrkMast.getWrkSts() == 4 ? currentLocNo : liftSiteLocNo, liftSiteLocNo, locNo, assignCommand, shuttleThread);
//                                if (commands == null) {
//                                    continue;//找不到路径等待下一次
//                                }
//                                if (wrkMast.getWrkSts() == 8) {
//                                    //此时车在提升机内部,下达一步指令让车移动到提升机口
//                                    Integer staNo = Utils.levToOutInStaNo(currentLev >= 2 ? currentLev + 1 : currentLev);//站点号
//                                    BasDevp basDevp = basDevpService.selectById(staNo);
//
//                                    short startCode = liftProtocol.getBarcode();//提升机内部二维码
//                                    Short distCode = Short.parseShort(basDevp.getQrCodeValue());//提升机口站点二维码
//                                    Short runDirection = ShuttleRunDirection.BOTTOM.id;//运行方向
//                                    //获取命令
//                                    ShuttleCommand moveCommand = shuttleThread.getMoveCommand(startCode, distCode, 1600, runDirection, startCode, 1600, 500);
//                                    commands.add(0, moveCommand);//将该指令添加到队头
//                                }
//                                assignCommand.setCommands(commands);
//                                //分配目标库位
//                                shuttleProtocol.setLocNo(wrkMast.getLocNo());
//                                //目标库位
//                                assignCommand.setLocNo(wrkMast.getLocNo());
//                                wrkMast.setWrkSts(9L);//小车入库中
//                            }else {
//                                //不同层,将目标库位分配成提升机库位号
//
//                                //小车移动到提升机口,计算路径
//                                List<ShuttleCommand> commands = this.shuttleAssignCommand(currentLocNo, liftSiteLocNo, NavigationMapType.NONE.id, assignCommand, shuttleThread);
//                                if (commands == null) {
//                                    continue;//未找到路径
//                                }
//
//                                //获取当前小车所在楼层的站点信息
//                                BasDevp basDevp = basDevpService.queryByLocNo(liftSiteLocNo);
//                                Short endStartCode = Short.parseShort(basDevp.getQrCodeValue());//站点二维码
//
//                                //增加移动进提升机命令
//                                ShuttleCommand moveCommand = shuttleThread.getMoveCommand(endStartCode, liftProtocol.getBarcode(), 1600, ShuttleRunDirection.TOP.id, endStartCode, 1600, 500);
//                                commands.add(moveCommand);
//
//                                //分配目标库位
//                                shuttleProtocol.setLocNo(liftSiteLocNo);
//                                //目标库位
//                                assignCommand.setLocNo(liftSiteLocNo);
//                                assignCommand.setCommands(commands);
//                                wrkMast.setWrkSts(5L);//小车迁移状态
//                            }
                            if (wrkMastMapper.updateById(wrkMast) > 0) {
                                //下发任务
                                MessageQueue.offer(SlaveType.Shuttle, assignCommand.getShuttleNo().intValue(), new Task(3, assignCommand));
                            }
                        }
                    }
                boolean step1 = this.shuttleInExecuteStep1(wrkMast, basDevp);//小车搬入库中
                if (!step1) {
                    continue;
                }
            }
        }
    }
    /**
     * 入库-小车搬入库中
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
    public boolean shuttleInExecuteStep1(WrkMast wrkMast, BasDevp basDevp) {
        if (wrkMast.getWrkSts() == 4) {
            if (wrkMast.getShuttleNo() == null) {//没有绑定小车,进行调度
                dispatchShuttle(wrkMast.getWrkNo(), basDevp.getLocNo());//调度小车到货物所在输送站点进行取货
                return false;
            }
            //获取四向穿梭车线程
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
            if (shuttleThread == null) {
                return false;
            }
            ShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol();
            if (shuttleProtocol == null) {
                return false;
            }
            if (!shuttleProtocol.isIdle()) {
                return false;
            }
            //判断小车是否到达输送站点库位
            if (!shuttleProtocol.getCurrentLocNo().equals(basDevp.getLocNo())) {
                //小车不在输送站点位置
                dispatchShuttle(wrkMast.getWrkNo(), basDevp.getLocNo());//调度小车到货物所在输送站点进行取货
                return false;
            }
            //小车已抵达输送站点位置,进行搬运货物
            NyShuttleOperaResult result = NyShuttleOperaUtils.getShuttleTransportCommands(wrkMast.getShuttleNo(), wrkMast.getWrkNo(), shuttleProtocol.getCurrentLocNo(), basDevp.getLocNo(), wrkMast.getLocNo());
            if (result == null) {//路径计算失败
                return false;
            }
            //创建分配命令
            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo());//四向穿梭车号
            assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());//任务号
            assignCommand.setTaskMode(ShuttleTaskModeType.PAK_IN.id.shortValue());//入库模式
            assignCommand.setSourceLocNo(shuttleProtocol.getCurrentLocNo());//源库位(小车当前位置)
            assignCommand.setCommands(result.getCommands());//运行命令
            assignCommand.setNodes(result.getNodes());//路径节点
            wrkMast.setWrkSts(5L);//4.提升机搬运完成 => 5.小车搬运中
            wrkMast.setModiTime(new Date());
            if (wrkMastMapper.updateById(wrkMast) > 0) {
                //下发任务
                MessageQueue.offer(SlaveType.Shuttle, assignCommand.getShuttleNo().intValue(), new Task(3, assignCommand));
            }
            return false;
        }
        return true;
    }
    //获取起点-终点指令
@@ -1104,7 +957,7 @@
    /**
     * 出库  ===>>  四向穿梭车出库作业下发
     */
    public synchronized void shuttleIoOutExecute() {
    public synchronized void shuttleOutExecute() {
        for (WrkMast wrkMast : wrkMastMapper.selectBy2125()) {
            //提取一条待出库任务
            if (wrkMast != null) {