luxiaotao1123
2024-12-26 d14e77e0da0db122867500fecf6d0607ef4d3bd5
Merge remote-tracking branch 'origin/master'
9个文件已修改
1个文件已添加
261 ■■■■ 已修改文件
version/db/mock/50-20241225.rar 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/map/constants.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/scheduler/MapDataWsScheduler.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/AvoidWaveCalculator.java 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MapService.java 51 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/RetreatNavigateService.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/TrafficService.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/astart/AStarNavigateService.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/astart/MapDataDispatcher.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/resources/agv.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
version/db/mock/50-20241225.rar
Binary files differ
zy-acs-flow/src/map/constants.js
@@ -1,5 +1,5 @@
export const ANIMATE_DURING_TIME = 800;
export const ANIMATE_DURING_TIME = 1000;
export const MAP_DEFAULT_ROTATION = 270;
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 = 1000;
    private ExecutorService singleThreadExecutor;
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/AvoidWaveCalculator.java
@@ -50,6 +50,8 @@
    private ExecutorService singleThreadExecutor;
    private File pythonFile = null;
    @Autowired
    private MapDataDispatcher mapDataDispatcher;
    @Autowired
@@ -85,27 +87,8 @@
        });
    }
    private File pythonFile = null;
    private File loadPythonFile() {
        File scriptFile = null;
        try {
            Resource resource = new ClassPathResource("agv.py");
            InputStream is = resource.getInputStream();
            scriptFile = File.createTempFile("agv", ".py");
            scriptFile.deleteOnExit();
            Files.copy(is, scriptFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
            scriptFile.setExecutable(true);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return scriptFile;
    }
    public void calcWaveScope() {
    public boolean calcWaveScope() {
        Integer lev = MapDataDispatcher.MAP_DEFAULT_LEV;
        boolean lockAcquired = false;
@@ -115,9 +98,30 @@
        try {
            if (!(lockAcquired = lock.tryLock(LOCK_TIMEOUT, TimeUnit.SECONDS))) {
                log.warn("AvoidWaveCalculator execute fail, cause can not acquire lock ...");
                return;
                return false;
            }
//            return this.calcWaveScopeByPython(lev);
            return this.calcWaveScopeByJava(lev);
        } catch (Exception e) {
            log.error(this.getClass().getSimpleName(), e);
            return false;
        } finally {
            if (lockAcquired) {
                lock.unlock();
            }
            stopWatch.stop();
            if (stopWatch.getTime() > 100) {
                log.info("滤波函数花费时间为:{}毫秒......", stopWatch.getTime());
            }
        }
    }
    private boolean calcWaveScopeByPython(Integer lev) throws Exception {
            // python
            AgvModel agvModel = agvModelService.selectByType(AgvModelType.CTU_BOX_TRANSPORT_AGV.toString());    // can be optimized
            Double avoidDistance = MapDataUtils.getVehicleWaveSafeDistance(agvModel.getDiameter(), MapDataConstant.MAX_DISTANCE_BETWEEN_ADJACENT_AGV_FACTOR);
@@ -151,65 +155,75 @@
            if (exitCode != 0) {
                log.error("Python script exited with error code: {}", exitCode);
                log.error("python error:{}", builder.toString());
                return;
            return false;
            }
            reader.close();
            if (builder.length() <= 0) {
                return;
            return false;
            }
            String result = builder.toString();
            if (!Cools.isEmpty(result)) {
        if (Cools.isEmpty(result)) {
            return false;
        }
                if (!"1".equals(result)) {
                    log.error("Failed to call python");
            return false;
                }
        return true;
            }
//            log.error("python finish {}", System.currentTimeMillis() - startTime);
    private boolean calcWaveScopeByJava(Integer lev) throws Exception {
        AgvModel agvModel = agvModelService.selectByType(AgvModelType.CTU_BOX_TRANSPORT_AGV.toString());    // can be optimized
        Double avoidDistance = MapDataUtils.getVehicleWaveSafeDistance(agvModel.getDiameter(), MapDataConstant.MAX_DISTANCE_BETWEEN_ADJACENT_AGV_FACTOR);
            // java
//            String[][] codeMatrix = mapDataDispatcher.getCodeMatrix(lev);
//            String[][] waveMatrix = mapDataDispatcher.initWaveMatrix(lev);
//
//            // lock path
//            DynamicNode[][] dynamicMatrix = mapDataDispatcher.getDynamicMatrix(lev);
//            for (int i = 0; i < dynamicMatrix.length; i++) {
//                for (int j = 0; j < dynamicMatrix[i].length; j++) {
//                    DynamicNode dynamicNode = dynamicMatrix[i][j];
//                    String vehicle = dynamicNode.getVehicle();
//                    if (!DynamicNodeType.ACCESS.val.equals(vehicle) && !DynamicNodeType.BLOCK.val.equals(vehicle)) {
//                        AgvModel agvModel = agvModelService.getById(agvService.selectByUuid(vehicle).getAgvModel());    // can be optimized
//
//                        Double avoidDistance = MapDataUtils.getVehicleWaveSafeDistance(agvModel.getDiameter(), MapDataConstant.MAX_DISTANCE_BETWEEN_ADJACENT_AGV_FACTOR);
//                        List<NavigateNode> includeList = mapService.getWaveScopeByCode(lev, codeMatrix[i][j], avoidDistance);
//
//                        for (NavigateNode navigateNode : includeList) {
//                            String waveNode = waveMatrix[navigateNode.getX()][navigateNode.getY()]; // overlay
//                            waveMatrix[navigateNode.getX()][navigateNode.getY()] = MapDataUtils.generateWaveNode(waveNode, vehicle);
//                        }
//                    }
//                }
//            }
//
////            mapDataDispatcher.printMatrix(waveMatrix);
//            mapDataDispatcher.setWaveMatrix(lev, waveMatrix);
        String[][] codeMatrix = mapDataDispatcher.getCodeMatrix(lev);
        String[][] waveMatrix = mapDataDispatcher.initWaveMatrix(lev);
        // lock path
        DynamicNode[][] dynamicMatrix = mapDataDispatcher.getDynamicMatrix(lev);
        for (int i = 0; i < dynamicMatrix.length; i++) {
            for (int j = 0; j < dynamicMatrix[i].length; j++) {
                DynamicNode dynamicNode = dynamicMatrix[i][j];
                String vehicle = dynamicNode.getVehicle();
                if (!DynamicNodeType.ACCESS.val.equals(vehicle) && !DynamicNodeType.BLOCK.val.equals(vehicle)) {
                    List<NavigateNode> includeList = mapService.getWaveScopeByCode(lev, codeMatrix[i][j], avoidDistance);
                    for (NavigateNode navigateNode : includeList) {
                        String waveNode = waveMatrix[navigateNode.getX()][navigateNode.getY()]; // overlay
                        waveMatrix[navigateNode.getX()][navigateNode.getY()] = MapDataUtils.generateWaveNode(waveNode, vehicle);
                    }
                }
            }
        }
//            mapDataDispatcher.printMatrix(waveMatrix);
        mapDataDispatcher.setWaveMatrix(lev, waveMatrix);
        return true;
    }
    private File loadPythonFile() {
        File scriptFile = null;
        try {
            Resource resource = new ClassPathResource("agv.py");
            InputStream is = resource.getInputStream();
            scriptFile = File.createTempFile("agv", ".py");
            scriptFile.deleteOnExit();
            Files.copy(is, scriptFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
            boolean executable = scriptFile.setExecutable(true);
        } catch (Exception e) {
            log.error(this.getClass().getSimpleName(), e);
        } finally {
            if (lockAcquired) {
                lock.unlock();
            throw new RuntimeException(e);
            }
            stopWatch.stop();
            if (stopWatch.getTime() > 100) {
                log.info("滤波函数花费时间为:{}毫秒......", stopWatch.getTime());
            }
        }
        return scriptFile;
    }
    public void syncWaveBySingleVeh(String agvNo, String codeData) {
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MapService.java
@@ -267,7 +267,7 @@
        NavigateNode originNode = new NavigateNode(codeMatrixIdx[0], codeMatrixIdx[1], code);
        List<NavigateNode> includeList = new ArrayList<>();
        List<NavigateNode> existNodes = new ArrayList<>();
        Set<NavigateNode> existNodes = new HashSet<>();
        includeList.add(originNode);
        existNodes.add(originNode);
@@ -279,7 +279,7 @@
    public void spreadWaveNode(NavigateNode originNode, NavigateNode currNode
            , String[][] codeMatrix, String[][] cdaMatrix, Double radiusLen
            , List<NavigateNode> includeList, List<NavigateNode> existNodes) {
            , List<NavigateNode> includeList, Set<NavigateNode> existNodes) {
        int x = currNode.getX();
        int y = currNode.getY();
@@ -291,7 +291,7 @@
    public void extendNeighborNodes(NavigateNode originNode, NavigateNode nextNode
            , String[][] codeMatrix, String[][] cdaMatrix, Double radiusLen
            , List<NavigateNode> includeList, List<NavigateNode> existNodes) {
            , List<NavigateNode> includeList, Set<NavigateNode> existNodes) {
        int x = nextNode.getX();
        int y = nextNode.getY();
@@ -301,48 +301,26 @@
            return;
        }
        if (this.isExist(nextNode, existNodes)) {
        if (existNodes.contains(nextNode)) {
            return;
        }
        existNodes.add(nextNode);
        String nextNodeCodeData = codeMatrix[x][y];
        if (nextNodeCodeData.equals(CodeNodeType.NONE.val)) {
            this.spreadWaveNode(originNode, nextNode, codeMatrix, cdaMatrix, radiusLen, includeList, existNodes);
        } else {
            List<Double> o1Cda = MapDataUtils.parseCdaNode(cdaMatrix[originNode.getX()][originNode.getY()]);
            List<Double> o2Cda = MapDataUtils.parseCdaNode(cdaMatrix[nextNode.getX()][nextNode.getY()]);
        List<Double> o2Cda = MapDataUtils.parseCdaNode(cdaMatrix[x][y]);
//            if (Math.pow(o1.getX() - o2.getX(), 2) + Math.pow(o1.getY() - o2.getY(), 2) <= Math.pow(radiusLen, 2)) {
            if (Math.pow(o1Cda.get(0) - o2Cda.get(0), 2) + Math.pow(o1Cda.get(1) - o2Cda.get(1), 2) <= Math.pow(radiusLen, 2)) {
                nextNode.setCodeData(nextNodeCodeData);
            nextNode.setCodeData(codeMatrix[x][y]);
            if (!nextNode.getCodeData().equals(CodeNodeType.NONE.val)) {
                includeList.add(nextNode);
            }
                this.spreadWaveNode(originNode, nextNode, codeMatrix, cdaMatrix, radiusLen, includeList, existNodes);
            }
        }
    }
    private boolean isExist(NavigateNode node, List<NavigateNode> existNodes) {
        for (NavigateNode existNode : existNodes) {
            if (this.isSame(node, existNode)) {
                return true;
            }
        }
        return false;
    }
    private boolean isSame(NavigateNode o1, NavigateNode o2) {
        if (Cools.isEmpty(o1, o2)) {
            return false;
        }
        return o1.getX() == o2.getX() && o1.getY() == o2.getY();
    }
    // v2 BFS ------------------------------------------------------------------------------
@@ -394,7 +372,7 @@
        }
        // If the node has already been visited, skip it
        if (this.isExist0(nextNode, visited)) {
        if (visited.contains(nextNode)) {
            return;
        }
@@ -422,15 +400,6 @@
                queue.offer(nextNode);
            }
        }
    }
    private boolean isExist0(NavigateNode node, Set<NavigateNode> existNodes) {
        for (NavigateNode existNode : existNodes) {
            if (this.isSame(node, existNode)) {
                return true;
            }
        }
        return false;
    }
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/RetreatNavigateService.java
@@ -23,6 +23,7 @@
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
/**
@@ -95,7 +96,7 @@
            List<RetreatNavigateNode> enableNodes = new ArrayList<>();
            ArrayList<RetreatNavigateNode> neighborNodes = this.getNeighborNodes(currentNode, existNodes, codeMatrix);
            List<RetreatNavigateNode> neighborNodes = this.getNeighborNodes(currentNode, existNodes, codeMatrix);
            boolean pointOfTurn = neighborNodes.size() >= 2;
            label: for (RetreatNavigateNode node : neighborNodes) {
                if (node.getCodeData().equals(breakPoint)) { continue; }
@@ -212,7 +213,7 @@
                RetreatNavigateNode currentNode = openQueue.poll();
                List<RetreatNavigateNode> enableNodes = new ArrayList<>();
                ArrayList<RetreatNavigateNode> neighborNodes = this.getNeighborNodes(currentNode, existNodes, codeMatrix);
                List<RetreatNavigateNode> neighborNodes = this.getNeighborNodes(currentNode, existNodes, codeMatrix);
                // 第一步:获取有效转弯点
                if (null == availablePointOfTurn) {
@@ -319,12 +320,12 @@
    }
    // 获取四周节点
    private ArrayList<RetreatNavigateNode> getNeighborNodes(RetreatNavigateNode currentNode, Set<RetreatNavigateNode> existNodes, String[][] codeMatrix) {
    private List<RetreatNavigateNode> getNeighborNodes(RetreatNavigateNode currentNode, Set<RetreatNavigateNode> existNodes, String[][] codeMatrix) {
        int x = currentNode.getX();
        int y = currentNode.getY();
        ArrayList<RetreatNavigateNode> neighbourNodes = new ArrayList<>();
        List<RetreatNavigateNode> neighbourNodes = new CopyOnWriteArrayList<>();
        List<RetreatNavigateNode> possibleNodes = Arrays.asList(
                new RetreatNavigateNode(x, y + 1), // right
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/TrafficService.java
@@ -126,8 +126,11 @@
            // execute -----------------------------------------------
            //        ArrayList<List<TaskPosDto>> list = JSON.parseObject(travel.getTaskContent(), new TypeReference<ArrayList<List<TaskPosDto>>>() {});
            // get path list
            avoidWaveCalculator.calcWaveScope();    // * sync wave scope
            // * sync wave scope
            if (!avoidWaveCalculator.calcWaveScope()) {
                log.error("failed to calculate avoid wave matrix ...");
                return;
            }
            // checkout path
            Code startCode = codeService.getById(agvDetail.getRecentCode());
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/astart/AStarNavigateService.java
@@ -1,6 +1,7 @@
package com.zy.acs.manager.core.service.astart;
import com.zy.acs.common.constant.RedisConstant;
import com.zy.acs.common.utils.GsonUtils;
import com.zy.acs.common.utils.RedisSupport;
import com.zy.acs.framework.common.Cools;
import com.zy.acs.manager.common.utils.MapDataUtils;
@@ -11,14 +12,17 @@
import com.zy.acs.manager.manager.entity.Segment;
import com.zy.acs.manager.manager.service.JamService;
import com.zy.acs.manager.system.service.ConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
/**
 * Created by vincent on 6/12/2024
 */
@Slf4j
@Service
public class AStarNavigateService {
@@ -58,9 +62,10 @@
            // 取优先队列顶部元素并且把这个元素从Open表中删除,取F值最小的节点
            NavigateNode currentNode = openQueue.poll();
            ArrayList<NavigateNode> neighbourNodes = this.getNeighborNodes(currentNode, mapMatrix, existNodes);
            List<NavigateNode> neighbourNodes = this.getNeighborNodes(currentNode, mapMatrix, existNodes);
            for (NavigateNode node : neighbourNodes) {
                node.setCodeData(codeMatrix[node.getX()][node.getY()]);
                boolean isEndNode = node.getX() == end.getX() && node.getY() == end.getY();
                int weight = 0;
@@ -171,11 +176,11 @@
    }
    // 获取四周节点
    private ArrayList<NavigateNode> getNeighborNodes(NavigateNode currentNode, int[][] mapMatrix, Set<NavigateNode> existNodes) {
    private List<NavigateNode> getNeighborNodes(NavigateNode currentNode, int[][] mapMatrix, Set<NavigateNode> existNodes) {
        int x = currentNode.getX();
        int y = currentNode.getY();
        ArrayList<NavigateNode> neighbourNodes = new ArrayList<>();
        List<NavigateNode> neighbourNodes = new CopyOnWriteArrayList<>();
        List<NavigateNode> possibleNodes = Arrays.asList(
                new NavigateNode(x, y + 1), // right
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/astart/MapDataDispatcher.java
@@ -3,6 +3,7 @@
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zy.acs.common.constant.RedisConstant;
import com.zy.acs.common.utils.GsonUtils;
import com.zy.acs.common.utils.RedisSupport;
import com.zy.acs.framework.common.Cools;
import com.zy.acs.framework.exception.CoolException;
@@ -28,6 +29,9 @@
    public static final Integer MAP_DEFAULT_LEV = 1;
    private final RedisSupport redis = RedisSupport.defaultRedisSupport;
    List<Double> xIdxList;
    List<Double> yIdxList;
    private String[][] codeMatrix;
@@ -193,7 +197,6 @@
    }
    public String[][] initWaveMatrix(Integer lev) {
        log.info("There is initializing Wave Matrix......");
        lev = Optional.ofNullable(lev).orElse(MAP_DEFAULT_LEV);
        String[][] codeMatrix = getCodeMatrix(lev);
@@ -236,13 +239,20 @@
        log.info("There is initializing Cda Matrix......");
        lev = Optional.ofNullable(lev).orElse(MAP_DEFAULT_LEV);
        if (Cools.isEmpty(xIdxList, yIdxList)) {
            this.initCodeMatrix(lev);
        }
        String[][] codeMatrix = getCodeMatrix(lev);
        String[][] cdaMatrix = new String[codeMatrix.length][codeMatrix[0].length];
        for (int i = 0; i < codeMatrix.length; i++) {
            for (int j = 0; j < codeMatrix[i].length; j++) {
                if (CodeNodeType.NONE.val.equals(codeMatrix[i][j])) {
                    cdaMatrix[i][j] = CdaNodeType.DISABLE.val;
                    List<Double> cdaArr = new ArrayList<>();
                    cdaArr.add(xIdxList.get(j));
                    cdaArr.add(yIdxList.get(i));
                    cdaMatrix[i][j] = JSON.toJSONString(cdaArr);
                } else {
                    Code currCode = codeService.selectByData(codeMatrix[i][j]);
                    if (null != currCode) {
@@ -385,13 +395,9 @@
                .orderByAsc(Code::getY)
                .orderByAsc(Code::getX)
        );
//        int xCount = codeService.selectDistinctCountFromX();
//        int yCount = codeService.selectDistinctCountFromY();
//        // [][] 第一个是排的数量 第二个是列的数量
//        String[][] codeMatrix = new String[yCount][xCount];
        List<Double> xIdxList = new ArrayList<>();
        List<Double> yIdxList = new ArrayList<>();
        xIdxList = new ArrayList<>();
        yIdxList = new ArrayList<>();
        for (Code code : codeList) {
            Double x = code.getX();
            Double y = code.getY();
@@ -409,24 +415,9 @@
        // [][] 第一个是排的数量 第二个是列的数量
        String[][] codeMatrix = new String[yIdxList.size()][xIdxList.size()];
        int idxX = -1;
        int idxY = -1;
        double lastX = -1;
        double lastY = -1;
        for (Code code : codeList) {
            Double x = code.getX();
            Double y = code.getY();
//            if (y != lastY) {
//                idxY ++;
//                idxX = 0;
//                lastY = y;
//                lastX = x;
//            }
//            if (x != lastX) {
//                idxX++;
//                lastX = x;
//            }
//            codeMatrix[idxY][idxX] = code.getData();
            codeMatrix[yIdxList.indexOf(y)][xIdxList.indexOf(x)] = code.getData();
        }
zy-acs-manager/src/main/resources/agv.py
@@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-
import ast
import multiprocessing
import sys