Junjie
2023-06-17 928bc386bea03b9d3157e6d66dcb7afc843e9964
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -670,12 +670,40 @@
                        if (wrkMast.getWrkSts() == 4 || wrkMast.getWrkSts() == 8) {
                            ShuttleThread shuttleThread = null;
                            HashMap<String, Object> searchIdleShuttle = null;
                            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, 1);
                            LiftProtocol liftProtocol = liftThread.getLiftProtocol();
                            if (wrkMast.getWrkSts() == 4) {
                                //寻找最近且空闲的四向穿梭车
                                searchIdleShuttle = this.searchIdleShuttle(wrkMast);
                                shuttleThread = (ShuttleThread) searchIdleShuttle.get("result");
                            }else {
                                //状态8,四向穿梭车已在提升机口,等待命令进行入库搬运动作
                            }else if(wrkMast.getWrkSts() == 8){//状态8,需要向小车下发命令从提升机移动出去,需要判断提升机状是否空闲、提升机是否到达目标楼层、目标楼层站点是否存在、目标楼层站点是否给出提升机到位信号
                                //状态8,等待命令进行入库搬运动作
                                //判断提升机是否空闲
                                if (!liftProtocol.isIdle()) {
                                    continue;//提升机忙
                                }
                                //判断提升机楼层是否到位,判断站点是否给出提升机到位信号
                                String locNo = wrkMast.getLocNo();
                                int lev = Utils.getLev(locNo);//目标二维码所在楼层
                                int liftLev = liftProtocol.getLev().intValue();//提升机所在楼层
                                if (liftLev != lev) {
                                    continue;//提升机不在目标楼层跳过
                                }
                                Integer staNo = Utils.levToOutInStaNo(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);
                            }
@@ -705,7 +733,7 @@
                            assignCommand.setSourceLocNo(currentLocNo);//源库位(小车当前位置)
                            String locNo = wrkMast.getLocNo();//当前工作档库位号
                            Integer currentLev = Utils.getLev(currentLocNo);//小车当前层高
                            Integer currentLev = wrkMast.getWrkSts() == 4 ? Utils.getLev(currentLocNo) : liftProtocol.getLev();//小车当前层高
                            //提升机口站点库位号
                            String liftSiteLocNo = Utils.levToOutInStaLocNo(currentLev);
