From 702549f5d846ae76cc005c56d03fd774a3caa341 Mon Sep 17 00:00:00 2001
From: L <L@132>
Date: 星期四, 23 四月 2026 14:23:01 +0800
Subject: [PATCH] *
---
src/main/java/com/zy/core/thread/RgvThread.java | 607 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 551 insertions(+), 56 deletions(-)
diff --git a/src/main/java/com/zy/core/thread/RgvThread.java b/src/main/java/com/zy/core/thread/RgvThread.java
index ce27b3f..e923ce4 100644
--- a/src/main/java/com/zy/core/thread/RgvThread.java
+++ b/src/main/java/com/zy/core/thread/RgvThread.java
@@ -5,7 +5,7 @@
import HslCommunication.Profinet.Siemens.SiemensPLCS;
import HslCommunication.Profinet.Siemens.SiemensS7Net;
import com.alibaba.fastjson.JSON;
-import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.core.common.DateUtils;
import com.core.common.SpringUtils;
import com.zy.asrs.entity.BasCircularShuttle;
@@ -13,6 +13,7 @@
import com.zy.asrs.entity.BasRgvErrLog;
import com.zy.asrs.entity.BasRgvOpt;
import com.zy.asrs.service.BasCircularShuttleService;
+import com.zy.asrs.service.BasDevpPositionService;
import com.zy.asrs.service.BasRgvErrLogService;
import com.zy.asrs.service.BasRgvOptService;
import com.zy.asrs.service.BasRgvService;
@@ -20,6 +21,7 @@
import com.zy.core.ThreadHandler;
import com.zy.core.cache.MessageQueue;
import com.zy.core.cache.OutputQueue;
+import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.RgvModeType;
import com.zy.core.enums.RgvTaskModeType;
import com.zy.core.enums.SlaveType;
@@ -31,10 +33,8 @@
import lombok.extern.slf4j.Slf4j;
import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
/**
* RGV绾跨▼
@@ -57,6 +57,34 @@
private boolean resetFlag2 = false;
private boolean connectRgv = false;
private boolean alarmChangeSign = false;
+ private boolean csSign = true;//娴嬭瘯鏍囪
+
+ /** 妯℃嫙绉诲姩閫熷害锛歅LC杞ㄩ亾鍗曚綅/tick锛�200ms锛夛紝5000鍗曚綅鈮�2.5m/s */
+ private static final long SIM_CS_MOVE_STEP = 5000;
+ /** 鐜舰杞ㄩ亾鎬婚暱锛圥LC杞ㄩ亾鍗曚綅锛� */
+ private static final long PERIMETER = 1737000;
+ /** 閬胯瀹夊叏璺濈 */
+ private static final long AVOIDANCE_DISTANCE = 50000;
+
+ /** 妯℃嫙浠诲姟闃舵 */
+ private enum SimPhase { IDLE, MOVING, WAITING_AT_SOURCE }
+
+ /** 妯℃嫙浠诲姟鏁版嵁 */
+ @Data
+ static class SimTask {
+ int taskNo;
+ short sourceSta;
+ short destSta;
+ short mode; // 浠诲姟妯″紡锛�1=鍙栬揣 2=鏀捐揣 3=鍙栨斁璐� 5=婕父
+ SimPhase phase;
+ long targetPos; // 鐩爣杞ㄩ亾浣嶇疆
+ long startPos; // 璧峰杞ㄩ亾浣嶇疆
+ long destPos; // 鏀捐揣绔欎綅缃紙浠呭彇鏀捐揣浠诲姟浣跨敤锛�
+ long waitStartTime; // 鍒拌揪鍙栬揣绔欏悗鐨勭瓑寰呭紑濮嬫椂闂�
+ }
+
+ /** 鍏ㄥ眬妯℃嫙浠诲姟琛細rgvNo 鈫� SimTask锛岀嚎绋嬪畨鍏� */
+ static final Map<Integer, SimTask> simTasks = new ConcurrentHashMap<>();
public RgvThread(RgvSlave slave) {
this.slave = slave;
@@ -65,7 +93,11 @@
@Override
@SuppressWarnings("InfiniteLoopStatement")
public void run() {
- connectRgv = this.connect();
+ if (csSign) {
+ connectRgv = true; // 妯℃嫙妯″紡璺宠繃PLC杩炴帴
+ } else {
+ connectRgv = this.connect();
+ }
// 鍚姩绾跨▼鑷姩閲嶈繛
new Thread(this::rgvConnect).start();
@@ -75,6 +107,11 @@
// 鍚姩浠诲姟涓嬪彂绾跨▼
new Thread(this::taskIssued).start();
+
+ // 妯℃嫙妯″紡锛氬惎鍔ㄦā鎷熻繍琛岀嚎绋�
+ if (csSign) {
+ new Thread(this::simThreadRun).start();
+ }
}
@@ -97,47 +134,89 @@
if (task != null) {
step = task.getStep();
}
- switch (step) {
- //婕父浠诲姟瀹屾垚淇″彿
- case 1:
+ if (csSign) {
+ // ===== 妯℃嫙妯″紡锛氫笉鍐橮LC锛岀敤妯℃嫙鏂规硶鏇夸唬 =====
+ switch (step) {
+ case 1:
+ taskCompleteCS();
+ break;
+ case 2:
+ RgvCommand command2 = (RgvCommand) task.getData();
+ rgvOpt(command2);
+ writeCS(command2);
+ rgvProtocol.setTaskNo1(command2.getTaskNo1());
+ break;
+ case 3:
+ RgvCommand command = (RgvCommand) task.getData();
+ if (null == command) {
+ command = new RgvCommand();
+ }
+ command.setRgvNo(slave.getId());
+ command.setTaskNo1((short) 0);
+ command.setAckFinish1((short) 1);
+ command.setTaskMode1(RgvTaskModeType.NONE);
+ command.setSourceStaNo1((short)0);
+ command.setDestinationStaNo1((short)0);
+ rgvOpt(command);
+ write3CS(command);
+ break;
+ case 4:
+ RgvCommand command4 = (RgvCommand) task.getData();
+ rgvOpt(command4);
+ write4CS(command4);
+ break;
+ case 5:
+ Long aLong = (Long) task.getData();
+ rgvOpt(aLong);
+ write5CS(aLong);
+ break;
+ default:
+ break;
+ }
+ } else {
+ // ===== 鐪熷疄妯″紡锛氬啓PLC =====
+ switch (step) {
+ //婕父浠诲姟瀹屾垚淇″彿
+ case 1:
// readStatus();
- taskComplete();
- break;
- //宸ヤ綅1鍐欏叆鏁版嵁
- case 2:
- RgvCommand command2 = (RgvCommand) task.getData();
- rgvOpt(command2);
- write(command2);
- break;
- // 澶嶄綅
- case 3:
- RgvCommand command = (RgvCommand) task.getData();
- if (null == command) {
- command = new RgvCommand();
- }
- command.setRgvNo(slave.getId()); // RGV缂栧彿
- command.setTaskNo1((short) 0); // 宸ヤ綔鍙�
- command.setAckFinish1((short) 1); // 浠诲姟瀹屾垚纭浣�
- command.setTaskMode1(RgvTaskModeType.NONE); // 浠诲姟妯″紡
- command.setSourceStaNo1((short)0); // 婧愮珯
- command.setDestinationStaNo1((short)0); // 鐩爣绔�
- rgvOpt(command);
- write3(command);
- break;
- //宸ヤ綅1鍐欏叆鍙栨秷鏁版嵁
- case 4:
- RgvCommand command4 = (RgvCommand) task.getData();
- rgvOpt(command4);
- write4(command4);
- break;
- // 婕父
- case 5:
- Long aLong = (Long) task.getData();
- rgvOpt(aLong);
- write5(aLong);
- break;
- default:
- break;
+ taskComplete();
+ break;
+ //宸ヤ綅1鍐欏叆鏁版嵁
+ case 2:
+ RgvCommand command2 = (RgvCommand) task.getData();
+ rgvOpt(command2);
+ write(command2);
+ break;
+ // 澶嶄綅
+ case 3:
+ RgvCommand command = (RgvCommand) task.getData();
+ if (null == command) {
+ command = new RgvCommand();
+ }
+ command.setRgvNo(slave.getId()); // RGV缂栧彿
+ command.setTaskNo1((short) 0); // 宸ヤ綔鍙�
+ command.setAckFinish1((short) 1); // 浠诲姟瀹屾垚纭浣�
+ command.setTaskMode1(RgvTaskModeType.NONE); // 浠诲姟妯″紡
+ command.setSourceStaNo1((short)0); // 婧愮珯
+ command.setDestinationStaNo1((short)0); // 鐩爣绔�
+ rgvOpt(command);
+ write3(command);
+ break;
+ //宸ヤ綅1鍐欏叆鍙栨秷鏁版嵁
+ case 4:
+ RgvCommand command4 = (RgvCommand) task.getData();
+ rgvOpt(command4);
+ write4(command4);
+ break;
+ // 婕父
+ case 5:
+ Long aLong = (Long) task.getData();
+ rgvOpt(aLong);
+ write5(aLong);
+ break;
+ default:
+ break;
+ }
}
Thread.sleep(50);
} catch (Exception e) {
@@ -156,7 +235,7 @@
try {
// 鏍规嵁瀹炴椂淇℃伅鏇存柊鏁版嵁搴�
BasCircularShuttleService basCircularShuttleService = SpringUtils.getBean(BasCircularShuttleService.class);
- BasCircularShuttle basCircularShuttle = basCircularShuttleService.selectOne(new EntityWrapper<BasCircularShuttle>().eq("rgv_no", slave.getId()));
+ BasCircularShuttle basCircularShuttle = basCircularShuttleService.getOne(new QueryWrapper<BasCircularShuttle>().eq("rgv_no", slave.getId()));
if (basCircularShuttle.getStatus() != 0){
continue;
}
@@ -192,8 +271,8 @@
continue;
}
Thread.sleep(40);
- readStatus();
-
+// readStatus();
+ initRgv();
} catch (Exception e) {
log.error("RGV璇荤嚎绋嬪紓甯�"+e.getMessage());
@@ -210,6 +289,17 @@
* 鍒濆鍖朢GV鐘舵��
*/
private void initRgv() {
+ if (csSign){
+ initRgvCS();
+ } else {
+ initRgvT();
+ }
+ }
+
+ /**
+ * 鍒濆鍖朢GV鐘舵��
+ */
+ private void initRgvT() {
if (null == rgvProtocol) {
rgvProtocol = new RgvProtocol();
}
@@ -229,6 +319,51 @@
rgvProtocol.setxDistance((short) 0);
rgvProtocol.setxDuration((short) 0);
log.error("杩炴帴涓柇锛歊GV鍙凤細"+slave.getId());
+ try {
+ // 鏍规嵁瀹炴椂淇℃伅鏇存柊鏁版嵁搴�
+ BasRgvService basRgvService = SpringUtils.getBean(BasRgvService.class);
+ BasRgv basRgv = new BasRgv();
+ basRgv.setRgvNo(slave.getId());
+ basRgv.setRgvSts((int)rgvProtocol.getMode());
+ basRgv.setLoaded2(rgvProtocol.getLoaded2().intValue());
+ if (!basRgvService.updateById(rgvProtocol.toSqlModel(basRgv))){
+ log.error("RGV plc鏁版嵁搴撴洿鏂板け璐� ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
+ }
+ } catch (Exception ignore) {
+ }
+ }
+
+ /**
+ * 鍒濆鍖朢GV鐘舵��
+ */
+ private void initRgvCS() {
+ if (null == rgvProtocol) {
+ rgvProtocol = new RgvProtocol();
+ rgvProtocol.setRgvNo(slave.getId());
+ rgvProtocol.setMode((short) 3);
+ rgvProtocol.setStatus((short)0);
+ rgvProtocol.setTaskNo1((short)0);
+ rgvProtocol.setStatus1((short)0);
+ rgvProtocol.setLoaded1((short)0);
+ rgvProtocol.setWalkPos((short)0);
+ if (rgvProtocol.getRgvPos()==null || rgvProtocol.getRgvPos()==0){
+ rgvProtocol.setRgvPos(1L+rgvProtocol.getRgvNo()*100000);
+ }
+// rgvProtocol.setRgvPos(rgvProtocol.getRgvPos()+1000);
+ rgvProtocol.setRgvPos(rgvProtocol.getRgvPos());
+ if (rgvProtocol.getRgvPos()>0){
+ rgvProtocol.setRgvPos((long)rgvProtocol.getRgvPos());
+ rgvProtocol.setRgvPosInt(rgvProtocol.getRgvPos().intValue());
+ }
+ rgvProtocol.setTaskNo2((short)0);
+ rgvProtocol.setStatus2((short)-1);
+ rgvProtocol.setLoaded2((short)0);
+ rgvProtocol.setAlarm((short)0);
+ rgvProtocol.setxSpeed((short) 0);
+ rgvProtocol.setxDistance((short) 0);
+ rgvProtocol.setxDuration((short) 0);
+ }
+// log.error("杩炴帴涓柇锛歊GV鍙凤細"+slave.getId());
try {
// 鏍规嵁瀹炴椂淇℃伅鏇存柊鏁版嵁搴�
BasRgvService basRgvService = SpringUtils.getBean(BasRgvService.class);
@@ -323,7 +458,7 @@
if (!alarmChangeSign && !alarmList.isEmpty()){
BasRgvErrLogService basRgvErrLogService = SpringUtils.getBean(BasRgvErrLogService.class);
BasRgvErrLog basRgvErrLog = new BasRgvErrLog(rgvProtocol.getAlarmList(), rgvProtocol.getTaskNo1(), rgvProtocol.getRgvNo());
- basRgvErrLogService.insert(basRgvErrLog);
+ basRgvErrLogService.save(basRgvErrLog);
}
} catch (Exception e){
log.error("RGV寮傚父淇℃伅淇濆瓨澶辫触锛侊紒");
@@ -354,7 +489,7 @@
BasRgvOptService basRgvOptService = SpringUtils.getBean(BasRgvOptService.class);
BasRgvOpt basRgvOpt = new BasRgvOpt(rgvProtocol.getTaskNo1().intValue(), rgvProtocol.getRgvNo(), rgvProtocol.getRgvPosInt(), command);
log.info(rgvProtocol.getRgvNo()+"鍙峰皬杞﹀啓鍏ュ懡浠ゅ畾浣嶅�硷細"+rgvProtocol.getRgvPosInt());
- basRgvOptService.insert(basRgvOpt);
+ basRgvOptService.save(basRgvOpt);
}catch (Exception e){
log.error("RGV鍐欏叆鍛戒护淇濆瓨澶辫触锛侊紒");
}
@@ -363,7 +498,7 @@
try{
BasRgvOptService basRgvOptService = SpringUtils.getBean(BasRgvOptService.class);
BasRgvOpt basRgvOpt = new BasRgvOpt(rgvProtocol.getTaskNo1().intValue(), rgvProtocol.getRgvNo(), rgvProtocol.getRgvPosI(), command);
- basRgvOptService.insert(basRgvOpt);
+ basRgvOptService.save(basRgvOpt);
}catch (Exception e){
log.error("RGV鍐欏叆鍛戒护淇濆瓨澶辫触锛侊紒");
}
@@ -415,7 +550,7 @@
new Date(),
null
);
- bean.insert(basRgvOpt);
+ bean.save(basRgvOpt);
} catch (Exception ignore) {}
if (result != null && result.IsSuccess) {
@@ -477,7 +612,7 @@
new Date(),
null
);
- bean.insert(basRgvOpt);
+ bean.save(basRgvOpt);
} catch (Exception ignore) {}
if (result != null && result.IsSuccess) {
@@ -562,7 +697,7 @@
new Date(),
null
);
- bean.insert(basRgvOpt);
+ bean.save(basRgvOpt);
} catch (Exception ignore) {}
if (result != null && result.IsSuccess) {
@@ -580,7 +715,367 @@
@Override
public void close() {
- siemensNet.ConnectClose();
+ if (siemensNet != null) {
+ siemensNet.ConnectClose();
+ }
+ }
+
+ // ==================== 妯℃嫙妯″紡鏂规硶 ====================
+
+ /**
+ * 妯℃嫙瀹屾垚纭锛坰tep=1锛夛細妯℃嫙妯″紡鏃犻渶璇籔LC
+ */
+ private void taskCompleteCS() {
+ // 妯℃嫙妯″紡涓嬫棤PLC锛岃烦杩�
+ }
+
+ /**
+ * 妯℃嫙鍙栨斁璐т笅鍙戯紙step=2锛夛細璁板綍鍒皊imTask锛屽惎鍔ㄦā鎷熺Щ鍔�
+ * 鍙栨斁璐�(mode=3): 绗竴闃舵鍘诲彇璐х珯锛屽埌杈惧悗绛夊緟5绉掞紝鍐嶅幓鏀捐揣绔�
+ */
+ private void writeCS(RgvCommand command) {
+ if (command == null) return;
+ SimTask st = new SimTask();
+ st.setTaskNo(command.getTaskNo1());
+ st.setSourceSta(command.getSourceStaNo1());
+ st.setDestSta(command.getDestinationStaNo1());
+ st.setMode(command.getTaskMode1());
+ st.setPhase(SimPhase.MOVING);
+ st.setStartPos(rgvProtocol.getRgvPos() != null ? rgvProtocol.getRgvPos() : 0L);
+
+ if (command.getTaskMode1().intValue() == RgvTaskModeType.FETCH_PUT.id) {
+ // 鍙栨斁璐э細鍏堝幓鍙栬揣绔欙紝璁颁笅鏀捐揣绔欎綅缃�
+ st.setTargetPos(getStationPosition(command.getSourceStaNo1()));
+ st.setDestPos(getStationPosition(command.getDestinationStaNo1()));
+ } else {
+ // 鍏朵粬妯″紡锛氱洿鎺ュ幓鐩爣绔�
+ st.setTargetPos(getStationPosition(command.getDestinationStaNo1()));
+ st.setDestPos(0L);
+ }
+
+ simTasks.put(slave.getId(), st);
+
+ log.info("[妯℃嫙] RGV{} 鍙栨斁璐т换鍔℃帴鏀�: taskNo={} source={} dest={} 鐩爣浣嶇疆={}",
+ slave.getId(), command.getTaskNo1(), command.getSourceStaNo1(),
+ command.getDestinationStaNo1(), st.getTargetPos());
+ OutputQueue.RGV.offer(MessageFormat.format("銆恵0}銆慬妯℃嫙][id:{1}] 鍙栨斁璐т换鍔℃帴鏀�: source={2} dest={3} target={4}",
+ DateUtils.convert(new Date()), slave.getId(),
+ command.getSourceStaNo1(), command.getDestinationStaNo1(), st.getTargetPos()));
+ }
+
+ /**
+ * 妯℃嫙澶嶄綅锛坰tep=3锛夛細娓呴櫎妯℃嫙浠诲姟
+ */
+ private void write3CS(RgvCommand command) {
+ simTasks.remove(slave.getId());
+ rgvProtocol.setTaskNo1((short) 0);
+ rgvProtocol.setStatus((short) 0);
+ log.info("[妯℃嫙] RGV{} 澶嶄綅瀹屾垚", slave.getId());
+ OutputQueue.RGV.offer(MessageFormat.format("銆恵0}銆慬妯℃嫙][id:{1}] 澶嶄綅瀹屾垚",
+ DateUtils.convert(new Date()), slave.getId()));
+ }
+
+ /**
+ * 妯℃嫙鍙栨秷锛坰tep=4锛夛細娓呴櫎妯℃嫙浠诲姟
+ */
+ private void write4CS(RgvCommand command) {
+ simTasks.remove(slave.getId());
+ log.info("[妯℃嫙] RGV{} 浠诲姟鍙栨秷: taskNo={}", slave.getId(), command.getTaskNo1());
+ OutputQueue.RGV.offer(MessageFormat.format("銆恵0}銆慬妯℃嫙][id:{1}] 浠诲姟鍙栨秷: taskNo={2}",
+ DateUtils.convert(new Date()), slave.getId(), command.getTaskNo1()));
+ }
+
+ /**
+ * 妯℃嫙婕父涓嬪彂锛坰tep=5锛夛細璁板綍鍒皊imTask锛屽惎鍔ㄦā鎷熺Щ鍔�
+ */
+ private void write5CS(Long destination) {
+ SimTask st = new SimTask();
+ st.setMode((short) 5);
+ st.setPhase(SimPhase.MOVING);
+ st.setTargetPos(destination);
+ st.setStartPos(rgvProtocol.getRgvPos() != null ? rgvProtocol.getRgvPos() : 0L);
+ simTasks.put(slave.getId(), st);
+
+ log.info("[妯℃嫙] RGV{} 婕父浠诲姟鎺ユ敹: 鐩爣浣嶇疆={}", slave.getId(), destination);
+ OutputQueue.RGV.offer(MessageFormat.format("銆恵0}銆慬妯℃嫙][id:{1}] 婕父浠诲姟鎺ユ敹: 鐩爣={2}",
+ DateUtils.convert(new Date()), slave.getId(), destination));
+ }
+
+ // ==================== 妯℃嫙杩愯绾跨▼ ====================
+
+ /**
+ * 妯℃嫙杩愯绾跨▼锛氭瘡200ms鏇存柊鏈溅浣嶇疆 + 妫�娴嬮伩璁╋紙鍚勭嚎绋嬪彧澶勭悊鑷繁鐨剆imTask锛�
+ */
+ private void simThreadRun() {
+ log.info("[妯℃嫙] RGV{} 妯℃嫙杩愯绾跨▼鍚姩", slave.getId());
+ int tick = 0;
+ int myId = slave.getId();
+ while (true) {
+ try {
+ Thread.sleep(200);
+ tick++;
+
+ SimTask st = simTasks.get(myId);
+ if (st == null || st.getPhase() == SimPhase.IDLE) continue;
+
+ if (rgvProtocol == null || rgvProtocol.getRgvPos() == null) continue;
+ long current = rgvProtocol.getRgvPos();
+ long target = st.getTargetPos();
+ double dist = forwardDistance(current, target);
+
+ // 鍒拌揪鍙栬揣绔欙細绛夊緟5绉掑悗鍓嶅線鏀捐揣绔�
+ if (st.getPhase() == SimPhase.WAITING_AT_SOURCE) {
+ long waited = System.currentTimeMillis() - st.getWaitStartTime();
+ if (waited >= 5000) {
+ st.setTargetPos(st.getDestPos());
+ st.setStartPos(current);
+ st.setPhase(SimPhase.MOVING);
+ log.info("[妯℃嫙] RGV{} 绛夊緟{}ms缁撴潫锛屽紑濮嬪墠寰�鏀捐揣绔�: pos={}", myId, waited, st.getDestPos());
+ OutputQueue.RGV.offer(MessageFormat.format("銆恵0}銆慬妯℃嫙][id:{1}] 绛夊緟缁撴潫锛屽墠寰�鏀捐揣绔�: {2}",
+ DateUtils.convert(new Date()), myId, st.getDestPos()));
+ }
+ continue;
+ }
+
+ if (dist <= SIM_CS_MOVE_STEP) {
+ // 鍒拌揪鐩爣
+ rgvProtocol.setRgvPos(target);
+ rgvProtocol.setRgvPosInt((int) target);
+
+ if (st.getMode() == RgvTaskModeType.FETCH_PUT.id.shortValue() && st.getDestPos() != 0L && target != st.getDestPos()) {
+ // 闃舵1锛氬埌杈惧彇璐х珯锛岃繘鍏ョ瓑寰�
+ rgvProtocol.setStatus((short) 2); // 杩涚珯杩愯涓�
+ st.setPhase(SimPhase.WAITING_AT_SOURCE);
+ st.setWaitStartTime(System.currentTimeMillis());
+
+ log.info("[妯℃嫙] RGV{} 鍒拌揪鍙栬揣绔�: pos={}锛岀瓑寰�5绉掑悗鍓嶅線鏀捐揣绔�", myId, target);
+ OutputQueue.RGV.offer(MessageFormat.format("銆恵0}銆慬妯℃嫙][id:{1}] 鍒拌揪鍙栬揣绔�: {2}锛岀瓑寰�5绉�",
+ DateUtils.convert(new Date()), myId, target));
+ } else {
+ // 闃舵2鍒拌揪鏀捐揣绔� / 婕父鍒拌揪 鈫� 鐢宠瀹屾垚浠诲姟
+ rgvProtocol.setStatus((short) 100); // WAITING
+ simTasks.remove(myId);
+
+ log.info("[妯℃嫙] RGV{} 鍒拌揪鏀捐揣绔�: pos={}锛岀姸鎬佸彉涓虹敵璇峰畬鎴�(WAITING)", myId, target);
+ OutputQueue.RGV.offer(MessageFormat.format("銆恵0}銆慬妯℃嫙][id:{1}] 鍒拌揪鏀捐揣绔�: {2}锛岀敵璇峰畬鎴愪换鍔�",
+ DateUtils.convert(new Date()), myId, target));
+ }
+
+ try {
+ BasRgvService basRgvService = SpringUtils.getBean(BasRgvService.class);
+ basRgvService.updateById(rgvProtocol.toSqlModel(new BasRgv()));
+ } catch (Exception ignore) {}
+ } else {
+ // 鍓嶈繘锛堝噺閫熼�昏緫锛氬墠鏂规湁杞﹀垯闄嶄綆姝ラ暱锛屼笉閲嶅悎涓嶈秴杩囷級
+ long step = calcAdjustedStep(myId, current);
+ long newPos = (current + step) % PERIMETER;
+ rgvProtocol.setRgvPos(newPos);
+ rgvProtocol.setRgvPosInt((int) newPos);
+ rgvProtocol.setStatus((short) 11); // ROAM
+
+ if (tick % 5 == 0) {
+ log.info("[妯℃嫙] RGV{} 绉诲姩涓�: {} 鈫� {} (璺濈洰鏍噞}, 姝ラ暱={})",
+ myId, current, newPos, (long) dist, step);
+ }
+
+ try {
+ BasRgvService basRgvService = SpringUtils.getBean(BasRgvService.class);
+ basRgvService.updateById(rgvProtocol.toSqlModel(new BasRgv()));
+ } catch (Exception ignore) {}
+
+ // 妫�娴嬮伩璁╋細鍙鏌ユ湰杞﹀墠鏂规槸鍚︽湁闃绘尅
+ checkAndAvoidBlocker(myId, target);
+ }
+
+ } catch (Exception e) {
+ log.error("[妯℃嫙] RGV{} 妯℃嫙绾跨▼寮傚父: {}", slave.getId(), e.getMessage());
+ }
+ }
+ }
+
+ /**
+ * 妫�娴嬪墠鏂归樆鎸″苟閫掓帹閬胯
+ * @param myRgvNo 褰撳墠灏忚溅缂栧彿
+ * @param myTarget 褰撳墠灏忚溅鐨勭洰鏍囦綅缃�
+ */
+ private void checkAndAvoidBlocker(int myRgvNo, long myTarget) {
+ RgvThread myThread = getRgvThread(myRgvNo);
+ if (myThread == null || myThread.getRgvProtocol() == null) return;
+ long myPos = myThread.getRgvProtocol().getRgvPos();
+ if (myPos == 0) return;
+
+ double distToTarget = forwardDistance(myPos, myTarget);
+ if (distToTarget <= 0) return;
+
+ try {
+ BasCircularShuttleService shuttleService = SpringUtils.getBean(BasCircularShuttleService.class);
+ List<BasCircularShuttle> shuttles = shuttleService.list(
+ new QueryWrapper<BasCircularShuttle>().orderByAsc("rgv_id"));
+ if (shuttles == null) return;
+
+ // 鍙壘绂昏嚜宸辨渶杩戠殑鍓嶈溅锛堝湪鑷繁涓庣洰鏍囦箣闂达級
+ int nearestRgvNo = -1;
+ double nearestDist = Double.MAX_VALUE;
+
+ for (BasCircularShuttle shuttle : shuttles) {
+ int otherNo = shuttle.getRgvNo();
+ if (otherNo == myRgvNo) continue;
+ if (!isIdleForAvoidance(otherNo)) continue;
+
+ RgvThread otherThread = getRgvThread(otherNo);
+ if (otherThread == null || otherThread.getRgvProtocol() == null) continue;
+ long otherPos = otherThread.getRgvProtocol().getRgvPos();
+ if (otherPos == 0) continue;
+
+ double fwdDist = forwardDistance(myPos, otherPos);
+ // 瀵规柟鍦ㄥ墠鏂� 涓� 鍦ㄧ洰鏍囩偣涔嬪墠 鈫� 闃绘尅
+ if (fwdDist > 0 && fwdDist < distToTarget) {
+ if (fwdDist < nearestDist) {
+ nearestDist = fwdDist;
+ nearestRgvNo = otherNo;
+ }
+ }
+ }
+
+ if (nearestRgvNo > 0) {
+ long avoidDest = forwardAvoidDest(myTarget);
+ issueAvoidanceRecursive(nearestRgvNo, avoidDest);
+ }
+ } catch (Exception ignore) {}
+ }
+
+ /**
+ * 鍒ゆ柇RGV鏄惁绌洪棽鍙敤浜庨伩璁�
+ */
+ private boolean isIdleForAvoidance(int rgvNo) {
+ SimTask otherSim = simTasks.get(rgvNo);
+ if (otherSim != null && otherSim.getPhase() == SimPhase.MOVING) return false;
+
+ RgvThread otherThread = getRgvThread(rgvNo);
+ if (otherThread == null) return false;
+ RgvProtocol protocol = otherThread.getRgvProtocol();
+ if (protocol == null) return false;
+
+ int st = protocol.getStatus() != null ? protocol.getStatus() : -1;
+ return (st == 0 || st == 11) && protocol.getTaskNo1() == 0;
+ }
+
+ /**
+ * 涓嬪彂閬胯锛氱粰rgvNo鍐欏叆閬胯simTask鑷砤voidDest
+ * 璇GV鐨勭嚎绋嬩細鍦ㄤ笅涓�tick鑷妫�娴嬮伩璁╄矾寰勪笂鐨勯樆鎸�
+ */
+ private void issueAvoidanceRecursive(int rgvNo, long avoidDest) {
+ MessageQueue.offer(SlaveType.Rgv, rgvNo, new Task(5, avoidDest));
+// RgvThread otherThread = getRgvThread(rgvNo);
+// if (otherThread == null || otherThread.getRgvProtocol() == null) return;
+// long currentPos = otherThread.getRgvProtocol().getRgvPos();
+//
+// // 鍐欏叆simTask锛堣鐩栧凡鏈夌殑WAITING_AT_SOURCE鎴朚OVING浠诲姟锛�
+// SimTask st = new SimTask();
+// st.setMode((short) 5);
+// st.setPhase(SimPhase.MOVING);
+// st.setTargetPos(avoidDest);
+// st.setStartPos(currentPos);
+// simTasks.put(rgvNo, st);
+//
+// log.info("[妯℃嫙閬胯] RGV{} 鍓嶆柟RGV{}闃绘尅锛岄伩璁╄嚦: {}",
+// slave.getId(), rgvNo, avoidDest);
+// OutputQueue.RGV.offer(MessageFormat.format(
+// "銆恵0}銆慬妯℃嫙閬胯] RGV{1} 鍓嶆柟RGV{2}闃绘尅, 閬胯鑷�: {3}",
+// DateUtils.convert(new Date()), slave.getId(), rgvNo, avoidDest));
+ }
+
+ /**
+ * 璁$畻鐩爣鐐瑰墠鏂�10000澶勭殑閬胯浣嶇疆
+ */
+ private long forwardAvoidDest(long target) {
+ long dest = target + 100000;
+ if (dest > PERIMETER) dest -= PERIMETER;
+ return dest;
+ }
+
+ /** 鍓嶈溅璺熼殢璺濈锛氳繘鍏ユ鑼冨洿寮�濮嬪噺閫� */
+ private static final long FOLLOW_DISTANCE = 20000;
+ /** 鏈�灏忓畨鍏ㄩ棿璺濓細涓嶈兘姣旇繖鏇磋繎 */
+ private static final long MIN_GAP = 3000;
+
+ /**
+ * 鏍规嵁鍓嶆柟杞﹁締璺濈璁$畻鏈瀹為檯姝ラ暱
+ * 鍓嶆柟鏃犺溅 鈫� 鍏ㄩ�燂紱鏈夎溅 鈫� 绾挎�у噺閫燂紱璐寸揣 鈫� 鍋滄
+ */
+ private long calcAdjustedStep(int myId, long myPos) {
+ long aheadDist = distanceToNearestAhead(myId, myPos);
+ if (aheadDist < 0) return SIM_CS_MOVE_STEP; // 鍓嶆柟鏃犺溅锛屽叏閫�
+
+ long gap = aheadDist - MIN_GAP;
+ if (gap <= 0) return 0; // 宸插埌鏈�灏忛棿璺濓紝鍋滄
+ return Math.min(SIM_CS_MOVE_STEP, gap);
+ }
+
+ /**
+ * 鏌ユ壘姝e墠鏂规渶杩戜竴杈嗚溅鐨勬鍚戣窛绂伙紝鏃犺溅杩斿洖-1
+ * 鍙叧娉ㄦ湁浠诲姟鎴栨鍦ㄧЩ鍔ㄧ殑杞︼紝绌洪棽闈欐鐨勮溅鐢遍伩璁╅�昏緫澶勭悊
+ */
+ private long distanceToNearestAhead(int myId, long myPos) {
+ long best = -1;
+ try {
+ BasCircularShuttleService shuttleService = SpringUtils.getBean(BasCircularShuttleService.class);
+ List<BasCircularShuttle> shuttles = shuttleService.list(
+ new QueryWrapper<BasCircularShuttle>().orderByAsc("rgv_id"));
+ if (shuttles == null) return -1;
+
+ for (BasCircularShuttle shuttle : shuttles) {
+ int otherId = shuttle.getRgvNo();
+ if (otherId == myId) continue;
+
+ SimTask otherTask = simTasks.get(otherId);
+ // 鍙叧娉ㄦ湁浠诲姟鐨勮溅锛圡OVING / WAITING_AT_SOURCE锛�
+ if (otherTask == null || otherTask.getPhase() == SimPhase.IDLE) continue;
+
+ RgvThread otherThread = getRgvThread(otherId);
+ if (otherThread == null || otherThread.getRgvProtocol() == null) continue;
+ Long otherPos = otherThread.getRgvProtocol().getRgvPos();
+ if (otherPos == null || otherPos == 0) continue;
+
+ double fwd = forwardDistance(myPos, otherPos);
+ if (fwd > 0 && fwd <= FOLLOW_DISTANCE && (best < 0 || fwd < best)) {
+ best = (long) fwd;
+ }
+ }
+ } catch (Exception ignore) {}
+ return best;
+ }
+
+ /**
+ * 璁$畻鐜舰杞ㄩ亾涓婁粠current鍒皌arget鐨勬鍚戣窛绂�
+ */
+ private double forwardDistance(long current, long target) {
+ if (target >= current) return target - current;
+ return PERIMETER - current + target;
+ }
+
+ /**
+ * 鑾峰彇绔欑偣鍦ㄨ建閬撲笂鐨勪綅缃�
+ */
+ private long getStationPosition(short staNo) {
+ try {
+ BasDevpPositionService positionService = SpringUtils.getBean(BasDevpPositionService.class);
+ com.zy.asrs.entity.BasDevpPosition pos = positionService.getOne(
+ new QueryWrapper<com.zy.asrs.entity.BasDevpPosition>().eq("dev_no", (int) staNo));
+ if (pos != null && pos.getPlcPosition() != null) return pos.getPlcPosition();
+ } catch (Exception ignore) {}
+ return 0L;
+ }
+
+ /**
+ * 鑾峰彇鎸囧畾RGV鐨凴gvThread瀹炰緥
+ */
+ private RgvThread getRgvThread(int rgvNo) {
+ try {
+ return (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgvNo);
+ } catch (Exception e) {
+ return null;
+ }
}
/******************************************************************************************/
--
Gitblit v1.9.1