Explorar o código

轨道车调度

wuhb hai 3 semanas
pai
achega
85b400c935

+ 4 - 0
mes/ktg-mes/src/main/java/com/ktg/mes/rms/service/impl/RmsLineServiceImpl.java

@@ -1728,6 +1728,10 @@ public class RmsLineServiceImpl implements IRmsLineService {
                     rmsTaskPool.setCheck(true);
                     ApiCache.addAgvTask(rmsTaskPool);
                 }
+                if(rmsTaskPool.getDeviceType().equals(DeviceTypeEnum.RAILAGV.getValue() + "")){
+                    rmsTaskPool.setCheck(true);
+                    ApiCache.addRailAgvTask(rmsTaskPool);
+                }
                 if (Long.parseLong(rmsTaskPool.getDeviceType()) == DeviceTypeEnum.LIFT.getValue()) {
                     rmsTaskPool.setCheck(true);
                     ApiCache.addSingeLiftTask(rmsTaskPool);

+ 119 - 12
mes/ktg-mes/src/main/java/com/ktg/mes/rms/task/ApiStockTask.java

@@ -47,6 +47,7 @@ public class ApiStockTask {
     private static final Logger log = LoggerFactory.getLogger(ApiStockTask.class);
     public static final Map<String, LiftThread> workThreadMap = new ConcurrentHashMap<>();
     public static List<AgvThread> runAgvThread = new CopyOnWriteArrayList<>();
+    public static List<RailAgvThread> runRailAgvThread = new CopyOnWriteArrayList<>();
     public static Map<String, RollerThread> runRollerThread = new ConcurrentHashMap<>();
     public static volatile boolean isStop = false;
     public static Map<String, LiftPlcHelper>  liftPlcHelpTask = new ConcurrentHashMap<>();
@@ -133,8 +134,7 @@ public class ApiStockTask {
     }
 
 //    执行AGV任务
-    @Scheduled(fixedDelay=1000)
-    public void agvTask(){
+    public void rmsAgvTask(){
         if("net".equals(robotModel)||"mes".equals(robotModel)){
             return;
         }
@@ -230,6 +230,104 @@ public class ApiStockTask {
             rmsWebSocketServer.sendToUI("lift",DateUtils.getTime() + " "+rmsTaskPool.getTaskId()+ "["+rmsTaskPool.getTaskName()+"]完成");
         }
     }
+
+    public void railAgvTask(){
+        if("net".equals(robotModel)||"mes".equals(robotModel)){
+            return;
+        }
+        List<RmsTaskPool> rmsTaskPools = ApiCache.getRailAgvPriorityList();
+        if(!rmsTaskPools.isEmpty()){
+            log.info("优先轨道agv任务数:" + rmsTaskPools.size());
+            ApiCache.insertFirstAll(rmsTaskPools);
+        }
+        if(!ApiCache.topRailAgvList.isEmpty()){
+            log.info("置顶轨道agv任务数:" + ApiCache.topRailAgvList.size());
+            ApiCache.setTopRailAgvTask();
+        }
+        RmsTaskPool rmsTaskPool = ApiCache.railAgvWorkQueue.peek();
+        if (rmsTaskPool != null) {
+            printQueue(ApiCache.railAgvWorkQueue, "轨道agv队列:");
+            log.info("轨道AGV开始:" + DateUtils.getTime() + ", " + rmsTaskPool.getTaskId());
+            rmsWebSocketServer.sendToUI("lift",DateUtils.getTime() + " 开始"+rmsTaskPool.getTaskId()+ "[" +rmsTaskPool.getTaskName()+"]");
+            try {
+                boolean isConnAgvServer = checkAgvServer(rmsTaskPool);
+                if(!isConnAgvServer){
+                    return;
+                }
+                int i = checkErrorTaskPool(rmsTaskPool, ApiCache.railAgvWorkQueue);
+                if (i == 0) {
+                    showException(rmsTaskPool, rmsTaskPool.getTaskStatus());
+                }
+                if (i == 2) {
+                    throw new Exception(rmsTaskPool.getTaskId() + "任务锁定");
+                }
+                if(i == 3){
+                    log.info("没有找到记录,等待下次查找");
+                    return;
+                }
+
+                RmsTaskPool runPool = checkInTask(rmsTaskPool);
+                if (runPool != null) {
+                    log.info(runPool.getGroupCode()+ "|" + runPool.getTaskId() + "任务正在执行");
+                    throw new Exception(runPool.getGroupCode()+"入库正在运行");
+                }
+                boolean isValid = checkPushRollerLift(rmsTaskPool);
+                if (!isValid) {
+                    throw new Exception(rmsTaskPool + "入库对接平台上有物料");
+                }
+                if (!runRailAgvThread.isEmpty()) {
+                    List<RailAgvThread> validThread = new ArrayList<>();
+                    for (RailAgvThread runThread : runRailAgvThread) {
+                        if (runThread == null || !runThread.isAlive()) {
+                            validThread.add(runThread);
+                        }
+                    }
+                    if(!validThread.isEmpty()){
+                        for (RailAgvThread thread:validThread){
+                            runRailAgvThread.remove(thread);
+                        }
+                    }
+                }
+                if(isStop){
+                    throw new Exception(rmsTaskPool.getTaskName() + "任务锁定");
+                }
+            }catch (Exception ex){
+                log.error("轨道AGV任务异常:" + ex.getMessage());
+                String msg = "轨道AGV任务异常:" + ex.getMessage();
+                if(!msg.equals(rmsTaskPool.getStartMessage())){
+                    try {
+                        updateRemark(rmsTaskPool, msg);
+                    } catch (Exception e) {
+                        log.error("异常:", e);
+                    }
+                }
+                return;
+            }
+            try {
+                RmsTaskPool rmsTaskPoolN = ApiCache.railAgvWorkQueue.poll();
+                if(rmsTaskPoolN == null){
+                    throw new Exception("轨道AGV任务异常:没有取到任务");
+                }
+                if(!rmsTaskPoolN.getTaskId().equals(rmsTaskPool.getTaskId())){
+                    log.warn("队列重排:期望 {} 实际 {}", rmsTaskPool.getTaskId(), rmsTaskPoolN.getTaskId());
+                    ApiCache.addRailAgvTask(rmsTaskPool);
+                    return;
+                }
+                rmsTaskPoolService.startGroupTask(rmsTaskPool);
+                update(rmsTaskPool, "1");
+                RailAgvThread agvThread = new RailAgvThread(rmsTaskPool);
+                agvThread.start();
+                runRailAgvThread.add(agvThread);
+            }catch (Exception ex){
+                log.error("创建轨道AGV线程异常:", ex);
+                update(rmsTaskPool, "0");
+                return;
+            }
+            log.info("轨道AGV结束:" + DateUtils.getTime());
+            rmsWebSocketServer.sendToUI("lift",DateUtils.getTime() + " "+rmsTaskPool.getTaskId()+ "["+rmsTaskPool.getTaskName()+"]完成");
+        }
+    }
+
     //    执行轨道车任务
 //    @Scheduled(fixedDelay=1000)
     public void liftTask(){
@@ -278,7 +376,7 @@ public class ApiStockTask {
         }
     }
 
-    @Scheduled(fixedDelay=1000)
+//    @Scheduled(fixedDelay=1000)
     public void syErrorPool(){
         if("net".equals(robotModel)||"mes".equals(robotModel)){
             return;
@@ -302,7 +400,6 @@ public class ApiStockTask {
         }
     }
 
-    @Scheduled(fixedDelay=5000)
     public void checkErpTask(){
 //        查找所有完成任务的出入库单, 更新ERP
         if("net".equals(robotModel)||"mes".equals(robotModel)){
@@ -792,6 +889,16 @@ public class ApiStockTask {
         return false;
     }
 
+    public static boolean checkRunRailAgv(RmsTaskPool rmsTaskPool){
+        for (RailAgvThread agvThread : runRailAgvThread){
+            RmsTaskPool rmsTask = agvThread.getRmsTaskPool();
+            if(rmsTask!=null && Objects.equals(rmsTask.getTaskId(), rmsTaskPool.getTaskId())){
+                return true;
+            }
+        }
+        return false;
+    }
+
     public static boolean checkRunLift(RmsTaskPool rmsTaskPool){
         for (LiftThread liftThread : workThreadMap.values()){
             RmsTaskPool rmsTask = liftThread.getRmsTaskPool();
@@ -950,14 +1057,14 @@ public class ApiStockTask {
     public boolean checkAgvServer(RmsTaskPool rmsTaskPool) throws Exception {
         try {
             log.info("检查AGV服务器:" + rmsTaskPool.getDeviceType());
-            if(String.valueOf(DeviceTypeEnum.ROLLERAGV.getValue()).equals(rmsTaskPool.getDeviceType())) {
-                RmsHelper rmsHelper = RmsHelper.getInstance();
-                rmsHelper.init();
-            }
-            if (String.valueOf(DeviceTypeEnum.RAILAGV.getValue()).equals(rmsTaskPool.getDeviceType())){
-                RailHelper railHelper = RailHelper.getInstance();
-                railHelper.init();
-            }
+//            if(String.valueOf(DeviceTypeEnum.ROLLERAGV.getValue()).equals(rmsTaskPool.getDeviceType())) {
+//                RmsHelper rmsHelper = RmsHelper.getInstance();
+//                rmsHelper.init();
+//            }
+//            if (String.valueOf(DeviceTypeEnum.RAILAGV.getValue()).equals(rmsTaskPool.getDeviceType())){
+//                RailHelper railHelper = RailHelper.getInstance();
+//                railHelper.init();
+//            }
             return true;
         }catch (Exception ex){
             log.error("RMS通讯异常:", ex);

+ 368 - 0
mes/ktg-mes/src/main/java/com/ktg/mes/rms/thread/RailAgvThread.java

@@ -0,0 +1,368 @@
+package com.ktg.mes.rms.thread;
+
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.ktg.common.constant.UserConstants;
+import com.ktg.common.utils.StringUtils;
+import com.ktg.common.utils.spring.SpringUtils;
+import com.ktg.mes.rms.domain.*;
+import com.ktg.mes.rms.emcsenum.DeviceTypeEnum;
+import com.ktg.mes.rms.emcsenum.RmsStatusEnum;
+import com.ktg.mes.rms.emcsenum.SiteTypeEnum;
+import com.ktg.mes.rms.emcsenum.TaskTypeEnum;
+import com.ktg.mes.rms.server.RmsWebSocketServer;
+import com.ktg.mes.rms.service.IRmsTaskOutstockLineService;
+import com.ktg.mes.rms.service.impl.RmsTaskOutstockLineServiceImpl;
+import com.ktg.mes.rms.task.ApiStockTask;
+import com.ktg.mes.rms.util.ApiCache;
+import com.ktg.mes.rms.util.RailHelper;
+import com.ktg.mes.wm.domain.WmRmsBox;
+import com.ktg.mes.wm.domain.WmRmsBoxItem;
+import com.ktg.mes.wm.domain.WmStorageArea;
+import com.ktg.mes.wm.domain.WmStorageLocation;
+import com.ktg.mes.wm.service.IWmRmsBoxItemService;
+import com.ktg.mes.wm.service.IWmRmsBoxService;
+import com.ktg.mes.wm.service.IWmStorageAreaService;
+import com.ktg.mes.wm.service.IWmStorageLocationService;
+import com.ktg.mes.wm.service.impl.WmRmsBoxItemServiceImpl;
+import com.ktg.mes.wm.service.impl.WmRmsBoxServiceImpl;
+import com.ktg.mes.wm.utils.MaterialStockTaskHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.transaction.TransactionStatus;
+import org.springframework.transaction.support.DefaultTransactionDefinition;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+public class RailAgvThread extends BaseThread{
+    private static final Logger log = LoggerFactory.getLogger(RailAgvThread.class);
+    private enum AgvStatus {RUN, DONE, CANCEL, ARRIVER}
+
+    private volatile RmsTaskPool rmsTaskPool;
+    private final RailHelper railHelper = RailHelper.getInstance(true);
+    private final IWmRmsBoxService wmRmsBoxService;
+    private final int waitAgvTime = 600;
+
+    private final IRmsTaskOutstockLineService rmsTaskOutstockLineService;
+
+    public RailAgvThread(RmsTaskPool rmsTaskPool){
+        super();
+        this.rmsTaskPool = rmsTaskPool;
+        wmRmsBoxService = SpringUtils.getBean(WmRmsBoxServiceImpl.class);
+        rmsTaskOutstockLineService = SpringUtils.getBean(RmsTaskOutstockLineServiceImpl.class);
+    }
+
+    public void run(){
+        try{
+            log.info("=========收到轨道AGV任务:"+rmsTaskPool.getTaskId()+"=========");
+            rmsTaskPoolService.startGroupTask(rmsTaskPool);
+            updateRemark(null,1, 1, "开始"+rmsTaskPool.getTaskName());
+            if(rmsTaskPool.getRunDelay()!=null && rmsTaskPool.getRunDelay() > 0){
+                System.out.println("=========延迟"+rmsTaskPool.getRunDelay()+"秒执行=========");
+                Thread.sleep(rmsTaskPool.getRunDelay()*1000);
+            }
+            String robotType = "";
+            Long deviceType = Long.parseLong(rmsTaskPool.getDeviceType());
+            if(deviceType.equals(DeviceTypeEnum.RAILAGV.getValue())){
+                robotType = DeviceTypeEnum.RAILAGV.getKey();
+            }
+            String robotId = "";
+            RmsTaskPool bindPool = getBindTask();
+            if(StringUtils.isNotEmpty(bindPool.getLiftCode())){
+                robotId = bindPool.getLiftCode();
+            }
+            if(StringUtils.isNotEmpty(rmsTaskPool.getLiftCode())){
+                robotId = rmsTaskPool.getLiftCode();
+            }
+            String taskType = rmsTaskPool.getTaskType();
+            String data = railHelper.sendAgvTask(rmsTaskPool.getFromSite(), rmsTaskPool.getToSite()
+                    , rmsTaskPool.getPickTime(), rmsTaskPool.getKeyRoute(), taskType
+                    , robotType, robotId);
+            JSONObject dataJson = JSONUtil.toBean(data, JSONObject.class);
+            String rmsRemoteTaskId = dataJson.getStr("id");
+            if(StringUtils.isNotEmpty(rmsRemoteTaskId)){
+                if(rmsTaskPool.getIsWait() == 0){
+                    updateRemark(rmsRemoteTaskId, 1, 3, rmsTaskPool.getTaskName()+"任务已发送");
+                }else{
+                    updateRemark(rmsRemoteTaskId, 1, 3, rmsTaskPool.getTaskName()+"任务已发送,等待中");
+                }
+            }else{
+                throw new Exception("AGV任务请求失败");
+            }
+            boolean isRunDone = true;
+            if(TaskTypeEnum.X2B_ROLLER_BACK_UP.getValue().equals(rmsTaskPool.getTaskType())
+                ||TaskTypeEnum.X2B_ROLLER_BACK_DOWN.getValue().equals(rmsTaskPool.getTaskType())){
+                isRunDone = waitAgv(rmsRemoteTaskId);
+            }else{
+                if(rmsTaskPool.getIsWait() != 0){    //不是出入库,不滚动,判断等待用wait
+                    log.info("开始AGV等待任务完成");
+                    isRunDone = waitAgv(rmsRemoteTaskId);
+                }
+            }
+            if(!isRunDone){
+                log.info("任务被取消,结束线程");
+                cancleOrder();
+                return;
+            }
+            waitByTask();
+            if(StringUtils.isNotNull(rmsRemoteTaskId)){
+                updateOrder();
+                updateRemark(null,2, 2, "成功");
+                checkNextTask();
+            }
+            rmsTaskPoolService.closeAutoGroupTask(rmsTaskPool);
+        }catch (Exception ex){
+            log.error("AGV异常:" + JSONUtil.toJsonStr(rmsTaskPool), ex);
+            updateLog(rmsTaskPool, ex.getMessage());
+            rmsTaskPoolService.cancelAgvTaskGroup(rmsTaskPool);
+            cancleOrder();
+        }finally {
+            this.rmsTaskPool = null;
+            ApiStockTask.runRailAgvThread.remove(this);
+        }
+    }
+
+    public void updateOrder() throws Exception {
+        DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
+        definition.setPropagationBehaviorName("PROPAGATION_REQUIRED");
+        TransactionStatus transaction = transactionManager.getTransaction(definition);
+        try {
+            Long deviceType = Long.parseLong(rmsTaskPool.getDeviceType());
+            if(deviceType.equals(DeviceTypeEnum.RAILAGV.getValue())){
+                if(rmsTaskPool.getWaitType() != null && rmsTaskPool.getWaitType() == 2){
+                    //清除料框的标注和是否扫码标识
+                    String boxCode = rmsTaskPool.getBoxCode();
+                    Long lineId = rmsTaskPool.getSourceId();
+                    if(StringUtils.isNotEmpty(boxCode)){
+                        WmRmsBox wmRmsBox = wmRmsBoxService.selectWmRmsBoxByBoxCode(boxCode);
+                        if(wmRmsBox != null && wmRmsBox.getWaitType() != null && wmRmsBox.getWaitType() == 2){
+                            //线边库搬运任务。
+                            //更新出库明细lineId的状态和库存
+                            rmsTaskPoolService.updateXbMoveStock(rmsTaskPool);
+                            // 重置isScan和lineIds
+                            wmRmsBox.setIsScan("-1");
+                            if(StringUtils.isNotEmpty(wmRmsBox.getLineIds())){
+                                String lineIds = wmRmsBox.getLineIds();
+                                String[] lineIdArray = lineIds.split(",");
+                                StringBuilder newLineIds = new StringBuilder();
+                                for (String id : lineIdArray) {
+                                    if (!id.equals(String.valueOf(lineId)))  {
+                                        if (newLineIds.length()  > 0) {
+                                            newLineIds.append(",");
+                                        }
+                                        newLineIds.append(id);
+                                    }
+                                }
+                                if(StringUtils.isNotEmpty(newLineIds.toString())){
+                                    wmRmsBox.setLineIds(newLineIds.toString());
+                                }else{
+                                    wmRmsBox.setWaitType(-1);
+                                    wmRmsBox.setLineIds("-1");
+                                }
+                            }
+                            //搬运结束料框加入出库单信息
+                            wmRmsBox.setItemOutCode(rmsTaskPool.getSourceType());
+                            wmRmsBoxService.updateWmRmsBox2(wmRmsBox);
+                        }
+                    }
+                }
+            }
+            transactionManager.commit(transaction);
+        } catch (Exception e) {
+            transactionManager.rollback(transaction);
+            throw e;
+        } finally {
+            if (!transaction.isCompleted()) {
+                transactionManager.commit(transaction);
+            }
+        }
+    }
+
+    public RmsTaskPool getBindTask(){
+        RmsTaskPool pool = new RmsTaskPool();
+        pool.setGroupCode(rmsTaskPool.getGroupCode());
+        pool.setFlowLineId(rmsTaskPool.getBindTask());
+        List<RmsTaskPool> poolList = rmsTaskPoolService.selectRmsTaskPoolList(pool);
+        if(poolList.size() > 0){
+            pool = poolList.get(0);
+        }
+        return pool;
+    }
+
+    private void checkNextTask() throws Exception {
+        List<RmsTaskPool>  nextTaskPools = rmsTaskPoolService.getTaskPoolByParent(rmsTaskPool.getTaskId());
+        if(nextTaskPools.size() > 0) {
+            log.info("插入新任务:" + nextTaskPools.size());
+            nextTaskPools.forEach(item->{
+                if(item.getTaskType().equals(TaskTypeEnum.PUSH.getValue())){
+                    item.setIsSort(1);
+                }
+            });
+            ApiCache.addPriorityList(nextTaskPools);
+            log.info("插入新任务完成");
+        }
+    }
+
+    private boolean waitAgv(String rmsRemoteTaskId) throws Exception {
+        boolean isStop = false;
+        long runTime = new Date().getTime();
+        while (!isStop){
+            AgvStatus agvStatus = checkRmsStock(rmsRemoteTaskId);
+            if(agvStatus.equals(AgvStatus.CANCEL)){
+                throw new Exception("AGV异常,取消任务");
+            }
+            if(agvStatus.equals(AgvStatus.DONE)){
+                isStop = true;
+            }
+            try {
+                RmsTaskPool pool = rmsTaskPoolService.selectRmsTaskPoolByTaskId(rmsTaskPool.getTaskId());
+                if ("4".equals(pool.getTaskStatus())) {
+                    railHelper.cancelAgvTask(rmsTaskPool.getRmsTaskId());
+                    return false;
+                }
+            }catch (Exception ex){
+                log.error("查工单状态错误:["+rmsTaskPool.getTaskId()+"]" + ex.getMessage());
+            }
+            long longTime = (new Date().getTime() - runTime)/1000;
+            if(longTime > waitAgvTime){
+                throw new Exception("等待AGV任务完成超时");
+            }
+            sleep(1000);
+        }
+        return true;
+    }
+
+    public AgvStatus checkRmsStock(String rmsTaskId) throws Exception {
+        if(StringUtils.isEmpty(rmsTaskId)){
+            throw new Exception("没有找到AGV执行的任务ID");
+        }
+        if(StringUtils.isEmpty(railHelper.session)){
+            railHelper.init();
+        }
+//        updateLiftCode(robotId, rmsTaskId);
+        return RailAgvThread.AgvStatus.DONE;
+    }
+
+    private void updateLiftCode(String robotId, String rmsTaskId){
+        if(!StringUtils.isEmpty(robotId)
+                && StringUtils.isEmpty(rmsTaskPool.getLiftCode())){
+            rmsTaskPool.setLiftCode(robotId);
+            RmsTaskPool pool = new RmsTaskPool();
+            pool.setTaskId(rmsTaskPool.getTaskId());
+            pool.setLiftCode(robotId);
+            pool.setRmsTaskId(rmsTaskId);
+            pool.setRemark("获取AGV编号");
+            rmsTaskPoolService.updateRmsTaskPoolMapper(pool);
+        }
+    }
+
+    public void updateRemark(String rmsTaskId, Integer status, int step, String remark) throws Exception {
+        rmsTaskPool.setStep(step);
+        rmsTaskPool.setTaskStatus(status+"");
+        rmsTaskPool.setRmsTaskId(rmsTaskId);
+        rmsTaskPoolService.updateMastPoolRemark(rmsTaskPool, remark);
+    }
+
+    public void waitByTask() throws Exception {
+        Integer isWait = rmsTaskPool.getIsWait();
+        if(isWait==null){
+            return;
+        }
+        String waitTaskId = rmsTaskPool.getWaitTask();
+        if(StringUtils.isEmpty(rmsTaskPool.getGroupCode())){
+            throw new Exception("任务组编号不存在");
+        }
+        if(isWait == 3 && StringUtils.isNotEmpty(waitTaskId)){
+            String[] taskIds = waitTaskId.split(",");
+            boolean isUpdate = false;
+            for(String taskId:taskIds){
+                boolean isStop = false;
+                while (!isStop){
+                    RmsTaskPool p = new RmsTaskPool();
+                    p.setGroupCode(rmsTaskPool.getGroupCode());
+                    p.setFlowLineId(Long.parseLong(taskId));
+                    List<RmsTaskPool> poolList = rmsTaskPoolService.selectRmsTaskPoolList(p);
+                    if(poolList.size() > 0){
+                        p = poolList.get(0);
+                    }else{
+                        return;
+                    }
+                    if(!("0".equals(p.getTaskStatus()) ||"1".equals(p.getTaskStatus()))){
+                        isStop = true;
+                    }
+                    if(!isUpdate){
+                        updateRemark(null,1, 3, "正在等待"+p.getTaskName()+"任务结束");
+                        isUpdate = true;
+                    }
+                    sleep(1000);
+                }
+            }
+        }
+    }
+
+    public RmsTaskPool getRmsTaskPool() {
+        return rmsTaskPool;
+    }
+
+    public void cancleOrder(){
+        Long deviceType = Long.parseLong(rmsTaskPool.getDeviceType());
+        if(deviceType.equals(DeviceTypeEnum.ROLLERAGV.getValue())){
+            if(rmsTaskPool.getWaitType() != null && rmsTaskPool.getWaitType() == 2){
+                //清除料框的标注和是否扫码标识
+                String boxCode = rmsTaskPool.getBoxCode();
+                Long lineId = rmsTaskPool.getSourceId();
+                if(StringUtils.isNotEmpty(boxCode)){
+                    WmRmsBox wmRmsBox = wmRmsBoxService.selectWmRmsBoxByBoxCode(boxCode);
+                    if(wmRmsBox != null && wmRmsBox.getWaitType() != null && wmRmsBox.getWaitType() == 2){
+                        //线边库搬运任务。
+                        wmRmsBox.setIsScan("-1");
+                        if(StringUtils.isNotEmpty(wmRmsBox.getLineIds()) && lineId != null){
+                            String lineIds = wmRmsBox.getLineIds();
+                            String[] lineIdArray = lineIds.split(",");
+                            StringBuilder newLineIds = new StringBuilder();
+                            for (String id : lineIdArray) {
+                                if (!id.equals(String.valueOf(lineId)))  {
+                                    if (newLineIds.length()  > 0) {
+                                        newLineIds.append(",");
+                                    }
+                                    newLineIds.append(id);
+                                }
+                            }
+                            if(StringUtils.isNotEmpty(newLineIds.toString())){
+                                wmRmsBox.setLineIds(newLineIds.toString());
+                            }else{
+                                wmRmsBox.setWaitType(-1);
+                                wmRmsBox.setLineIds("-1");
+                            }
+                        }
+                        wmRmsBoxService.updateWmRmsBox2(wmRmsBox);
+                    }
+                }
+                if(lineId != null){
+                    RmsTaskOutstockLine rmsTaskOutstockLine = new RmsTaskOutstockLine();
+                    rmsTaskOutstockLine.setLineId(lineId);
+                    rmsTaskOutstockLine.setBoxCode("-1");
+                    rmsTaskOutstockLine.setDeviceCode("-1");
+                    rmsTaskOutstockLine.setLiftCode("-1");
+                    rmsTaskOutstockLineService.updateRmsTaskOutstockLine(rmsTaskOutstockLine);
+                }
+            }
+        }
+    }
+
+    public boolean checkDoneOutStockLine(Long inStockId){
+        RmsTaskOutstockLine outStockLine = new RmsTaskOutstockLine();
+        outStockLine.setOutstockId(inStockId);
+        List<RmsTaskOutstockLine> rmsTaskOutStockLines = rmsTaskOutstockLineService.selectRmsTaskOutstockLineList(outStockLine);
+        return rmsTaskOutStockLines.stream().noneMatch(item->item.getStatus()!=2);
+    }
+
+    public boolean checkDoneInStockLine(Long inStockId){
+        RmsTaskInstockLine inStockLine = new RmsTaskInstockLine();
+        inStockLine.setInstockId(inStockId);
+        List<RmsTaskInstockLine> rmsTaskInstockLines = rmsTaskInstockLineService.selectRmsTaskInstockLineList(inStockLine);
+        return rmsTaskInstockLines.stream().noneMatch(item->item.getStatus()!=2);
+    }
+}

+ 85 - 0
mes/ktg-mes/src/main/java/com/ktg/mes/rms/util/ApiCache.java

@@ -30,12 +30,14 @@ public class ApiCache {
 
     public static final ConcurrentHashMap<String, Queue<RmsTaskPool>> liftTaskQueueMap = new ConcurrentHashMap<>();
     public static final Queue<RmsTaskPool> agvWorkQueue = new ConcurrentLinkedDeque<>();
+    public static final Queue<RmsTaskPool> railAgvWorkQueue = new ConcurrentLinkedDeque<>();
     public static final Map<String, Queue<RmsTaskPool>> rollerWorkQueue = new ConcurrentHashMap<>();
     private static final ReentrantLock lock = new ReentrantLock();
     private static final ReentrantLock topLock = new ReentrantLock();
     public static final ReentrantLock addFirstLock = new ReentrantLock();
     private static final List<RmsTaskPool> priorityList = new ArrayList<>();
     public static final List<RmsTaskPool> topAgvList = new ArrayList<>();
+    public static final List<RmsTaskPool> topRailAgvList = new ArrayList<>();
 
     @Autowired
     private RedisCache redisCache;
@@ -163,6 +165,22 @@ public class ApiCache {
         ApiCache.agvWorkQueue.offer(rmsTaskPool);
     }
 
+    public static void addRailAgvTask(RmsTaskPool rmsTaskPool){
+        if("net".equals(robotModel)){
+            return;
+        }
+        if(checkQueue(ApiCache.railAgvWorkQueue, rmsTaskPool)){
+            log.debug(rmsTaskPool.getTaskId() + " 轨道AGV任务已存在队列");
+            return;
+        }
+        if(ApiStockTask.checkRunRailAgv(rmsTaskPool)){
+            log.debug(rmsTaskPool.getTaskId() + " 任务正在执行中");
+            return;
+        }
+        log.info("增加轨道AGV队列:"+rmsTaskPool.getTaskId());
+        ApiCache.railAgvWorkQueue.offer(rmsTaskPool);
+    }
+
     public static void addRollerTask(RmsTaskPool rmsTaskPool) throws Exception {
         if("net".equals(robotModel)){
             return;
@@ -214,6 +232,15 @@ public class ApiCache {
                     opRmsTaskPoolMap.put("AGV", agvRmsTaskPoolList);
                     continue;
                 }
+                if (Long.parseLong(rmsTaskPool.getDeviceType()) == DeviceTypeEnum.RAILAGV.getValue()) {
+                    List<RmsTaskPool> railAgvRmsTaskPoolList = new ArrayList<>();
+                    if (opRmsTaskPoolMap.containsKey("RAILAGV")) {
+                        railAgvRmsTaskPoolList = opRmsTaskPoolMap.get("RAILAGV");
+                    }
+                    railAgvRmsTaskPoolList.add(rmsTaskPool);
+                    opRmsTaskPoolMap.put("RAILAGV", railAgvRmsTaskPoolList);
+                    continue;
+                }
                 if (rmsTaskPool.getTaskType().equals(TaskTypeEnum.PULL.getValue())
                         || rmsTaskPool.getTaskType().equals(TaskTypeEnum.PUSH.getValue())) {
                     List<RmsTaskPool> liftRmsTaskPoolList = new ArrayList<>();
@@ -242,6 +269,10 @@ public class ApiCache {
                 List<RmsTaskPool> agvList = opRmsTaskPoolMap.get("AGV");
                 insertFirst(agvList, agvWorkQueue);
             }
+            if (opRmsTaskPoolMap.containsKey("RAILAGV")) {
+                List<RmsTaskPool> agvList = opRmsTaskPoolMap.get("RAILAGV");
+                insertFirst(agvList, railAgvWorkQueue);
+            }
             if (opRmsTaskPoolMap.containsKey(TaskTypeEnum.ROLLER.getValue())) {
                 log.info("插入一条新对接平台任务");
                 List<RmsTaskPool> rollerList = opRmsTaskPoolMap.get(TaskTypeEnum.ROLLER.getValue());
@@ -318,6 +349,34 @@ public class ApiCache {
         }
     }
 
+    public static void setTopRailAgvTask(List<RmsTaskPool> taskPools){
+        Queue<RmsTaskPool> queue_ = new ConcurrentLinkedDeque<>();
+        List<RmsTaskPool> agvTask = new ArrayList<>();
+        boolean first = true;
+        while (!railAgvWorkQueue.isEmpty()){
+            RmsTaskPool pool = railAgvWorkQueue.peek();
+            if(pool==null)continue;
+            if(first){
+                queue_.offer(pool);
+                first = false;
+            }else{
+                boolean isTop = taskPools.stream().anyMatch(item->item.getGroupCode().equals(pool.getGroupCode()));
+                if(isTop){
+                    queue_.offer(pool);
+                }else{
+                    agvTask.add(pool);
+                }
+            }
+            railAgvWorkQueue.poll();
+        }
+        for (RmsTaskPool pool:agvTask){
+            queue_.offer(pool);
+        }
+        while (!queue_.isEmpty()){
+            ApiCache.railAgvWorkQueue.offer(queue_.poll());
+        }
+    }
+
     public static void sortLiftTaskByLift(RmsTaskPool lastPool){
         if(lastPool==null)return;
 //        log.info(lastPool.getLiftCode()+"任务排序开始");
@@ -402,6 +461,18 @@ public class ApiCache {
         }
     }
 
+    public static void setTopRailAgvTask(){
+        topLock.lock();
+        try{
+            if(!ApiCache.topRailAgvList.isEmpty()){
+                ApiCache.setTopRailAgvTask(ApiCache.topRailAgvList);
+                topRailAgvList.clear();
+            }
+        }finally {
+            topLock.unlock();
+        }
+    }
+
     public static List<RmsTaskPool> getLiftPriorityList(){
         lock.lock();
         try{
@@ -427,6 +498,20 @@ public class ApiCache {
             lock.unlock();
         }
     }
+
+    public static List<RmsTaskPool> getRailAgvPriorityList(){
+        lock.lock();
+        try{
+            List<RmsTaskPool> nList = priorityList.stream()
+                    .filter(item->item.getDeviceType().equals(DeviceTypeEnum.RAILAGV.getValue()+""))
+                    .collect(Collectors.toList());
+            priorityList.removeAll(nList);
+            return nList;
+        }finally {
+            lock.unlock();
+        }
+    }
+
     private static void printQueue(Queue<RmsTaskPool> tmp, String remark){
         StringBuilder str = new StringBuilder();
         for (RmsTaskPool p :tmp){

+ 1 - 1
mes/ktg-mes/src/main/java/com/ktg/mes/rms/util/RailHelper.java

@@ -155,7 +155,7 @@ public class RailHelper {
      * @param fromSite 入库记录
      * @param toSite 出库记录
      */
-    public String sendAgvTask(String fromSite, String toSite, Integer pickTime, String keyRoute, String taskType, String robotType, String robotId, boolean isJoin) throws Exception {
+    public String sendAgvTask(String fromSite, String toSite, Integer pickTime, String keyRoute, String taskType, String robotType, String robotId) throws Exception {
         Map<String, Object> dats = new HashMap<>();
         dats.put("taskType", taskType);
         dats.put("robotType", robotType);