@@ -713,15 +741,17 @@
                            if (wrkMast.getWrkSts() == 8 || Boolean.parseBoolean(searchIdleShuttle.get("sameLay").toString())) {
                                //同一层直接取货无需经过提升机
                                //直接计算车到提升机取货再到库位路径指令
                                List<ShuttleCommand> commands = this.shuttleAssignCommand(currentLocNo, liftSiteLocNo, locNo, assignCommand,shuttleThread);
                                List<ShuttleCommand> commands = this.shuttleAssignCommand(wrkMast.getWrkSts() == 4 ? currentLocNo : liftSiteLocNo, liftSiteLocNo, locNo, assignCommand, shuttleThread);
                                if (wrkMast.getWrkSts() == 8) {
                                    //此时车在提升机内部,需要多下达一步指令让车移动到提升机口
                                    BasDevp basDevp = basDevpService.selectById(109);//获取提升机信息
                                    short startCode = Short.parseShort(basDevp.getQrCodeValue());//提升机内部二维码
                                    Short distCode = commands.get(0).getStartCodeNum();//提升机口二维码
                                    Short runDirection = commands.get(0).getRunDirection();//运行方向
                                    //此时车在提升机内部,下达一步指令让车移动到提升机口
                                    Integer staNo = Utils.levToOutInStaNo(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, 1300, runDirection, (short) 1, 0);
                                    ShuttleCommand moveCommand = shuttleThread.getMoveCommand(startCode, distCode, 1400, runDirection, startCode, 1400, 1000);
                                    commands.add(0, moveCommand);//将该指令添加到队头
                                }
                                assignCommand.setCommands(commands);
@@ -735,6 +765,15 @@
                                //小车移动到提升机口,计算路径
                                List<ShuttleCommand> commands = this.shuttleAssignCommand(currentLocNo, liftSiteLocNo, ShuttleTaskModeType.PAK_IN.id, assignCommand, shuttleThread);
                                //获取当前小车所在楼层的站点信息
                                BasDevp basDevp = basDevpService.queryByLocNo(liftSiteLocNo);
                                Short endStartCode = Short.parseShort(basDevp.getQrCodeValue());//站点二维码
                                //增加移动进提升机命令
                                ShuttleCommand moveCommand = shuttleThread.getMoveCommand(endStartCode, liftProtocol.getBarcode(), 1400, ShuttleRunDirection.TOP.id, endStartCode, 1400, 1000);
                                commands.add(moveCommand);
                                //分配目标库位
                                shuttleProtocol.setLocNo(liftSiteLocNo);
                                //目标库位
@@ -923,11 +962,43 @@
                        || wrkMast.getWrkSts() == 31) {
                    ShuttleThread shuttleThread = null;
                    HashMap<String, Object> searchIdleShuttle = null;
                    LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, 1);
                    LiftProtocol liftProtocol = liftThread.getLiftProtocol();
                    if (wrkMast.getWrkSts() == 21) {
                        //寻找最近且空闲的四向穿梭车
                        searchIdleShuttle = this.searchIdleShuttle(wrkMast);
                        shuttleThread = (ShuttleThread) searchIdleShuttle.get("result");
                    }else if(wrkMast.getWrkSts() == 31 || wrkMast.getWrkSts() == 25) {
                    }else if(wrkMast.getWrkSts() == 25) {//状态25,需要向小车下发命令从提升机移动出去,需要判断提升机状是否空闲、提升机是否到达目标楼层、目标楼层站点是否存在、目标楼层站点是否给出提升机到位信号
                        //判断提升机是否空闲
                        if (!liftProtocol.isIdle()) {
                            continue;//提升机忙
                        }
                        //判断提升机楼层是否到位,判断站点是否给出提升机到位信号
                        String locNo = wrkMast.getSourceLocNo();
                        int lev = Utils.getLev(locNo);//目标二维码所在楼层
                        int liftLev = liftProtocol.getLev().intValue();//提升机所在楼层
                        if (liftLev != lev) {
                            continue;//提升机不在目标楼层跳过
                        }
                        Integer staNo = Utils.levToOutInStaNo(lev);
                        DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, 1);
                        //获取目标站信息
                        StaProtocol staProtocol1 = devpThread.getStation().get(staNo);
                        if (staProtocol1 == null) {
                            continue;//站点信息不存在
                        }
                        if (!staProtocol1.isLiftArrival()) {
                            continue;//站点提升机到位信号false
                        }
                        //继续完成之前小车未完成的任务
                        shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
                    } else if (wrkMast.getWrkSts() == 31) {
                        //继续完成之前小车未完成的任务
                        shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
                    }
@@ -995,6 +1066,15 @@
                            //小车到提升机口指令
                            List<ShuttleCommand> commands = this.shuttleAssignCommand(currentLocNo, liftSiteLocNo, ShuttleTaskModeType.PAK_IN.id, assignCommand, shuttleThread);
                            shuttleProtocol.setLocNo(liftSiteLocNo);
                            //获取当前小车所在楼层的站点信息
                            BasDevp basDevp = basDevpService.queryByLocNo(liftSiteLocNo);
                            Short endStartCode = Short.parseShort(basDevp.getQrCodeValue());//站点二维码
                            //增加移动进提升机命令
                            ShuttleCommand moveCommand = shuttleThread.getMoveCommand(endStartCode, liftProtocol.getBarcode(), 1400, ShuttleRunDirection.TOP.id, endStartCode, 1400, 1000);
                            commands.add(moveCommand);
                            //目标库位
                            assignCommand.setLocNo(liftSiteLocNo);
                            assignCommand.setCommands(commands);
