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