自动化立体仓库 - WCS系统
Junjie
2024-11-22 ab39e1f220db502ed235b0fca3492ff7fdbfe308
src/main/java/com/zy/common/utils/ShuttleDispatchUtils.java
@@ -33,9 +33,7 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.*;
/**
 * 四向穿梭车调度工具
@@ -105,6 +103,11 @@
                continue;
            }
            if (shuttleProtocol.getWorkingMode() == 0) {
                //小车处于手动模式
                continue;
            }
            int currentLev = shuttleProtocol.getPoint().getZ();//小车当前层高
            String currentLocNo = shuttleProtocol.getCurrentLocNo();//小车当前库位号
@@ -130,11 +133,9 @@
        }
        Integer recentAllDistance = 9999999;
        NyShuttleThread recentShuttle = null;//当前距离最近的四向穿梭车线程
        if (sameLev.size() > 0) {
            //同一楼层有空闲穿梭车,则只在工作档楼层寻找
            //寻找离任务最近的穿梭车
        //优先调度同楼层小车,寻找离任务最近的穿梭车
        if (!sameLev.isEmpty()) {
            Map<Integer, NyShuttleThread> sameShuttles = new TreeMap<>();//自然排序小车Map
            for (NyShuttleThread shuttleThread : sameLev) {
                //当前穿梭车库位号
                String currentLocNo = shuttleThread.getShuttleProtocol().getCurrentLocNo();
@@ -144,19 +145,26 @@
                    continue;
                }
                Integer currentAllDistance = NavigateUtils.getOriginPathAllDistance(currentShuttlePath);//计算当前路径行走总距离
                if (currentAllDistance < recentAllDistance) {
                    //如果当前楼层的车路径更小,则更新最近穿梭车
                    recentShuttle = shuttleThread;
                    recentAllDistance = currentAllDistance;
                sameShuttles.put(currentAllDistance, shuttleThread);
            }
            //尝试调度同楼层小车
            for (Map.Entry<Integer, NyShuttleThread> entry : sameShuttles.entrySet()) {
                NyShuttleThread shuttleThread = entry.getValue();
                //尝试调度小车
                boolean result = shuttleMoveGenerate(wrkNo, locNo, shuttleThread.getSlave().getId());
                if (result) {
                    return true;//调度成功
                }
            }
        }else {
            //同一楼层,没有空闲穿梭车,只能从其他楼层调度
            //寻找离任务楼层最近的穿梭车(不考虑跨楼层小车移动距离)
        }
        //执行到此处,同楼层无调度成功小车。需要进行跨楼层调度小车
        //寻找离任务楼层最近的穿梭车(不考虑跨楼层小车移动距离)
        if (!diffLev.isEmpty()) {
            Map<Integer, NyShuttleThread> diffShuttles = new TreeMap<>();//自然排序小车Map
            //获取任务
            WrkMast wrkMast1 = wrkMastMapper.selectByWorkNo(wrkNo);
            if (wrkMast1 != null) {
                String targetLoc = wrkMast1.getIoType() < 100 ? wrkMast1.getLocNo() : wrkMast1.getSourceLocNo();
                int lev = Utils.getLev(targetLoc);//目标楼层
@@ -168,35 +176,36 @@
                    return false;
                }
                int recentValue = 99999;//最小差值
                for (NyShuttleThread shuttleThread : diffLev) {
                    //当前穿梭车库位号
                    String currentLocNo = shuttleThread.getShuttleProtocol().getCurrentLocNo();
                    int currentLev = Utils.getLev(currentLocNo);
                    List<WrkMast> wrkMasts1 = wrkMastService.selectNoShuttleWrkByLev(currentLev);//判断当前穿梭车楼层是否有待分配车辆的任务,如果有则不分配这辆车
                    if (wrkMasts1.size() > 0) {
                        //存在其他任务,跳过这辆车
                    int shuttleCount = this.getShuttleCountByLev(currentLev);//获取穿梭车楼层车辆数量
                    if (!wrkMasts1.isEmpty() && shuttleCount <= 1) {
                        //存在其他任务且可用小车数量小于等于1,跳过这辆车
                        continue;
                    }
                    //ABS(目标楼层 - 当前楼层) 得到差距,取最小差值
                    int currentValue = Math.abs(lev - currentLev);
                    if (currentValue < recentValue) {
                        //如果当前楼层的车路径更小,则更新最近穿梭车
                        recentShuttle = shuttleThread;
                        recentValue = currentValue;
                    diffShuttles.put(currentValue, shuttleThread);
                }
                //尝试调度跨楼层小车
                for (Map.Entry<Integer, NyShuttleThread> entry : diffShuttles.entrySet()) {
                    NyShuttleThread shuttleThread = entry.getValue();
                    //尝试调度小车
                    boolean result = shuttleMoveGenerate(wrkNo, locNo, shuttleThread.getSlave().getId());
                    if (result) {
                        return true;//调度成功
                    }
                }
            }
        }
        if (recentShuttle == null) {//没有搜索到可用穿梭车
            News.info("{}目标库位没有搜索到可用穿梭车", locNo);
            return false;
        }
        //搜索到可用穿梭车,调度该车
        return shuttleMoveGenerate(wrkNo, locNo, recentShuttle.getSlave().getId());
        News.info("{}目标库位没有搜索到可用穿梭车", locNo);
        return false;
    }
    /**
@@ -322,6 +331,14 @@
            }
            if (point.getZ().equals(lev)) {
                if (shuttleProtocol.getChargState() == 1) {
                    continue;//充电中
                }
                if (shuttleProtocol.getSuspendState() == 1) {
                    continue;//管制中
                }
                levCount++;//目标楼层有车,数量增加
            }
        }