@@ -1032,10 +1112,13 @@
     */
    public HashMap<String,Object> searchIdleShuttle(WrkMast wrkMast) {
        HashMap<String, Object> map = new HashMap<>();
        String locNo = wrkMast.getWrkSts() < 10 ? wrkMast.getLocNo() : wrkMast.getSourceLocNo();//库位号
        String locNo = wrkMast.getIoType() < 101 ? wrkMast.getLocNo() : wrkMast.getSourceLocNo();//库位号
        LocMast locMast = locMastService.queryByLoc(locNo);//找到库位记录
        int lev = Utils.getLev(locNo);//当前工作档库位层高
        ShuttleThread recentShuttle = null;//当前距离最近的四向穿梭车线程
        ArrayList<ShuttleThread> sameLev = new ArrayList<>();//相同楼层的穿梭车
        ArrayList<ShuttleThread> diffLev = new ArrayList<>();//不同楼层的穿梭车
        for (ShuttleSlave shuttle : slaveProperties.getShuttle()) {
            //获取四向穿梭车线程
@@ -1051,58 +1134,131 @@
            String shuttleLocNo = shuttleProtocol.getCurrentLocNo();//二维码对应库位号
            int shuttleLocNoLey = Utils.getLev(shuttleLocNo);//库位号对应层高
            if (lev == shuttleLocNoLey) {
                //当前四向穿梭车和工作档任务在同一层,则调配该车辆
                map.put("sameLay", true);//同一层
                map.put("result", shuttleThread);
                return map;
            }
            //更新当前最近的四向穿梭车
            if (recentShuttle == null) {
                recentShuttle = shuttleThread;
                //工作档楼层相同的穿梭车
                sameLev.add(shuttleThread);
            }else {
                ShuttleProtocol recentShuttleProtocol = recentShuttle.getShuttleProtocol();//目前最近穿梭车
                String recentShuttleLocNo = recentShuttleProtocol.getCurrentLocNo();//二维码对应库位号
                String recentShuttleLocNoLay = recentShuttleLocNo.substring(recentShuttleLocNo.length() - 2, recentShuttleLocNo.length());//库位号对应层高
                int recentShuttleLocNoLayInt = Integer.parseInt(recentShuttleLocNoLay);
                int i = Math.abs(lev - recentShuttleLocNoLayInt);//工作档楼层减最近穿梭车楼层,取绝对值
                int j = Math.abs(lev - shuttleLocNoLey);//工作档楼层减当前穿梭车楼层,取绝对值
                if (i < j) {
                    //更新最近穿梭车
                    recentShuttle = shuttleThread;
                } else if (i == j) {
                    //楼层相同情况
                    //找距离出库点最近的车
                    if (!(recentShuttleProtocol.isIdle() && shuttleProtocol.isIdle())) {
                        //只要有一辆车不是空闲则不进行调度
                        map.put("sameLay", false);//不同层
                        map.put("result", null);
                        return map;
                    }
                    //获取提升机
                    LiftSlave liftSlave = slaveProperties.getLift().get(0);
                    //提升机库位号
                    String recentLiftLocNo = liftSlave.getLiftLocNo(recentShuttleLocNoLayInt);
                    String shuttleLiftLocNo = liftSlave.getLiftLocNo(shuttleLocNoLey);
                    //当前最近四向穿梭车到提升机路径
                    List<NavigateNode> recentShuttlePath = NavigateUtils.calc(recentShuttleLocNo, recentLiftLocNo, ShuttleTaskModeType.PAK_IN.id);
                    //当前楼层四向穿梭车到提升机路径
                    List<NavigateNode> shuttlePath = NavigateUtils.calc(shuttleLocNo, shuttleLiftLocNo, ShuttleTaskModeType.PAK_IN.id);
                    //判断哪一个路径最短
                    if (shuttlePath.size() < recentShuttlePath.size()) {
                        //如果当前楼层的车路径更小,则更新最近穿梭车
                        recentShuttle = shuttleThread;
                    }
                }
                //工作档不同楼层的穿梭车
                diffLev.add(shuttleThread);
            }
//
//            //更新当前最近的四向穿梭车
//            if (recentShuttle == null) {
//                recentShuttle = shuttleThread;
//            }else {
//                ShuttleProtocol recentShuttleProtocol = recentShuttle.getShuttleProtocol();//目前最近穿梭车
//                String recentShuttleLocNo = recentShuttleProtocol.getCurrentLocNo();//二维码对应库位号
//                String recentShuttleLocNoLay = recentShuttleLocNo.substring(recentShuttleLocNo.length() - 2, recentShuttleLocNo.length());//库位号对应层高
//
//                int recentShuttleLocNoLayInt = Integer.parseInt(recentShuttleLocNoLay);
//                int i = Math.abs(lev - recentShuttleLocNoLayInt);//工作档楼层减最近穿梭车楼层,取绝对值
//                int j = Math.abs(lev - shuttleLocNoLey);//工作档楼层减当前穿梭车楼层,取绝对值
//                if (i < j) {
//                    //更新最近穿梭车
//                    recentShuttle = shuttleThread;
//                } else if (i == j) {
//                    //楼层相同情况
//                    //找距离出库点最近的车
//
//                    if (!(recentShuttleProtocol.isIdle() && shuttleProtocol.isIdle())) {
//                        //只要有一辆车不是空闲则不进行调度
//                        map.put("sameLay", false);//不同层
//                        map.put("result", null);
//                        return map;
//                    }
//
//                    //获取提升机
//                    LiftSlave liftSlave = slaveProperties.getLift().get(0);
//                    //提升机库位号
//                    String recentLiftLocNo = liftSlave.getLiftLocNo(recentShuttleLocNoLayInt);
//                    String shuttleLiftLocNo = liftSlave.getLiftLocNo(shuttleLocNoLey);
//
//                    //当前最近四向穿梭车到提升机路径
//                    List<NavigateNode> recentShuttlePath = NavigateUtils.calc(recentShuttleLocNo, recentLiftLocNo, ShuttleTaskModeType.PAK_IN.id);
//                    //当前楼层四向穿梭车到提升机路径
//                    List<NavigateNode> shuttlePath = NavigateUtils.calc(shuttleLocNo, shuttleLiftLocNo, ShuttleTaskModeType.PAK_IN.id);
//                    //判断哪一个路径最短
//                    if (shuttlePath.size() < recentShuttlePath.size()) {
//                        //如果当前楼层的车路径更小,则更新最近穿梭车
//                        recentShuttle = shuttleThread;
//                    }
//                }
//            }
        }
        map.put("sameLay", false);//不同层
        map.put("result", recentShuttle);
        if (sameLev.size() > 0) {
            //同一楼层有空闲穿梭车,则只在工作档楼层寻找
            //寻找离任务最近的穿梭车
            for (ShuttleThread shuttleThread : sameLev) {
                if (recentShuttle == null) {//最近穿梭车为空,则默认赋予为最近穿梭车
                    recentShuttle = shuttleThread;
                }
                //判断其他空闲穿梭车是否离任务最近
                String distLocNo = null;//目标地点,入库=》提升机口,出库=》货物库位号
                if (wrkMast.getIoType() < 101) {
                    //入库
                    distLocNo = Utils.levToOutInStaLocNo(lev);
                }else {
                    //出库
                    distLocNo = locNo;
                }
                //当前穿梭车库位号
                String currentLocNo = shuttleThread.getShuttleProtocol().getCurrentLocNo();
                //目前最近穿梭车库位号
                String recentLocNo = recentShuttle.getShuttleProtocol().getCurrentLocNo();
                //当前最近四向穿梭车到目标地点距离
                List<NavigateNode> recentShuttlePath = NavigateUtils.calc(recentLocNo, distLocNo, ShuttleTaskModeType.PAK_IN.id);
                //当前穿梭车线程到目标地点距离
                List<NavigateNode> currentShuttlePath = NavigateUtils.calc(currentLocNo, distLocNo, ShuttleTaskModeType.PAK_IN.id);
                if (recentShuttlePath == null || currentShuttlePath == null) {
                    continue;
                }
                Integer recentAllDistance = NavigateUtils.getOriginPathAllDistance(recentShuttlePath);//计算当前路径行走总距离
                Integer currentAllDistance = NavigateUtils.getOriginPathAllDistance(currentShuttlePath);//计算当前路径行走总距离
                if (currentAllDistance < recentAllDistance) {
                    //如果当前楼层的车路径更小,则更新最近穿梭车
                    recentShuttle = shuttleThread;
                }
            }
            map.put("sameLay", true);//同层
            map.put("result", recentShuttle);
        }else {
            //同一楼层,没有空闲穿梭车,只能从其他楼层调度
            //寻找离任务最近的穿梭车
            for (ShuttleThread shuttleThread : diffLev) {
                if (recentShuttle == null) {//最近穿梭车为空,则默认赋予为最近穿梭车
                    recentShuttle = shuttleThread;
                }
                //当前穿梭车库位号
                String currentLocNo = shuttleThread.getShuttleProtocol().getCurrentLocNo();
                int currentLev = Utils.getLev(currentLocNo);
                //目前最近穿梭车库位号
                String recentLocNo = recentShuttle.getShuttleProtocol().getCurrentLocNo();
                int recentLev = Utils.getLev(recentLocNo);
                //当前最近四向穿梭车到当前车子所在楼层的提升机口距离
                List<NavigateNode> recentShuttlePath = NavigateUtils.calc(recentLocNo, Utils.levToOutInStaLocNo(recentLev), ShuttleTaskModeType.PAK_IN.id);
                //当前穿梭车线程到当前车子所在楼层的提升机口距离
                List<NavigateNode> currentShuttlePath = NavigateUtils.calc(currentLocNo, Utils.levToOutInStaLocNo(currentLev), ShuttleTaskModeType.PAK_IN.id);
                if (recentShuttlePath == null || currentShuttlePath == null) {
                    continue;
                }
                Integer recentAllDistance = NavigateUtils.getOriginPathAllDistance(recentShuttlePath);//计算当前路径行走总距离
                Integer currentAllDistance = NavigateUtils.getOriginPathAllDistance(currentShuttlePath);//计算当前路径行走总距离
                if (currentAllDistance < recentAllDistance) {
                    //如果当前楼层的车路径更小,则更新最近穿梭车
                    recentShuttle = shuttleThread;
                }
            }
            map.put("sameLay", false);//不同层
            map.put("result", recentShuttle);
        }
        return map;
    }
