#
Junjie
2024-10-18 33c638f4f7d49d92814a5d69cf51dca6026ced66
#
5个文件已修改
283 ■■■■ 已修改文件
zy-asrs-flow/src/pages/task/task/index.jsx 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/AnalyzeService.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/command/LiftCommandService.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/timer/TaskTimer.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/ShuttleDispatcher.java 205 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-flow/src/pages/task/task/index.jsx
@@ -331,6 +331,32 @@
            />,
        },
        {
            title: '小车',
            dataIndex: 'shuttleNo',
            valueType: 'text',
            hidden: false,
            width: 140,
            filterDropdown: (props) => <TextFilter
                name='phase'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '提升机',
            dataIndex: 'liftNo',
            valueType: 'text',
            hidden: false,
            width: 140,
            filterDropdown: (props) => <TextFilter
                name='phase'
                {...props}
                actionRef={actionRef}
                setSearchParam={setSearchParam}
            />,
        },
        {
            title: '空托',
            dataIndex: 'emptyMk$',
            valueType: 'text',
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/AnalyzeService.java
@@ -170,7 +170,7 @@
                            dto.setLev(Utils.getLev(task.getDestLoc()));
                            dto.setStaNo(getStaByLev(Utils.getLev(task.getDestLoc())));
                            dto.setDevpNo(basConveyorStaDest.getConveyorDeviceId().intValue());
//                            dto.setSync();//异步执行
                            dto.setReleaseLift(1);//执行完成后释放提升机
                        }))
                ));
@@ -206,7 +206,7 @@
                            dto.setShuttleNo(shuttleDevice.getId().intValue());
                            dto.setLiftNo(transferLiftDevice.getId().intValue());
                            dto.setLocNo(destLoc);
                            dto.setReleaseLift(2);//执行中释放提升机
//                            dto.setReleaseLift(2);//执行中释放提升机
                        })),
                        MotionCtgType.SHUTTLE_TRANSPORT
                ));
@@ -237,6 +237,7 @@
                            dto.setLev(Utils.getLev(task.getDestLoc()));
                            dto.setStaNo(getStaByLev(Utils.getLev(task.getDestLoc())));
                            dto.setDevpNo(basConveyorStaDest.getConveyorDeviceId().intValue());
                            dto.setReleaseLift(1);//执行完成后释放提升机
                        }))
                ));
@@ -382,7 +383,6 @@
                            dto.setShuttleNo(shuttleDevice.getId().intValue());
                            dto.setLiftNo(transferLiftDevice.getId().intValue());
                            dto.setLocNo(destLoc);
                            dto.setReleaseLift(2);//执行中释放提升机
                        })),
                        MotionCtgType.SHUTTLE_TRANSPORT
                ));
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/command/LiftCommandService.java
@@ -113,6 +113,50 @@
//                    return false;
//                }
                //判断目标站是否有托盘
                Integer conveyorDeviceId = Integer.parseInt(motion.getDockNo());
                DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, conveyorDeviceId);
                if (devpThread == null) {
                    return false;
                }
