|
|
@@ -1,21 +1,19 @@
|
|
|
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.DateUtils;
|
|
|
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.IRmsLiftService;
|
|
|
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.rms.util.RailAgvPlcHelper;
|
|
|
import com.ktg.mes.wm.domain.WmRmsBox;
|
|
|
import com.ktg.mes.wm.domain.WmRmsBoxItem;
|
|
|
import com.ktg.mes.wm.domain.WmStorageArea;
|
|
|
@@ -34,14 +32,15 @@ import org.springframework.transaction.support.DefaultTransactionDefinition;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Date;
|
|
|
+import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
|
|
|
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;
|
|
|
|
|
|
@@ -55,6 +54,7 @@ public class RailAgvThread extends BaseThread{
|
|
|
}
|
|
|
|
|
|
public void run(){
|
|
|
+ RailAgvPlcHelper plcHelper = null;
|
|
|
try{
|
|
|
log.info("=========收到轨道AGV任务:"+rmsTaskPool.getTaskId()+"=========");
|
|
|
rmsTaskPoolService.startGroupTask(rmsTaskPool);
|
|
|
@@ -63,56 +63,73 @@ public class RailAgvThread extends BaseThread{
|
|
|
System.out.println("=========延迟"+rmsTaskPool.getRunDelay()+"秒执行=========");
|
|
|
Thread.sleep(rmsTaskPool.getRunDelay()*1000);
|
|
|
}
|
|
|
- String robotType = DeviceTypeEnum.RAILAGV.getKey();
|
|
|
- String robotId = "";
|
|
|
- RmsTaskPool bindPool = getBindTask();
|
|
|
- if(StringUtils.isNotEmpty(bindPool.getLiftCode())){
|
|
|
- robotId = bindPool.getLiftCode();
|
|
|
+
|
|
|
+ // 获取轨道AGV的PLC连接
|
|
|
+ String agvCode = rmsTaskPool.getLiftCode();
|
|
|
+ if(StringUtils.isEmpty(agvCode)){
|
|
|
+ RmsTaskPool bindPool = getBindTask();
|
|
|
+ if(bindPool != null){
|
|
|
+ agvCode = bindPool.getLiftCode();
|
|
|
+ }
|
|
|
}
|
|
|
- if(StringUtils.isNotEmpty(rmsTaskPool.getLiftCode())){
|
|
|
- robotId = rmsTaskPool.getLiftCode();
|
|
|
+ if(StringUtils.isEmpty(agvCode)){
|
|
|
+ throw new Exception("未找到轨道AGV编号");
|
|
|
}
|
|
|
- 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任务请求失败");
|
|
|
+ IRmsLiftService rmsLiftService = SpringUtils.getBean(IRmsLiftService.class);
|
|
|
+ RmsLift rmsLift = rmsLiftService.selectRmsLiftByLiftCode(agvCode);
|
|
|
+ if(rmsLift == null || StringUtils.isEmpty(rmsLift.getLiftIp())){
|
|
|
+ throw new Exception("未找到轨道AGV设备信息:"+agvCode);
|
|
|
}
|
|
|
- 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);
|
|
|
+ plcHelper = RailAgvPlcHelper.getInstance(rmsLift.getLiftIp(), rmsLift.getLiftPort().intValue());
|
|
|
+
|
|
|
+ // 下发任务参数到PLC
|
|
|
+ Map<String, String> taskParams = new HashMap<>();
|
|
|
+ taskParams.put(RailAgvPlcHelper.sFromSite, rmsTaskPool.getFromSite());
|
|
|
+ taskParams.put(RailAgvPlcHelper.sToSite, rmsTaskPool.getToSite());
|
|
|
+ if(rmsTaskPool.getPickTime() != null){
|
|
|
+ taskParams.put(RailAgvPlcHelper.iPickTime, rmsTaskPool.getPickTime().toString());
|
|
|
+ }
|
|
|
+ taskParams.put(RailAgvPlcHelper.sKeyRoute, rmsTaskPool.getKeyRoute());
|
|
|
+ taskParams.put(RailAgvPlcHelper.iTaskType, rmsTaskPool.getTaskType());
|
|
|
+ plcHelper.setVar(taskParams);
|
|
|
+
|
|
|
+ // 启动任务
|
|
|
+ plcHelper.setVar(RailAgvPlcHelper.bTaskStart, "1", 0);
|
|
|
+ if(rmsTaskPool.getIsWait() == 0){
|
|
|
+ updateRemark(null, 1, 3, rmsTaskPool.getTaskName()+"任务已发送");
|
|
|
}else{
|
|
|
- if(rmsTaskPool.getIsWait() != 0){ //不是出入库,不滚动,判断等待用wait
|
|
|
- log.info("开始AGV等待任务完成");
|
|
|
- isRunDone = waitAgv(rmsRemoteTaskId);
|
|
|
- }
|
|
|
+ updateRemark(null, 1, 3, rmsTaskPool.getTaskName()+"任务已发送,等待中");
|
|
|
}
|
|
|
- if(!isRunDone){
|
|
|
- log.info("任务被取消,结束线程");
|
|
|
- cancleOrder();
|
|
|
- return;
|
|
|
+
|
|
|
+ // 等待AGV执行完成
|
|
|
+ boolean needWait = TaskTypeEnum.X2B_ROLLER_BACK_UP.getValue().equals(rmsTaskPool.getTaskType())
|
|
|
+ || TaskTypeEnum.X2B_ROLLER_BACK_DOWN.getValue().equals(rmsTaskPool.getTaskType())
|
|
|
+ || rmsTaskPool.getIsWait() != 0;
|
|
|
+ if(needWait){
|
|
|
+ log.info("开始AGV等待任务完成");
|
|
|
+ if(!waitAgv(plcHelper)){
|
|
|
+ log.info("任务被取消,结束线程");
|
|
|
+ cancleOrder();
|
|
|
+ return;
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
waitByTask();
|
|
|
- if(StringUtils.isNotNull(rmsRemoteTaskId)){
|
|
|
- updateOrder();
|
|
|
- updateRemark(null,2, 2, "成功");
|
|
|
- checkNextTask();
|
|
|
- }
|
|
|
+ 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);
|
|
|
+ if(plcHelper != null){
|
|
|
+ try {
|
|
|
+ plcHelper.setVar(RailAgvPlcHelper.bStop, "1", 0);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("停止轨道AGV异常", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
cancleOrder();
|
|
|
}finally {
|
|
|
this.rmsTaskPool = null;
|
|
|
@@ -137,25 +154,7 @@ public class RailAgvThread extends BaseThread{
|
|
|
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");
|
|
|
- }
|
|
|
- }
|
|
|
+ removeLineIdFromBox(wmRmsBox, lineId);
|
|
|
//搬运结束料框加入出库单信息
|
|
|
wmRmsBox.setItemOutCode(rmsTaskPool.getSourceType());
|
|
|
wmRmsBoxService.updateWmRmsBox2(wmRmsBox);
|
|
|
@@ -198,11 +197,13 @@ public class RailAgvThread extends BaseThread{
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private boolean waitAgv(String rmsRemoteTaskId) throws Exception {
|
|
|
+ private boolean waitAgv(RailAgvPlcHelper plcHelper) throws Exception {
|
|
|
boolean isStop = false;
|
|
|
long runTime = new Date().getTime();
|
|
|
+ long maxWaitMs = waitAgvTime * 1000L;
|
|
|
+ boolean timeoutNotified = false;
|
|
|
while (!isStop){
|
|
|
- AgvStatus agvStatus = checkRmsStock(rmsRemoteTaskId);
|
|
|
+ AgvStatus agvStatus = checkRmsStock(plcHelper);
|
|
|
if(agvStatus.equals(AgvStatus.CANCEL)){
|
|
|
throw new Exception("AGV异常,取消任务");
|
|
|
}
|
|
|
@@ -212,43 +213,36 @@ public class RailAgvThread extends BaseThread{
|
|
|
try {
|
|
|
RmsTaskPool pool = rmsTaskPoolService.selectRmsTaskPoolByTaskId(rmsTaskPool.getTaskId());
|
|
|
if ("4".equals(pool.getTaskStatus())) {
|
|
|
- railHelper.cancelAgvTask(rmsTaskPool.getRmsTaskId());
|
|
|
+ plcHelper.setVar(RailAgvPlcHelper.bStop, "1", 0);
|
|
|
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任务完成超时");
|
|
|
+ if(!timeoutNotified && (new Date().getTime() - runTime) > maxWaitMs){
|
|
|
+ timeoutNotified = true;
|
|
|
+ log.error("等待轨道AGV任务超时("+waitAgvTime+"秒),等待人工处理");
|
|
|
+ try {
|
|
|
+ SpringUtils.getBean(RmsWebSocketServer.class)
|
|
|
+ .sendToUI("lift", DateUtils.getTime() + " 等待轨道AGV任务"+rmsTaskPool.getTaskId()+"超时("+waitAgvTime+"秒),请人工处理");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("发送超时通知失败", e);
|
|
|
+ }
|
|
|
}
|
|
|
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();
|
|
|
+ public AgvStatus checkRmsStock(RailAgvPlcHelper plcHelper) throws Exception {
|
|
|
+ String taskStatus = plcHelper.getValue(RailAgvPlcHelper.iTaskStatus, 0);
|
|
|
+ if("2".equals(taskStatus)){
|
|
|
+ return AgvStatus.DONE;
|
|
|
}
|
|
|
-// 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);
|
|
|
+ if("3".equals(taskStatus)){
|
|
|
+ return AgvStatus.CANCEL;
|
|
|
}
|
|
|
+ return AgvStatus.RUN;
|
|
|
}
|
|
|
|
|
|
public void updateRemark(String rmsTaskId, Integer status, int step, String remark) throws Exception {
|
|
|
@@ -270,9 +264,22 @@ public class RailAgvThread extends BaseThread{
|
|
|
if(isWait == 3 && StringUtils.isNotEmpty(waitTaskId)){
|
|
|
String[] taskIds = waitTaskId.split(",");
|
|
|
boolean isUpdate = false;
|
|
|
+ long waitStart = System.currentTimeMillis();
|
|
|
+ long maxWaitMs = 600000;
|
|
|
+ boolean timeoutNotified = false;
|
|
|
for(String taskId:taskIds){
|
|
|
boolean isStop = false;
|
|
|
while (!isStop){
|
|
|
+ if(!timeoutNotified && System.currentTimeMillis() - waitStart > maxWaitMs){
|
|
|
+ timeoutNotified = true;
|
|
|
+ log.error("等待任务"+taskId+"超时("+(maxWaitMs/1000)+"秒),等待人工处理");
|
|
|
+ try {
|
|
|
+ SpringUtils.getBean(RmsWebSocketServer.class)
|
|
|
+ .sendToUI("lift", DateUtils.getTime() + " 等待任务"+taskId+"超时("+(maxWaitMs/1000)+"秒),请人工处理");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("发送超时通知失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
RmsTaskPool p = new RmsTaskPool();
|
|
|
p.setGroupCode(rmsTaskPool.getGroupCode());
|
|
|
p.setFlowLineId(Long.parseLong(taskId));
|
|
|
@@ -299,6 +306,29 @@ public class RailAgvThread extends BaseThread{
|
|
|
return rmsTaskPool;
|
|
|
}
|
|
|
|
|
|
+ private void removeLineIdFromBox(WmRmsBox wmRmsBox, Long lineId) {
|
|
|
+ if(lineId == null) return;
|
|
|
+ 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");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
public void cancleOrder(){
|
|
|
Long deviceType = Long.parseLong(rmsTaskPool.getDeviceType());
|
|
|
if(deviceType.equals(DeviceTypeEnum.ROLLERAGV.getValue())){
|
|
|
@@ -311,25 +341,7 @@ public class RailAgvThread extends BaseThread{
|
|
|
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");
|
|
|
- }
|
|
|
- }
|
|
|
+ removeLineIdFromBox(wmRmsBox, lineId);
|
|
|
wmRmsBoxService.updateWmRmsBox2(wmRmsBox);
|
|
|
}
|
|
|
}
|