From e14f937fac9ba2c9af1fffd4d37f0eba86292575 Mon Sep 17 00:00:00 2001
From: luxiaotao1123 <t1341870251@163.com>
Date: 星期二, 07 一月 2025 13:22:35 +0800
Subject: [PATCH] #
---
zy-acs-flow/src/map/constants.js | 2
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/AgvDataService.java | 7
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/PathQueueConsumer.java | 220 +++++++++++++++++++++++++++++++
zy-acs-manager/src/main/java/com/zy/acs/manager/core/scheduler/MapDataWsScheduler.java | 2
zy-acs-manager/src/main/java/com/zy/acs/manager/common/config/BeanConfig.java | 10 +
zy-acs-manager/src/main/java/com/zy/acs/manager/core/DemoController.java | 46 ++++++
zy-acs-manager/src/main/java/com/zy/acs/manager/core/domain/UnlockPathTask.java | 20 ++
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MapService.java | 61 +-------
8 files changed, 311 insertions(+), 57 deletions(-)
diff --git a/zy-acs-flow/src/map/constants.js b/zy-acs-flow/src/map/constants.js
index d7d46c0..8ab6ce1 100644
--- a/zy-acs-flow/src/map/constants.js
+++ b/zy-acs-flow/src/map/constants.js
@@ -1,5 +1,5 @@
-export const ANIMATE_DURING_TIME = 800;
+export const ANIMATE_DURING_TIME = 600;
export const MAP_DEFAULT_ROTATION = 270;
diff --git a/zy-acs-manager/src/main/java/com/zy/acs/manager/common/config/BeanConfig.java b/zy-acs-manager/src/main/java/com/zy/acs/manager/common/config/BeanConfig.java
index ed02249..d64f963 100644
--- a/zy-acs-manager/src/main/java/com/zy/acs/manager/common/config/BeanConfig.java
+++ b/zy-acs-manager/src/main/java/com/zy/acs/manager/common/config/BeanConfig.java
@@ -1,7 +1,11 @@
package com.zy.acs.manager.common.config;
+import com.zy.acs.manager.core.domain.UnlockPathTask;
+import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
+
+import java.util.concurrent.LinkedBlockingQueue;
/**
* Created by vincent on 12/19/2023
@@ -9,4 +13,10 @@
@Configuration
@ComponentScan(value = "com.zy.acs.common.config")
public class BeanConfig {
+
+ @Bean
+ public LinkedBlockingQueue<UnlockPathTask> unlockTaskQueue() {
+ return new LinkedBlockingQueue<>();
+ }
+
}
diff --git a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/DemoController.java b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/DemoController.java
index f525f3f..2369fee 100644
--- a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/DemoController.java
+++ b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/DemoController.java
@@ -69,6 +69,52 @@
return R.ok("RCS-FLOW-1.0.0");
}
+ // {"msg":"Success","code":200,"data":[[38,2],[38,3],[38,4],[38,5],[38,6],[37,6],[36,6],[35,6],[34,6],[33,6],[32,6],[31,6],[30,6],[29,6],[28,6],[27,6],[26,6],[25,6]]}
+ // {"msg":"Success","code":200,"data":[[38,2],[38,3],[38,4],[38,5],[38,6],[37,6],[36,6],[35,6],[34,6],[33,6],[32,6],[31,6],[30,6],[29,6],[28,6],[27,6],[26,6],[25,6]]}
+ @RequestMapping(value = "/system/demo", method = {RequestMethod.GET, RequestMethod.POST})
+ public R demo() {
+ long startTime = System.currentTimeMillis();
+ for (int i = 0; i < 1000; i++) {
+ this.demo1();
+ }
+ System.out.println(System.currentTimeMillis() - startTime);
+ return R.ok();
+ }
+
+ private R demo1() {
+ List<String> path = new ArrayList<>();
+ path.add("00000035");
+ path.add("00000085");
+ path.add("00000135");
+ path.add("00000185");
+ path.add("00000235");
+ path.add("00000234");
+ path.add("00000233");
+ path.add("00000232");
+ path.add("00000231");
+ path.add("00000230");
+ path.add("00000229");
+ path.add("00000228");
+ path.add("00000227");
+ path.add("00000226");
+ path.add("00000225");
+ path.add("00000224");
+ path.add("00000223");
+ path.add("00000222");
+
+// List<int[]> codeMatrixIdxList = new ArrayList<>();
+// for (String pathStr : path) {
+// int[] codeMatrixIdx = mapDataDispatcher.getCodeMatrixIdx(null, pathStr);
+// codeMatrixIdxList.add(codeMatrixIdx);
+// }
+
+ List<int[]> codeMatrixIdxList = mapDataDispatcher.getCodeMatrixIdxList(null, path);
+
+// System.out.println(codeMatrixIdxList.toString());
+
+ return R.ok().add(codeMatrixIdxList);
+ }
+
// @RequestMapping(value = "/system/route/generate", method = {RequestMethod.GET, RequestMethod.POST})
// public R generate() {
// String[][] codeMatrix = mapDataDispatcher.getCodeMatrix(null);
diff --git a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/domain/UnlockPathTask.java b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/domain/UnlockPathTask.java
new file mode 100644
index 0000000..229cefe
--- /dev/null
+++ b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/domain/UnlockPathTask.java
@@ -0,0 +1,20 @@
+package com.zy.acs.manager.core.domain;
+
+import lombok.Data;
+
+@Data
+public class UnlockPathTask {
+
+ private String agvNo;
+
+ private String codeData;
+
+ public UnlockPathTask() {
+ }
+
+ public UnlockPathTask(String agvNo, String codeData) {
+ this.agvNo = agvNo;
+ this.codeData = codeData;
+ }
+
+}
diff --git a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/scheduler/MapDataWsScheduler.java b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/scheduler/MapDataWsScheduler.java
index c0d5448..5b5f82b 100644
--- a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/scheduler/MapDataWsScheduler.java
+++ b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/scheduler/MapDataWsScheduler.java
@@ -33,7 +33,7 @@
@Component
public class MapDataWsScheduler {
- public static final int WEBSOCKET_BROADCAST_INTERVAL = 800;
+ public static final int WEBSOCKET_BROADCAST_INTERVAL = 600;
private ExecutorService singleThreadExecutor;
diff --git a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/AgvDataService.java b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/AgvDataService.java
index 4918fd8..452befc 100644
--- a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/AgvDataService.java
+++ b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/AgvDataService.java
@@ -84,9 +84,10 @@
AGV_12_UP agv_12_up = (AGV_12_UP) msgBody;
// unlock path
- threadPoolRegulator.getInstance().execute(() -> {
- mapService.unlockPath(protocol.getAgvNo(), agv_12_up.getQrCode());
- });
+ mapService.unlockPath(protocol.getAgvNo(), agv_12_up.getQrCode());
+// threadPoolRegulator.getInstance().execute(() -> {
+//
+// });
// finish jam
threadPoolRegulator.getInstance().execute(() -> jamService.checkIfFinish(agvId, agv_12_up.getQrCode()));
diff --git a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MapService.java b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MapService.java
index 11f942d..976c8e0 100644
--- a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MapService.java
+++ b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MapService.java
@@ -5,9 +5,9 @@
import com.zy.acs.framework.common.Cools;
import com.zy.acs.manager.common.utils.MapDataUtils;
import com.zy.acs.manager.core.constant.MapDataConstant;
+import com.zy.acs.manager.core.domain.UnlockPathTask;
import com.zy.acs.manager.core.service.astart.*;
import com.zy.acs.manager.core.service.astart.domain.AStarNavigateNode;
-import com.zy.acs.manager.core.service.astart.domain.DynamicNode;
import com.zy.acs.manager.core.service.floyd.FloydNavigateService;
import com.zy.acs.manager.manager.entity.Code;
import com.zy.acs.manager.manager.entity.Loc;
@@ -16,12 +16,13 @@
import com.zy.acs.manager.manager.service.CodeService;
import com.zy.acs.manager.system.service.ConfigService;
import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang.time.StopWatch;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.*;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
@@ -45,6 +46,8 @@
private ConfigService configService;
@Autowired
private ActionService actionService;
+ @Autowired
+ private LinkedBlockingQueue<UnlockPathTask> unlockTaskQueue;
/**
* 瀵诲潃 ===>> A Star
@@ -177,58 +180,12 @@
mapDataDispatcher.modifyDynamicMatrix(lev, codeMatrixIdxList, agvNo);
}
- public synchronized void unlockPath(String agvNo, String codeData) {
+ public void unlockPath(String agvNo, String codeData) {
try {
- StopWatch stopWatch = new StopWatch();
- stopWatch.start();
-
- if (Cools.isEmpty(agvNo, codeData)) {
- return;
- }
-
- Integer lev = null;
-
- String[][] codeMatrix = mapDataDispatcher.getCodeMatrix(null);
- int[] codeMatrixIdx = mapDataDispatcher.getCodeMatrixIdx(lev, codeData);
-
-
- DynamicNode[][] dynamicMatrix = mapDataDispatcher.getDynamicMatrix(lev);
-
- DynamicNode dynamicNode = dynamicMatrix[codeMatrixIdx[0]][codeMatrixIdx[1]];
-
-
- int serial = dynamicNode.getSerial();
-
- List<int[]> resetCodeIdxList = new ArrayList<>();
-
- for (int i = 0; i < dynamicMatrix.length; i++) {
- for (int j = 0; j < dynamicMatrix[i].length; j++) {
-
-// if (i == codeMatrixIdx[0] && j == codeMatrixIdx[1]) { continue; }
-
- DynamicNode node = dynamicMatrix[i][j];
- if (node.getVehicle().equals(agvNo)) {
- if (node.getSerial() < serial) {
- resetCodeIdxList.add(new int[] {i, j});
- }
- }
- }
- }
-
- if (!Cools.isEmpty(resetCodeIdxList)) {
-
- mapDataDispatcher.clearDynamicMatrixByCodeList(lev, resetCodeIdxList);
- }
-
- stopWatch.stop();
- if (stopWatch.getTime() > 50) {
- log.info("瑙i攣璺緞鍑芥暟鑺辫垂鏃堕棿涓猴細{}姣......", stopWatch.getTime());
- }
-
- } catch (Exception e) {
- log.error("MapService.unlockPath", e);
+ unlockTaskQueue.offer(new UnlockPathTask(agvNo, codeData), 5, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ log.error("unlockTaskQueue", e);
}
-
}
public List<String> getWaveScopeByCodeList(Integer lev, List<String> codeList, Double radiusLen) {
diff --git a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/PathQueueConsumer.java b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/PathQueueConsumer.java
new file mode 100644
index 0000000..8d38600
--- /dev/null
+++ b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/PathQueueConsumer.java
@@ -0,0 +1,220 @@
+package com.zy.acs.manager.core.service;
+
+import com.zy.acs.framework.common.Cools;
+import com.zy.acs.manager.core.domain.UnlockPathTask;
+import com.zy.acs.manager.core.service.astart.MapDataDispatcher;
+import com.zy.acs.manager.core.service.astart.domain.DynamicNode;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import java.util.*;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class PathQueueConsumer {
+
+ private ExecutorService consumerExecutor;
+
+ @Autowired
+ private LinkedBlockingQueue<UnlockPathTask> unlockTaskQueue;
+ @Autowired
+ private MapDataDispatcher mapDataDispatcher;
+
+ @PostConstruct
+ public void init() {
+ Integer lev = MapDataDispatcher.MAP_DEFAULT_LEV;
+
+ this.consumerExecutor = Executors.newSingleThreadExecutor();
+ this.consumerExecutor.execute(() -> {
+ while (!Thread.currentThread().isInterrupted()) {
+ try {
+
+ List<UnlockPathTask> tasks = new ArrayList<>();
+ // if unlockTaskQueue was empty, then block
+// tasks.add(unlockTaskQueue.take());
+ unlockTaskQueue.drainTo(tasks);
+
+ if (tasks.isEmpty()) {
+ Thread.sleep(30);
+ } else {
+
+ long startTime = System.currentTimeMillis();
+
+ List<int[]> resetCodeIdxList = null;
+ if (tasks.size() == 1) {
+ resetCodeIdxList = this.getResetCodeList(lev, tasks.get(0));
+ } else if (tasks.size() > 1) {
+ log.info("consumer task count:{}", tasks.size());
+ resetCodeIdxList = this.getResetCodeList(lev,tasks);
+ }
+
+ if (!Cools.isEmpty(resetCodeIdxList)) {
+ this.dealResetCodeList(lev, resetCodeIdxList);
+ }
+
+ log.info("consumer unlock path spend time:{}", System.currentTimeMillis() - startTime);
+ }
+
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ log.error("PathQueueConsumer[Thread.currentThread.interrupt]", e);
+ break;
+ } catch (Exception e) {
+ log.error("PathQueueConsumer", e);
+ }
+ }
+ });
+ }
+
+ private List<int[]> getResetCodeList(Integer lev, List<UnlockPathTask> tasks) {
+ if (Cools.isEmpty(tasks)) {
+ return new ArrayList<>();
+ }
+
+ // 1.鏁寸悊棰勫鐞嗘暟鎹�
+ String[][] codeMatrix = mapDataDispatcher.getCodeMatrix(lev);
+ DynamicNode[][] dynamicMatrix = mapDataDispatcher.getDynamicMatrix(lev);
+
+// Set<String> codeDataSet = tasks.stream().map(UnlockPathTask::getCodeData).collect(Collectors.toSet());
+ Set<String> agvNoSet = tasks.stream().map(UnlockPathTask::getAgvNo).collect(Collectors.toSet());
+
+ Map<String, Set<String>> agvNoCodeDataMap = new HashMap<>();
+ tasks.forEach(task -> agvNoCodeDataMap.computeIfAbsent(task.getAgvNo(), k -> new HashSet<>()).add(task.getCodeData()));
+
+
+ // 2.鑾峰彇agv鐨勬墍鏈塪ynamic node锛屽苟涓旇褰昦gv褰撳墠鐨刣ynamic node serial
+
+ // agvNo : List<{code, serial}>
+ Map<String, List<CodeSerial>> codeSerialMap = new HashMap<>();
+ // agvNo : serial
+ Map<String, Integer> agvNoSerialMap = new HashMap<>();
+
+
+ for (int i = 0; i < dynamicMatrix.length; i++) {
+ for (int j = 0; j < dynamicMatrix[i].length; j++) {
+ DynamicNode dynamicNode = dynamicMatrix[i][j];
+
+ if (agvNoSet.contains(dynamicNode.getVehicle())) {
+
+ String codeData = codeMatrix[i][j];
+ String vehicle = dynamicNode.getVehicle();
+ int serial = dynamicNode.getSerial();
+
+ List<CodeSerial> codeSerials = codeSerialMap.computeIfAbsent(vehicle, k -> new ArrayList<>());
+ codeSerials.add(new CodeSerial(new int[] {i, j}, serial));
+
+ if (agvNoCodeDataMap.get(vehicle).contains(codeData)) {
+ Integer agvNoSerial = agvNoSerialMap.get(vehicle);
+ if (null == agvNoSerial) {
+ agvNoSerialMap.put(vehicle, serial);
+ } else {
+ if (serial > agvNoSerial) {
+ agvNoSerialMap.put(vehicle, serial);
+ }
+ }
+
+ }
+
+ }
+
+ }
+ }
+
+ // 3.澶勭悊codeSerialMap锛岃幏鍙栨墍鏈塧gv闇�瑕侀噴鏀剧殑code matrix list
+
+ List<int[]> resetCodeIdxList = new ArrayList<>();
+
+ for (Map.Entry<String, List<CodeSerial>> entry : codeSerialMap.entrySet()) {
+ String agvNo = entry.getKey();
+ List<CodeSerial> codeSerials = entry.getValue();
+
+ Integer maxSerial = agvNoSerialMap.get(agvNo);
+
+ for (CodeSerial codeSerial : codeSerials) {
+ if (codeSerial.getSerial() < maxSerial) {
+ resetCodeIdxList.add(codeSerial.getCodeMatrixIdx());
+ }
+ }
+
+ }
+
+ return resetCodeIdxList;
+ }
+
+ private List<int[]> getResetCodeList(Integer lev, UnlockPathTask task) {
+ if (null == task) {
+ return new ArrayList<>();
+ }
+ DynamicNode[][] dynamicMatrix = mapDataDispatcher.getDynamicMatrix(lev);
+
+ String agvNo = task.getAgvNo();
+ int[] codeMatrixIdx = mapDataDispatcher.getCodeMatrixIdx(lev, task.getCodeData());
+
+ DynamicNode dynamicNode = dynamicMatrix[codeMatrixIdx[0]][codeMatrixIdx[1]];
+ int serial = dynamicNode.getSerial();
+
+ List<int[]> resetCodeIdxList = new ArrayList<>();
+
+ for (int i = 0; i < dynamicMatrix.length; i++) {
+ for (int j = 0; j < dynamicMatrix[i].length; j++) {
+
+ DynamicNode node = dynamicMatrix[i][j];
+ if (node.getVehicle().equals(agvNo)) {
+ if (node.getSerial() < serial) {
+ resetCodeIdxList.add(new int[] {i, j});
+ }
+ }
+ }
+ }
+
+ return resetCodeIdxList;
+ }
+
+ private void dealResetCodeList(Integer lev, List<int[]> resetCodeIdxList) {
+ if (Cools.isEmpty(resetCodeIdxList)) {
+ return;
+ }
+
+ mapDataDispatcher.clearDynamicMatrixByCodeList(lev, resetCodeIdxList);
+ }
+
+ @Data
+ public static class CodeSerial {
+ private String codeData;
+ private int[] codeMatrixIdx;
+ private int serial;
+
+ public CodeSerial(int[] codeMatrixIdx, int serial) {
+ this.codeMatrixIdx = codeMatrixIdx;
+ this.serial = serial;
+ }
+ }
+
+ @PreDestroy
+ public void destroy() {
+ if (this.consumerExecutor != null) {
+ this.consumerExecutor.shutdown();
+ try {
+ if (!this.consumerExecutor.awaitTermination(5, TimeUnit.SECONDS)) {
+ this.consumerExecutor.shutdownNow();
+ if (!this.consumerExecutor.awaitTermination(5, TimeUnit.SECONDS)) {
+ log.error("this.consumerExecutor failed to shutdown");
+ }
+ }
+ } catch (InterruptedException ie) {
+ this.consumerExecutor.shutdownNow();
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+
+}
--
Gitblit v1.9.1