From faaf77b2ed6609e1ec159f163cb97c79f37df532 Mon Sep 17 00:00:00 2001
From: Administrator <XS@163.COM>
Date: 星期六, 25 四月 2026 23:46:56 +0800
Subject: [PATCH] #
---
src/main/java/com/zy/common/utils/NavigateUtils.java | 223 ++++++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 185 insertions(+), 38 deletions(-)
diff --git a/src/main/java/com/zy/common/utils/NavigateUtils.java b/src/main/java/com/zy/common/utils/NavigateUtils.java
index e6b004e..3e88f2f 100644
--- a/src/main/java/com/zy/common/utils/NavigateUtils.java
+++ b/src/main/java/com/zy/common/utils/NavigateUtils.java
@@ -7,6 +7,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.zy.asrs.entity.BasDevp;
@@ -15,6 +16,7 @@
import com.zy.asrs.service.BasStationService;
import com.zy.core.News;
import com.zy.core.model.StationObjModel;
+import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -34,6 +36,7 @@
@Component
public class NavigateUtils {
+ private static final long STATION_PATH_RUNTIME_SNAPSHOT_TTL_MS = 2000L;
private static final String CFG_STATION_PATH_LEN_WEIGHT_PERCENT = "stationPathLenWeightPercent";
private static final String CFG_STATION_PATH_CONG_WEIGHT_PERCENT = "stationPathCongWeightPercent";
@@ -43,7 +46,17 @@
@Autowired
private BasStationService basStationService;
- public synchronized List<NavigateNode> calcByStationId(Integer startStationId, Integer endStationId) {
+ private final AtomicReference<CachedStationPathRuntimeSnapshot> runtimeSnapshotRef = new AtomicReference<>();
+
+ @Scheduled(fixedDelay = 1500, initialDelay = 3000)
+ public void refreshStationPathCaches() {
+ try {
+ runtimeSnapshotRef.set(new CachedStationPathRuntimeSnapshot(System.currentTimeMillis(), buildStationPathRuntimeSnapshot()));
+ } catch (Exception ignore) {
+ }
+ }
+
+ public List<NavigateNode> calcByStationId(Integer startStationId, Integer endStationId) {
BasStation startStation = basStationService.selectById(startStationId);
if (startStation == null) {
throw new CoolException("鏈壘鍒拌 璧风偣 瀵瑰簲鐨勭珯鐐规暟鎹�");
@@ -121,7 +134,38 @@
return fitlerList;
}
- public synchronized List<NavigateNode> calcByTrackSiteNo(int lev, Integer startTrackSiteNo, Integer endTrackSiteNo) {
+ public List<NavigateNode> calcReachablePathByStationId(Integer startStationId, Integer endStationId) {
+ BasStation startStation = basStationService.selectById(startStationId);
+ if (startStation == null) {
+ throw new CoolException("鏈壘鍒拌 璧风偣 瀵瑰簲鐨勭珯鐐规暟鎹�");
+ }
+ Integer lev = startStation.getStationLev();
+
+ NavigateSolution navigateSolution = new NavigateSolution();
+ List<List<NavigateNode>> stationMap = navigateSolution.getStationMap(lev);
+
+ NavigateNode startNode = navigateSolution.findStationNavigateNode(stationMap, startStationId);
+ if (startNode == null) {
+ throw new CoolException("鏈壘鍒拌 璧风偣 瀵瑰簲鐨勮妭鐐�");
+ }
+
+ NavigateNode endNode = navigateSolution.findStationNavigateNode(stationMap, endStationId);
+ if (endNode == null) {
+ throw new CoolException("鏈壘鍒拌 缁堢偣 瀵瑰簲鐨勮妭鐐�");
+ }
+
+ long startTime = System.currentTimeMillis();
+ News.info("[WCS Debug] 绔欑偣蹇�熷彲杈捐矾寰勫紑濮嬭绠�,startStationId={},endStationId={}", startStationId, endStationId);
+ NavigateNode resNode = navigateSolution.astarSearchJava(stationMap, startNode, endNode);
+ if (resNode == null) {
+ return new ArrayList<>();
+ }
+ News.info("[WCS Debug] 绔欑偣蹇�熷彲杈捐矾寰勮绠楀畬鎴愶紝鑰楁椂锛歿}ms", System.currentTimeMillis() - startTime);
+
+ return buildStationPathFromFatherChain(resNode, stationMap);
+ }
+
+ public List<NavigateNode> calcByTrackSiteNo(int lev, Integer startTrackSiteNo, Integer endTrackSiteNo) {
NavigateSolution navigateSolution = new NavigateSolution();
List<List<NavigateNode>> rgvTrackMap = navigateSolution.getRgvTrackMap(lev);
@@ -191,7 +235,7 @@
return fitlerList;
}
- public synchronized List<NavigateNode> findLiftStationList(int lev) {
+ public List<NavigateNode> findLiftStationList(int lev) {
NavigateSolution navigateSolution = new NavigateSolution();
List<List<NavigateNode>> stationMap = navigateSolution.getStationMap(lev);
@@ -218,45 +262,76 @@
return liftStationList;
}
- public synchronized List<NavigateNode> findStationBestPath(List<List<NavigateNode>> allList) {
+ private List<NavigateNode> buildStationPathFromFatherChain(NavigateNode endNode, List<List<NavigateNode>> stationMap) {
+ ArrayList<NavigateNode> list = new ArrayList<>();
+ HashSet<NavigateNode> visited = new HashSet<>();
+ int maxSteps = stationMap.size() * stationMap.get(0).size() + 5;
+ int steps = 0;
+ NavigateNode fatherNode = null;
+ NavigateNode currentNode = endNode;
+ while (currentNode != null && visited.add(currentNode) && steps++ < maxSteps) {
+ currentNode.setIsInflectionPoint(false);
+ currentNode.setIsLiftTransferPoint(false);
+
+ try {
+ JSONObject valueObject = JSON.parseObject(currentNode.getNodeValue());
+ if (valueObject != null) {
+ Object isLiftTransfer = valueObject.get("isLiftTransfer");
+ if (isLiftTransfer != null) {
+ String isLiftTransferStr = isLiftTransfer.toString();
+ if ("1".equals(isLiftTransferStr) || "true".equalsIgnoreCase(isLiftTransferStr)) {
+ currentNode.setIsLiftTransferPoint(true);
+ }
+ }
+ }
+ } catch (Exception ignore) {
+ }
+
+ HashMap<String, Object> result = searchInflectionPoint(currentNode, fatherNode, currentNode.getFather());
+ if (Boolean.parseBoolean(result.get("result").toString())) {
+ currentNode.setIsInflectionPoint(true);
+ currentNode.setDirection(result.get("direction").toString());
+ }
+
+ list.add(currentNode);
+ fatherNode = currentNode;
+ currentNode = currentNode.getFather();
+ }
+ if (steps >= maxSteps) {
+ throw new CoolException("璺緞鍥炴函瓒呭嚭瀹夊叏涓婇檺锛岀枒浼煎瓨鍦ㄧ埗閾惧惊鐜�");
+ }
+
+ Collections.reverse(list);
+ for (NavigateNode navigateNode : list) {
+ navigateNode.setFather(null);
+ }
+
+ HashSet<Integer> stationIdSet = new HashSet<>();
+ List<NavigateNode> filterList = new ArrayList<>();
+ for (NavigateNode navigateNode : list) {
+ JSONObject valueObject = JSON.parseObject(navigateNode.getNodeValue());
+ if (valueObject.containsKey("rgvCalcFlag")) {
+ continue;
+ }
+ if (stationIdSet.add(valueObject.getInteger("stationId"))) {
+ filterList.add(navigateNode);
+ }
+ }
+ return filterList;
+ }
+
+ public List<NavigateNode> findStationBestPath(List<List<NavigateNode>> allList) {
if (allList == null || allList.isEmpty()) {
return new ArrayList<>();
}
- Map<Integer, StationProtocol> statusMap = new HashMap<>();
- try {
- DeviceConfigService deviceConfigService = SpringUtils.getBean(DeviceConfigService.class);
- if (deviceConfigService != null) {
- List<DeviceConfig> devpList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
- .eq("device_type", String.valueOf(SlaveType.Devp)));
- for (DeviceConfig deviceConfig : devpList) {
- StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, deviceConfig.getDeviceNo());
- if (stationThread == null) {
- continue;
- }
- Map<Integer, StationProtocol> m = stationThread.getStatusMap();
- if (m != null && !m.isEmpty()) {
- statusMap.putAll(m);
- }
- }
- }
- } catch (Exception ignore) {}
-
- Set<Integer> outStationIdSet = loadAllOutStationIdSet();
-
- double lenWeightPercent = 50.0;
- double congWeightPercent = 50.0;
- double passOtherOutStationWeightPercent = 100.0;
- boolean forceSkipPassOtherOutStation = false;
- try {
- ConfigService configService = SpringUtils.getBean(ConfigService.class);
- if (configService != null) {
- lenWeightPercent = loadDoubleConfig(configService, CFG_STATION_PATH_LEN_WEIGHT_PERCENT, lenWeightPercent);
- congWeightPercent = loadDoubleConfig(configService, CFG_STATION_PATH_CONG_WEIGHT_PERCENT, congWeightPercent);
- passOtherOutStationWeightPercent = loadDoubleConfig(configService, CFG_STATION_PATH_PASS_OTHER_OUT_STATION_WEIGHT_PERCENT, passOtherOutStationWeightPercent);
- forceSkipPassOtherOutStation = loadBooleanConfig(configService, CFG_STATION_PATH_PASS_OTHER_OUT_STATION_FORCE_SKIP, false);
- }
- } catch (Exception ignore) {}
+ StationPathRuntimeSnapshot runtimeSnapshot = loadStationPathRuntimeSnapshot();
+ Map<Integer, StationProtocol> statusMap = runtimeSnapshot.statusMap;
+ Set<Integer> outStationIdSet = runtimeSnapshot.outStationIdSet;
+ double lenWeightPercent = runtimeSnapshot.lenWeightPercent;
+ double congWeightPercent = runtimeSnapshot.congWeightPercent;
+ double passOtherOutStationWeightPercent = runtimeSnapshot.passOtherOutStationWeightPercent;
+ boolean forceSkipPassOtherOutStation = runtimeSnapshot.forceSkipPassOtherOutStation;
List<List<NavigateNode>> candidates = new ArrayList<>();
List<Integer> lens = new ArrayList<>();
@@ -472,6 +547,59 @@
|| "on".equalsIgnoreCase(value);
}
+ private StationPathRuntimeSnapshot loadStationPathRuntimeSnapshot() {
+ long now = System.currentTimeMillis();
+ CachedStationPathRuntimeSnapshot cached = runtimeSnapshotRef.get();
+ if (cached != null && now - cached.loadTimeMs < STATION_PATH_RUNTIME_SNAPSHOT_TTL_MS && cached.snapshot != null) {
+ return cached.snapshot;
+ }
+ StationPathRuntimeSnapshot snapshot = buildStationPathRuntimeSnapshot();
+ runtimeSnapshotRef.set(new CachedStationPathRuntimeSnapshot(now, snapshot));
+ return snapshot;
+ }
+
+ private StationPathRuntimeSnapshot buildStationPathRuntimeSnapshot() {
+ StationPathRuntimeSnapshot snapshot = new StationPathRuntimeSnapshot();
+ snapshot.statusMap = loadAllStationStatusMap();
+ snapshot.outStationIdSet = loadAllOutStationIdSet();
+
+ try {
+ ConfigService configService = SpringUtils.getBean(ConfigService.class);
+ if (configService != null) {
+ snapshot.lenWeightPercent = loadDoubleConfig(configService, CFG_STATION_PATH_LEN_WEIGHT_PERCENT, snapshot.lenWeightPercent);
+ snapshot.congWeightPercent = loadDoubleConfig(configService, CFG_STATION_PATH_CONG_WEIGHT_PERCENT, snapshot.congWeightPercent);
+ snapshot.passOtherOutStationWeightPercent = loadDoubleConfig(configService, CFG_STATION_PATH_PASS_OTHER_OUT_STATION_WEIGHT_PERCENT, snapshot.passOtherOutStationWeightPercent);
+ snapshot.forceSkipPassOtherOutStation = loadBooleanConfig(configService, CFG_STATION_PATH_PASS_OTHER_OUT_STATION_FORCE_SKIP, false);
+ }
+ } catch (Exception ignore) {
+ }
+ return snapshot;
+ }
+
+ private Map<Integer, StationProtocol> loadAllStationStatusMap() {
+ Map<Integer, StationProtocol> statusMap = new HashMap<>();
+ try {
+ DeviceConfigService deviceConfigService = SpringUtils.getBean(DeviceConfigService.class);
+ if (deviceConfigService == null) {
+ return statusMap;
+ }
+ List<DeviceConfig> devpList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
+ .eq("device_type", String.valueOf(SlaveType.Devp)));
+ for (DeviceConfig deviceConfig : devpList) {
+ StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, deviceConfig.getDeviceNo());
+ if (stationThread == null) {
+ continue;
+ }
+ Map<Integer, StationProtocol> m = stationThread.getStatusMap();
+ if (m != null && !m.isEmpty()) {
+ statusMap.putAll(m);
+ }
+ }
+ } catch (Exception ignore) {
+ }
+ return statusMap;
+ }
+
//鍒ゆ柇褰撳墠鑺傜偣鍒颁笅涓�涓妭鐐规槸鍚︿负鎷愮偣
public HashMap<String,Object> searchInflectionPoint(NavigateNode currentNode, NavigateNode fatherNode, NavigateNode nextNode) {
HashMap<String, Object> map = new HashMap<>();
@@ -523,4 +651,23 @@
return direction;
}
+
+ private static class StationPathRuntimeSnapshot {
+ private Map<Integer, StationProtocol> statusMap = new HashMap<>();
+ private Set<Integer> outStationIdSet = new HashSet<>();
+ private double lenWeightPercent = 50.0;
+ private double congWeightPercent = 50.0;
+ private double passOtherOutStationWeightPercent = 100.0;
+ private boolean forceSkipPassOtherOutStation = false;
+ }
+
+ private static class CachedStationPathRuntimeSnapshot {
+ private final long loadTimeMs;
+ private final StationPathRuntimeSnapshot snapshot;
+
+ private CachedStationPathRuntimeSnapshot(long loadTimeMs, StationPathRuntimeSnapshot snapshot) {
+ this.loadTimeMs = loadTimeMs;
+ this.snapshot = snapshot;
+ }
+ }
}
--
Gitblit v1.9.1