#
zjj
2024-07-10 c13fe87d70e81d7dcb604f8f1227de8f313cbefc
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/ShuttleDispatcher.java
@@ -17,10 +17,14 @@
import com.zy.asrs.wcs.rcs.News;
import com.zy.asrs.wcs.rcs.cache.SlaveConnection;
import com.zy.asrs.wcs.rcs.entity.Device;
import com.zy.asrs.wcs.rcs.model.enums.ShuttleProtocolStatusType;
import com.zy.asrs.wcs.rcs.model.enums.SlaveType;
import com.zy.asrs.wcs.rcs.model.protocol.ShuttleProtocol;
import com.zy.asrs.wcs.rcs.service.DeviceService;
import com.zy.asrs.wcs.rcs.thread.LiftThread;
import com.zy.asrs.wcs.rcs.thread.ShuttleThread;
import com.zy.asrs.wcs.system.entity.Dict;
import com.zy.asrs.wcs.system.service.DictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -53,11 +57,16 @@
    private TaskCtgService taskCtgService;
    @Autowired
    private ShuttleStandbyService shuttleStandbyService;
    @Autowired
    private DictService dictService;
    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());
        List<Device> list = deviceService.list(new LambdaQueryWrapper<Device>()
                .eq(Device::getDeviceType, DeviceCtgType.SHUTTLE.val())
@@ -77,6 +86,21 @@
            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;//小车禁用该楼层跳过该车
                }
            }
            //检测是否存在充电任务
@@ -99,10 +123,17 @@
            if (currentLev == Utils.getLev(locNo)) {
                targetLocNo = locNo;
            }else {
                Device recentTransferLift = Utils.getRecentTransferLift(locNo, Integer.parseInt(device.getDeviceNo()));
                if (recentTransferLift == null) {
                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>()
@@ -131,7 +162,7 @@
            }
            // 挂载任务权重
            List<Task> tasks = taskService.selectWorkingByShuttle(Integer.valueOf(device.getDeviceNo()));
            List<Task> tasks = taskService.selectWorkingByShuttle(Integer.valueOf(device.getDeviceNo()), null);
            if (!Cools.isEmpty(tasks)) {
                currDistance += tasks.size() * WEIGHT;
            }
@@ -272,20 +303,24 @@
        }
        int lev = Utils.getLev(locNo);//当前楼层
        JSONArray standbyLoc = JSON.parseArray(idleLoc);
        if (lev > standbyLoc.size()) {
        List<String> standbyLoc = JSON.parseArray(idleLoc, String.class);
        if (standbyLoc.isEmpty()) {
            throw new CoolException("避让数据异常");
        }
        Object object = standbyLoc.get(lev - 1);
        List<String> locs = JSON.parseArray(object.toString(), String.class);
        if (locs.isEmpty()) {
            throw new CoolException("避让数据为空");
        //获取当前层避让位置
        List<String> currentLevStandByLoc = new ArrayList<>();
        for (String loc : standbyLoc) {
            if (Utils.getLev(loc) == lev) {
                currentLevStandByLoc.add(loc);
            }
        }
        if (currentLevStandByLoc.isEmpty()) {
            throw new CoolException("当前层无避让位置");
        }
        Integer finalDistance = ShuttleDispatcher.INF;
        String recentLoc = null;
        for (String loc : locs) {
        for (String loc : currentLevStandByLoc) {
            //当前穿梭车到避让位计算
            List<NavigateNode> currentShuttlePath = NavigateUtils.calc(
                    locNo
@@ -311,5 +346,68 @@
        return recentLoc;
    }
    /**
     * 检测目标楼层车数量是否小于允许的最大数量
     * true: 小于最大数量  false: 大于或等于最大数量
     */
    public boolean checkDispatchMaxNum(Integer lev, Long hostId) {
        Dict dict = dictService.getOne(new LambdaQueryWrapper<Dict>().eq(Dict::getFlag, "dispatchShuttleMaxNum"));
        if (dict == null) {
            return false;
        }
        int levCount = 0;//目标楼层车辆数量
        List<Device> list = deviceService.list(new LambdaQueryWrapper<Device>()
                .eq(Device::getDeviceType, DeviceCtgType.SHUTTLE.val())
                .eq(Device::getHostId, hostId)
                .eq(Device::getStatus, 1));
        for (Device device : list) {
            //获取四向穿梭车线程
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, device.getId().intValue());
            if (shuttleThread == null) {
                continue;
            }
            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
            if (shuttleProtocol == null) {
                continue;
            }
            if (shuttleProtocol.getProtocolStatusType() == ShuttleProtocolStatusType.OFFLINE){
                continue;
            }
            if (Utils.getLev(shuttleProtocol.getCurrentLocNo()) == lev) {
                if (shuttleProtocol.getHasCharge()) {
                    continue;//充电中
                }
                levCount++;//目标楼层有车,数量增加
            }
        }
        //搜索是否存在前往目标楼层的小车移动工作档
        for (Task task : taskService.list(new LambdaQueryWrapper<Task>()
                .in(Task::getTaskSts, TaskStsType.NEW_MOVE.sts, TaskStsType.ANALYZE_MOVE.sts, TaskStsType.EXECUTE_MOVE.sts, TaskStsType.COMPLETE_MOVE.sts))) {
            if (task.getOriginLoc() == null || task.getDestLoc() == null) {
                continue;
            }
            int sourceLev = Utils.getLev(task.getOriginLoc());//工作档源楼层
            int targetLev = Utils.getLev(task.getDestLoc());//工作档目标楼层
            if (sourceLev == targetLev) {
                continue;//工作档楼层和目标楼层相同,跳过
            }
            if (targetLev == lev) {
                levCount++;//工作档目标楼层和实际楼层相同,数量增加
                continue;
            }
        }
        return levCount < Integer.parseInt(dict.getValue());
    }
}