//                //*************标准系统代码********************
//                StaProtocol staProtocol = devpThread.getStation().get(motion.getTarDrt());
//                if (staProtocol == null) {
//                    return false;
//                }
//                if (!staProtocol.isAutoing()) {
//                    return false;
//                }
//                if (staProtocol.isLoading()) {
//                    return false;
//                }
//                if (staProtocol.getWorkNo().intValue() != 0) {
//                    return false;
//                }
//                //*************************************************
                //*************此代码为光泰定制代码********************
                Integer tarDrt = motion.getTarDrt();
                if (tarDrt == 31001) {
                    tarDrt = 31004;
                }
                StaProtocol staProtocol = devpThread.getStation().get(tarDrt);
                if (staProtocol == null) {
                    return false;
                }
                if (!staProtocol.isAutoing()) {
                    return false;
                }
                if (staProtocol.isLoading()) {
                    return false;
                }
                if (staProtocol.getWorkNo().intValue() != 0) {
                    return false;
                }
                //*************************************************
                command = liftThread.getPalletInOutCommand(assignCommand.getDeviceTaskNo(), Integer.parseInt(motion.getOrigin()), Integer.parseInt(motion.getTarget()), motion.getOriDrt(), motion.getTarDrt(), LiftCommandModeType.PALLET_INOUT);
                list.addAll(command);
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/timer/TaskTimer.java
@@ -64,7 +64,7 @@
                if(task.getTaskSts().equals(TaskStsType.COMPLETE_INBOUND.sts) || task.getTaskSts().equals(TaskStsType.COMPLETE_OUTBOUND.sts)){
                    boolean httpRequest = doHttpRequest(task, wmsUrl, "/open/asrs//wrkMast/finish/v1");
                    if (!httpRequest) {
                        return;
                        continue;
                    }
                }
            }
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/ShuttleDispatcher.java
@@ -60,17 +60,44 @@
    public synchronized ShuttleThread searchIdleShuttle(Task task) {
        String locNo = taskService.judgeInbound(task) ? task.getDestLoc() : task.getOriginLoc();
        ShuttleThread resThread = null;
        Integer finalDistance = ShuttleDispatcher.INF;
        //检测目标楼层车数量是否小于允许的最大数量
        boolean checkDispatchMaxNum = checkDispatchMaxNum(Utils.getLev(locNo), task.getHostId());
        int lev = Utils.getLev(locNo);
        List<Device> list = deviceService.list(new LambdaQueryWrapper<Device>()
                .eq(Device::getDeviceType, DeviceCtgType.SHUTTLE.val())
                .eq(Device::getHostId, task.getHostId())
                .eq(Device::getStatus, 1));
        //获取同层小车
        List<Device> currentLevDevices = new ArrayList<>();
        //获取跨层小车
        List<Device> diffLevDevices = new ArrayList<>();
        for (Device device : list) {
            //获取四向穿梭车线程
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, device.getId().intValue());
            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
            if (shuttleProtocol == null || shuttleProtocol.getShuttleNo() == null) {
                continue;
            }
            if (Utils.getLev(shuttleProtocol.getCurrentLocNo()) == lev) {
                currentLevDevices.add(device);
            }else {
                diffLevDevices.add(device);
            }
        }
        //搜索同层
        resThread = this.searchCurrentLevShuttle(currentLevDevices, locNo);
        //同层没有搜索到合适小车,跨楼层搜索
        if(resThread == null) {
            resThread = this.searchDiffLevShuttle(diffLevDevices, locNo, task);
        }
        return resThread;
    }
    private synchronized ShuttleThread searchCurrentLevShuttle(List<Device> devices, String locNo) {
        ShuttleThread resThread = null;
        Integer finalDistance = ShuttleDispatcher.INF;
        for (Device device : devices) {
            if (taskService.hasBusyOutboundByShuttle(Integer.parseInt(device.getDeviceNo()))) {
                continue;
            }
@@ -115,32 +142,102 @@
                break;
            }
            String targetLocNo = null;//默认到提升机待机位
            // 同楼层直接计算到目标库位
            if (currentLev == Utils.getLev(locNo)) {
                targetLocNo = locNo;
            }else {
                if (!checkDispatchMaxNum) {
                    News.info("{}任务,{}层,已经达到当前楼层调度车辆最大值", task.getTaskNo(), Utils.getLev(locNo));
                    continue;
                }
                //获取距离目标位置最近的空闲可换层提升机
                LiftThread liftThread = liftDispatcher.searchIdleLift(locNo, task.getHostId(), true);
                if (liftThread == null) {
                    continue;
                }
                Device recentTransferLift = liftThread.getDevice();
                //获取小车楼层提升机待机位
                ShuttleStandby shuttleStandby = shuttleStandbyService.getOne(new LambdaQueryWrapper<ShuttleStandby>()
                        .eq(ShuttleStandby::getDeviceId, recentTransferLift.getId())
                        .eq(ShuttleStandby::getDeviceLev, currentLev)
                        .eq(ShuttleStandby::getStatus, 1));
                targetLocNo = shuttleStandby.getDeviceLoc();
            //当前穿梭车线程到当前车子所在楼层的目标库位距离
            List<NavigateNode> currentShuttlePath = NavigateUtils.calc(
                    currentLocNo
                    , locNo
                    , NavigationMapType.NORMAL.id
                    , Utils.getShuttlePoints(Integer.parseInt(shuttleThread.getDevice().getDeviceNo()), currentLev)
            );//搜索空闲穿梭车,使用正常通道地图
            if (currentShuttlePath == null) {
                continue;
            }
            //当前穿梭车线程到当前车子所在楼层的提升机口距离
            Integer currDistance = NavigateUtils.getOriginPathAllDistance(currentShuttlePath);//计算当前路径行走总距离
            // 挂载任务权重
            List<Task> tasks = taskService.selectWorkingByShuttle(Integer.valueOf(device.getDeviceNo()), null);
            if (!Cools.isEmpty(tasks)) {
                currDistance += tasks.size() * WEIGHT;
            }
            if (currDistance < finalDistance) {
                finalDistance = currDistance;
                resThread = shuttleThread;
            }
        }
        return resThread;
    }
    private synchronized ShuttleThread searchDiffLevShuttle(List<Device> devices, String locNo, Task task) {
        ShuttleThread resThread = null;
        Integer finalDistance = ShuttleDispatcher.INF;
        //检测目标楼层车数量是否小于允许的最大数量
        boolean checkDispatchMaxNum = checkDispatchMaxNum(Utils.getLev(locNo), task.getHostId());
        for (Device device : devices) {
            if (taskService.hasBusyOutboundByShuttle(Integer.parseInt(device.getDeviceNo()))) {
                continue;
            }
            //获取四向穿梭车线程
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, device.getId().intValue());
            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
            if (shuttleProtocol == null || shuttleProtocol.getShuttleNo() == null) {
                continue;
            }
            if (!shuttleThread.isIdle()) {
                continue;
            }
            BasShuttle basShuttle = basShuttleService.getOne(new LambdaQueryWrapper<BasShuttle>()
                    .eq(BasShuttle::getShuttleNo, device.getDeviceNo())
                    .eq(BasShuttle::getHostId, device.getHostId()));
            if (basShuttle == null) {
                continue;//小车基础数据不存在
            }
            if (!Cools.isEmpty(basShuttle.getDisableLev())) {
                List<Integer> disableLev = JSON.parseArray(basShuttle.getDisableLev(), Integer.class);
                //检查小车是否禁用该楼层
                if (disableLev.contains(Utils.getLev(locNo))) {
                    continue;//小车禁用该楼层跳过该车
                }
            }
            //检测是否存在充电任务
            Task taskCharge = taskService.selectChargeWorking(Integer.valueOf(device.getDeviceNo()));
            if (taskCharge != null) {
                continue;
            }
            // 有没有被其他任务调度
            int currentLev = Utils.getLev(shuttleProtocol.getCurrentLocNo());//小车当前层高
            String currentLocNo = shuttleProtocol.getCurrentLocNo();//小车当前库位号
            if (!checkDispatchMaxNum) {
                News.info("{}任务,{}层,已经达到当前楼层调度车辆最大值", task.getTaskNo(), Utils.getLev(locNo));
                continue;
            }
            //获取距离小车位置最近的空闲可换层提升机
            LiftThread liftThread = liftDispatcher.searchIdleLift(currentLocNo, task.getHostId(), true);
            if (liftThread == null) {
                continue;
            }
            Device recentTransferLift = liftThread.getDevice();
            //获取小车楼层提升机待机位
            ShuttleStandby shuttleStandby = shuttleStandbyService.getOne(new LambdaQueryWrapper<ShuttleStandby>()
                    .eq(ShuttleStandby::getDeviceId, recentTransferLift.getId())
                    .eq(ShuttleStandby::getDeviceLev, currentLev)
                    .eq(ShuttleStandby::getStatus, 1));
            String targetLocNo = shuttleStandby.getDeviceLoc();
            //当前穿梭车线程到当前车子所在楼层的提升机待机位距离
            List<NavigateNode> currentShuttlePath = NavigateUtils.calc(
                    currentLocNo
                    , targetLocNo
@@ -338,7 +435,7 @@
            return false;
        }
        int levCount = 0;//目标楼层车辆数量
        ArrayList<Integer> shuttleNos = new ArrayList<>();
        List<Device> list = deviceService.list(new LambdaQueryWrapper<Device>()
                .eq(Device::getDeviceType, DeviceCtgType.SHUTTLE.val())
                .eq(Device::getHostId, hostId)
@@ -373,7 +470,7 @@
                    continue;//充电中
                }
                levCount++;//目标楼层有车,数量增加
                shuttleNos.add(shuttleProtocol.getShuttleNo());//目标楼层有车,添加进list
            }
        }