@@ -1293,7 +1449,20 @@
                commands.add(command4);//将命令添加进list
                wrkMast.setWrkSts(3L);//3.提升机搬运中
            }else if(wrkMast.getWrkSts() == 6 || wrkMast.getWrkSts() == 23) {//6.迁移小车至提升机口完成 => 7.提升机迁移小车中 || 23.迁移小车至提升机口完成 => 24.提升机迁移小车中
            } else if (wrkMast.getWrkSts() == 6) {//6.迁移小车至提升机口完成 => 7.提升机迁移小车中
                liftProtocol.setShuttleNo(wrkMast.getShuttleNo().shortValue());//设置四向穿梭车号
                //工作档目标库位号
                String wrkMastLocNo = wrkMast.getIoType() == 101 ? wrkMast.getSourceLocNo() : wrkMast.getLocNo();
                //工作档目标库位楼层
                int wrkMastLocNoLey = Utils.getLev(wrkMastLocNo);
                //提升机前往目标楼层(工作档目标楼层)
                LiftCommand command1 = liftThread.getLiftUpDownCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), wrkMastLocNoLey);
                commands.add(command1);//将命令添加进list
                wrkMast.setWrkSts(7L);//6.迁移小车至提升机口完成 => 7.提升机迁移小车中
            } else if(wrkMast.getWrkSts() == 23) {//23.迁移小车至提升机口完成 => 24.提升机迁移小车中
                liftProtocol.setShuttleNo(wrkMast.getShuttleNo().shortValue());//设置四向穿梭车号
                //找到四向穿梭车的线程
@@ -1345,7 +1514,7 @@
                LiftCommand command4 = liftThread.getLiftTurnCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), 1);
                commands.add(command4);//将命令添加进list
                wrkMast.setWrkSts(wrkMast.getWrkSts() == 6 ? 7L : 24L);//6.迁移小车至提升机口完成 => 7.提升机迁移小车中 || 23.迁移小车至提升机口完成 => 24.提升机迁移小车中
                wrkMast.setWrkSts(24L);//23.迁移小车至提升机口完成 => 24.提升机迁移小车中
            } else if (wrkMast.getWrkSts() == 27) {//27.小车出库搬运完成
                //工作档源库位号
                String wrkMastLocNo = wrkMast.getSourceLocNo();
@@ -1421,31 +1590,6 @@
            if (liftProtocol == null) {
                continue;
            }
//            //当提升机状态处于工作中,但提升机实际为空闲状态,且时长超过30秒,自动复位
//            if (liftProtocol.getProtocolStatus() == LiftProtocolStatusType.WORKING.id
//                    && liftProtocol.getTaskNo() != 0
//                    && !liftProtocol.getRunning()
//            ) {
//                if (liftProtocol.getWrkTime() == null) {
//                    continue;
//                }
//
//                Date wrkTime = liftProtocol.getWrkTime();
//                Date now = new Date();
//                long interval = (now.getTime() - wrkTime.getTime()) / 1000;//计算时间差
//                if (interval >= 30) {//超过30秒自动复位
//                    //设置提升机为空闲状态
//                    liftProtocol.setProtocolStatus(LiftProtocolStatusType.IDLE);
//                    //任务号清零
//                    liftProtocol.setTaskNo((short) 0);
//                    //标记复位
//                    liftProtocol.setPakMk(true);
//                    //任务指令清零
//                    liftProtocol.setAssignCommand(null);
//                    News.info("提升机已确认且任务完成状态,复位。提升机号={}", liftProtocol.getLiftNo());
//                }
//            }
            //提升机为等待确认且空闲
            if (liftProtocol.getProtocolStatus() == LiftProtocolStatusType.WAITING.id