From 058d7bbb714634e42bff1dd71fdfca3a378421d3 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期二, 31 三月 2026 20:50:50 +0800
Subject: [PATCH] #
---
src/main/java/com/zy/core/thread/impl/station/StationSegmentExecutor.java | 40 +++++++++
src/test/java/com/zy/core/thread/impl/station/StationSegmentPlannerTest.java | 49 ++++++++++++
src/test/java/com/zy/common/utils/NavigateUtilsTest.java | 49 ++++++++++++
src/main/java/com/zy/common/utils/NavigateUtils.java | 9 +
src/main/java/com/zy/core/thread/impl/station/StationSegmentPlanner.java | 19 ++++
src/test/java/com/zy/core/thread/impl/station/StationSegmentExecutorTest.java | 33 ++++++++
6 files changed, 195 insertions(+), 4 deletions(-)
diff --git a/src/main/java/com/zy/common/utils/NavigateUtils.java b/src/main/java/com/zy/common/utils/NavigateUtils.java
index ee68fc0..541c143 100644
--- a/src/main/java/com/zy/common/utils/NavigateUtils.java
+++ b/src/main/java/com/zy/common/utils/NavigateUtils.java
@@ -1994,8 +1994,8 @@
}
private List<NavigateNode> normalizeStationPath(List<NavigateNode> path) {
- HashSet<Integer> stationIdSet = new HashSet<>();
List<NavigateNode> filterList = new ArrayList<>();
+ Integer lastStationId = null;
for (NavigateNode navigateNode : safeList(path)) {
if (navigateNode == null) {
continue;
@@ -2010,9 +2010,14 @@
continue;
}
Integer stationId = valueObject.getInteger("stationId");
- if (stationId == null || !stationIdSet.add(stationId)) {
+ if (stationId == null) {
continue;
}
+ // 浠呭帇缂╄繛缁噸澶嶇珯鐐癸紝淇濈暀鐜嚎閲嶇畻鍦烘櫙涓嬪悗缁啀娆$粡杩囩殑鍚屼竴绔欑偣銆�
+ if (lastStationId != null && lastStationId.equals(stationId)) {
+ continue;
+ }
+ lastStationId = stationId;
NavigateNode clonedNode = navigateNode.clone();
if (clonedNode == null) {
continue;
diff --git a/src/main/java/com/zy/core/thread/impl/station/StationSegmentExecutor.java b/src/main/java/com/zy/core/thread/impl/station/StationSegmentExecutor.java
index eca8680..95209a6 100644
--- a/src/main/java/com/zy/core/thread/impl/station/StationSegmentExecutor.java
+++ b/src/main/java/com/zy/core/thread/impl/station/StationSegmentExecutor.java
@@ -89,6 +89,7 @@
long lastSeenAt = System.currentTimeMillis();
int segCursor = 0;
Integer lastCurrentStationId = null;
+ int lastMatchedPathIndex = -1;
boolean firstRun = true;
while (true) {
try {
@@ -144,12 +145,17 @@
break;
}
- int currentIndex = effectiveFullPath.indexOf(currentStation.getStationId());
+ int currentIndex = resolveCurrentPathIndex(
+ effectiveFullPath,
+ currentStation.getStationId(),
+ lastMatchedPathIndex
+ );
if (currentIndex < 0) {
Thread.sleep(500L);
firstRun = false;
continue;
}
+ lastMatchedPathIndex = currentIndex;
int remaining = effectiveFullPath.size() - currentIndex - 1;
if (remaining <= 0) {
@@ -192,6 +198,38 @@
}
}
+ private int resolveCurrentPathIndex(List<Integer> fullPathStationIds,
+ Integer currentStationId,
+ int lastMatchedPathIndex) {
+ if (fullPathStationIds == null || fullPathStationIds.isEmpty() || currentStationId == null) {
+ return -1;
+ }
+ if (lastMatchedPathIndex >= 0
+ && lastMatchedPathIndex < fullPathStationIds.size()
+ && equalsInteger(currentStationId, fullPathStationIds.get(lastMatchedPathIndex))) {
+ return lastMatchedPathIndex;
+ }
+
+ int nextIndex = findNextStationIndex(fullPathStationIds, currentStationId, Math.max(lastMatchedPathIndex + 1, 0));
+ if (nextIndex >= 0) {
+ return nextIndex;
+ }
+ return findNextStationIndex(fullPathStationIds, currentStationId, 0);
+ }
+
+ private int findNextStationIndex(List<Integer> path, Integer stationId, int fromIndex) {
+ if (path == null || path.isEmpty() || stationId == null) {
+ return -1;
+ }
+ int startIdx = Math.max(fromIndex, 0);
+ for (int i = startIdx; i < path.size(); i++) {
+ if (equalsInteger(stationId, path.get(i))) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
private boolean sendSegmentWithRetry(StationCommand command,
StationTaskTraceRegistry traceRegistry,
Integer traceVersion,
diff --git a/src/main/java/com/zy/core/thread/impl/station/StationSegmentPlanner.java b/src/main/java/com/zy/core/thread/impl/station/StationSegmentPlanner.java
index 3c9328c..6d5fba6 100644
--- a/src/main/java/com/zy/core/thread/impl/station/StationSegmentPlanner.java
+++ b/src/main/java/com/zy/core/thread/impl/station/StationSegmentPlanner.java
@@ -34,8 +34,12 @@
int total = path.size();
List<Integer> segmentEndIndices = new ArrayList<>();
if (liftTransferPath != null) {
+ int searchStartIdx = 0;
for (Integer liftTransferStationId : liftTransferPath) {
- int endIndex = path.indexOf(liftTransferStationId);
+ int endIndex = findNextStationIndex(path, liftTransferStationId, searchStartIdx);
+ if (endIndex >= 0) {
+ searchStartIdx = endIndex + 1;
+ }
if (endIndex <= 0) {
continue;
}
@@ -87,6 +91,19 @@
return plan;
}
+ private int findNextStationIndex(List<Integer> path, Integer stationId, int fromIndex) {
+ if (path == null || path.isEmpty() || stationId == null) {
+ return -1;
+ }
+ int startIdx = Math.max(fromIndex, 0);
+ for (int i = startIdx; i < path.size(); i++) {
+ if (stationId.equals(path.get(i))) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
private List<Integer> copyIntegerList(List<Integer> source) {
if (source == null) {
return new ArrayList<>();
diff --git a/src/test/java/com/zy/common/utils/NavigateUtilsTest.java b/src/test/java/com/zy/common/utils/NavigateUtilsTest.java
new file mode 100644
index 0000000..2318053
--- /dev/null
+++ b/src/test/java/com/zy/common/utils/NavigateUtilsTest.java
@@ -0,0 +1,49 @@
+package com.zy.common.utils;
+
+import com.alibaba.fastjson.JSONObject;
+import com.zy.common.model.NavigateNode;
+import org.junit.jupiter.api.Test;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class NavigateUtilsTest {
+
+ @Test
+ void normalizeStationPath_keepsLoopRevisitStationsWhileCompressingAdjacentDuplicates() {
+ NavigateUtils navigateUtils = new NavigateUtils();
+
+ @SuppressWarnings("unchecked")
+ List<NavigateNode> normalizedPath = (List<NavigateNode>) ReflectionTestUtils.invokeMethod(
+ navigateUtils,
+ "normalizeStationPath",
+ List.of(
+ buildNode(121, 0, 0),
+ buildNode(121, 0, 1),
+ buildNode(124, 0, 2),
+ buildNode(186, 0, 3),
+ buildNode(189, 0, 4),
+ buildNode(121, 0, 5),
+ buildNode(124, 0, 6),
+ buildNode(124, 0, 7),
+ buildNode(125, 0, 8),
+ buildNode(127, 0, 9)
+ )
+ );
+
+ List<Integer> stationIdList = normalizedPath.stream()
+ .map(node -> JSONObject.parseObject(node.getNodeValue()).getInteger("stationId"))
+ .collect(Collectors.toList());
+
+ assertEquals(List.of(121, 124, 186, 189, 121, 124, 125, 127), stationIdList);
+ }
+
+ private NavigateNode buildNode(int stationId, int x, int y) {
+ NavigateNode node = new NavigateNode(x, y);
+ node.setNodeValue("{\"stationId\":" + stationId + "}");
+ return node;
+ }
+}
diff --git a/src/test/java/com/zy/core/thread/impl/station/StationSegmentExecutorTest.java b/src/test/java/com/zy/core/thread/impl/station/StationSegmentExecutorTest.java
index abb018b..8722170 100644
--- a/src/test/java/com/zy/core/thread/impl/station/StationSegmentExecutorTest.java
+++ b/src/test/java/com/zy/core/thread/impl/station/StationSegmentExecutorTest.java
@@ -14,9 +14,11 @@
import org.springframework.context.ApplicationContext;
import org.springframework.test.util.ReflectionTestUtils;
+import java.util.List;
import java.util.function.Function;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -26,6 +28,37 @@
class StationSegmentExecutorTest {
@Test
+ void resolveCurrentPathIndex_prefersForwardOccurrenceForLoopRevisitStations() {
+ StationSegmentExecutor executor = new StationSegmentExecutor(new DeviceConfig(), mock(RedisUtil.class), command -> null);
+
+ Integer second121Index = ReflectionTestUtils.invokeMethod(
+ executor,
+ "resolveCurrentPathIndex",
+ List.of(121, 124, 186, 189, 121, 124, 125, 127),
+ 121,
+ 3
+ );
+ Integer second124Index = ReflectionTestUtils.invokeMethod(
+ executor,
+ "resolveCurrentPathIndex",
+ List.of(121, 124, 186, 189, 121, 124, 125, 127),
+ 124,
+ 4
+ );
+ Integer same124Index = ReflectionTestUtils.invokeMethod(
+ executor,
+ "resolveCurrentPathIndex",
+ List.of(121, 124, 186, 189, 121, 124, 125, 127),
+ 124,
+ 5
+ );
+
+ assertEquals(Integer.valueOf(4), second121Index);
+ assertEquals(Integer.valueOf(5), second124Index);
+ assertEquals(Integer.valueOf(5), same124Index);
+ }
+
+ @Test
void sendSegmentWithRetry_skipsWhenRouteIsCancelPending() {
ApplicationContext applicationContext = mock(ApplicationContext.class);
StationMoveCoordinator coordinator = new StationMoveCoordinator();
diff --git a/src/test/java/com/zy/core/thread/impl/station/StationSegmentPlannerTest.java b/src/test/java/com/zy/core/thread/impl/station/StationSegmentPlannerTest.java
new file mode 100644
index 0000000..440a574
--- /dev/null
+++ b/src/test/java/com/zy/core/thread/impl/station/StationSegmentPlannerTest.java
@@ -0,0 +1,49 @@
+package com.zy.core.thread.impl.station;
+
+import com.zy.core.enums.StationCommandType;
+import com.zy.core.model.command.StationCommand;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class StationSegmentPlannerTest {
+
+ @Test
+ void buildPlan_usesLaterLiftTransferOccurrencesWhenLoopPathRevisitsStations() {
+ StationSegmentPlanner planner = new StationSegmentPlanner();
+
+ StationCommand original = new StationCommand();
+ original.setTaskNo(11017);
+ original.setCommandType(StationCommandType.MOVE);
+ original.setStationId(121);
+ original.setTargetStaNo(127);
+ original.setNavigatePath(List.of(121, 124, 186, 189, 121, 124, 125, 127));
+ original.setLiftTransferPath(List.of(121, 124, 186, 189, 121, 124, 127));
+
+ StationSegmentExecutionPlan plan = planner.buildPlan(original);
+
+ assertEquals(
+ List.of(
+ List.of(121, 124),
+ List.of(124, 186),
+ List.of(186, 189),
+ List.of(189, 121),
+ List.of(121, 124),
+ List.of(124, 125, 127)
+ ),
+ plan.getSegmentCommands().stream()
+ .map(StationCommand::getNavigatePath)
+ .collect(Collectors.toList())
+ );
+ assertEquals(List.of(1, 2, 3, 4, 5, 6),
+ plan.getSegmentCommands().stream()
+ .map(StationCommand::getSegmentNo)
+ .collect(Collectors.toList()));
+ assertTrue(plan.getSegmentCommands().stream()
+ .allMatch(command -> Integer.valueOf(6).equals(command.getSegmentCount())));
+ }
+}
--
Gitblit v1.9.1