@@ -391,52 +488,34 @@
            }
            if (targetLev == lev) {
                levCount++;//工作档目标楼层和实际楼层相同,数量增加
                //工作档目标楼层和实际楼层相同,数量增加
                if (!shuttleNos.contains(task.getShuttleNo())) {
                    shuttleNos.add(task.getShuttleNo());
                }
                continue;
            }
        }
        //搜索是否存在前往目标楼层的小车工作档
        for (Task task : taskService.list(new LambdaQueryWrapper<Task>()
                .in(Task::getTaskSts, TaskStsType.NEW_INBOUND.sts, TaskStsType.ANALYZE_INBOUND.sts, TaskStsType.EXECUTE_INBOUND.sts, TaskStsType.COMPLETE_INBOUND.sts
                        , TaskStsType.NEW_OUTBOUND.sts, TaskStsType.ANALYZE_OUTBOUND.sts, TaskStsType.EXECUTE_OUTBOUND.sts, TaskStsType.COMPLETE_OUTBOUND.sts))) {
            List<Motion> motions = motionService.list(new LambdaQueryWrapper<Motion>()
                    .eq(Motion::getTaskNo, task.getTaskNo())
                    .in(Motion::getMotionCtg, MotionCtgType.SHUTTLE_MOVE
                            , MotionCtgType.SHUTTLE_MOVE_LIFT_PALLET
                            , MotionCtgType.SHUTTLE_MOVE_DOWN_PALLET
                            , MotionCtgType.SHUTTLE_MOVE_FROM_LIFT
                            , MotionCtgType.SHUTTLE_MOVE_TO_LIFT
                            , MotionCtgType.SHUTTLE_MOVE_FROM_CONVEYOR
                            , MotionCtgType.SHUTTLE_MOVE_TO_CONVEYOR
                            , MotionCtgType.SHUTTLE_MOVE_FROM_LIFT_TO_CONVEYOR
                    ));
            boolean isUpdateLev = false;
            for (Motion motion : motions) {
                if (motion.getOrigin() == null || motion.getTarget() == null) {
                    continue;
                }
                int sourceLev = Utils.getLev(motion.getOrigin());//动作源楼层
                int targetLev = Utils.getLev(motion.getTarget());//动作目标楼层
                if (sourceLev != targetLev) {
                    isUpdateLev = true;
                    break;
                }
            }
            if(isUpdateLev) {
                levCount++;//工作档属于跨层任务,小车归属于目标楼层
            String locNo = taskService.judgeInbound(task) ? task.getDestLoc() : task.getOriginLoc();
            if (Utils.getLev(locNo) != lev) {
                continue;
            }
            if (task.getShuttleNo() == null) {
                continue;
            }
            if (!shuttleNos.contains(task.getShuttleNo())) {
                shuttleNos.add(task.getShuttleNo());
            }
        }
        return levCount < Integer.parseInt(dict.getValue());
        return shuttleNos.size() < Integer.parseInt(dict.getValue());
    }
    //分析出库路径待机库位