package com.zy.acs.manager.core.service.astart; 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.RedisSupport; import com.zy.acs.framework.common.Cools; import com.zy.acs.framework.exception.CoolException; import com.zy.acs.manager.core.service.astart.domain.DynamicNode; import com.zy.acs.manager.core.utils.RouteGenerator; import com.zy.acs.manager.manager.entity.Code; import com.zy.acs.manager.manager.entity.Route; import com.zy.acs.manager.manager.enums.StatusType; import com.zy.acs.manager.manager.service.CodeService; import com.zy.acs.manager.manager.service.RouteService; import lombok.extern.slf4j.Slf4j; import java.util.*; /** * Created by vincent on 6/6/2024 */ @Slf4j public class MapDataDispatcher { public static final Integer MAP_DEFAULT_LEV = 1; private final RedisSupport redis = RedisSupport.defaultRedisSupport; List xIdxList; List yIdxList; private String[][] codeMatrix; private int[][] mapMatrix; private int[][] turnMatrix; private String[][] cdaMatrix; public Map routeCdaMap = new HashMap<>(); private final CodeService codeService; private final RouteService routeService; public MapDataDispatcher(CodeService codeService, RouteService routeService) { this.codeService = codeService; this.routeService = routeService; } public String[][] getWaveMatrix(Integer lev) { lev = Optional.ofNullable(lev).orElse(MAP_DEFAULT_LEV); String[][] waveMatrix; String waveMatrixStr = redis.getValue(RedisConstant.AGV_MAP_ASTAR_WAVE_FLAG, String.valueOf(lev)); if (Cools.isEmpty(waveMatrixStr)) { waveMatrix = this.initWaveMatrix(lev); setWaveMatrix(lev, waveMatrix); } else { waveMatrix = JSON.parseObject(waveMatrixStr, String[][].class); } if (null == waveMatrix) { throw new CoolException("the floor " + lev + " cannot found wave matrix !!!"); } return waveMatrix; } public void setWaveMatrix(Integer lev, String[][] waveMatrix) { redis.setValue(RedisConstant.AGV_MAP_ASTAR_WAVE_FLAG, String.valueOf(lev), JSON.toJSONString(waveMatrix)); } public DynamicNode[][] getDynamicMatrix(Integer lev) { lev = Optional.ofNullable(lev).orElse(MAP_DEFAULT_LEV); DynamicNode[][] dynamicMatrix; String dynamicMatrixStr = redis.getValue(RedisConstant.AGV_MAP_ASTAR_DYNAMIC_FLAG, String.valueOf(lev)); if (Cools.isEmpty(dynamicMatrixStr)) { dynamicMatrix = this.initDynamicMatrix(lev); setDynamicMatrix(lev, dynamicMatrix); } else { dynamicMatrix = JSON.parseObject(dynamicMatrixStr, DynamicNode[][].class); } if (null == dynamicMatrix) { throw new CoolException("the floor " + lev + " cannot found dynamic matrix !!!"); } return dynamicMatrix; } public void setDynamicMatrix(Integer lev, DynamicNode[][] dynamicMatrix) { redis.setValue(RedisConstant.AGV_MAP_ASTAR_DYNAMIC_FLAG, String.valueOf(lev), JSON.toJSONString(dynamicMatrix)); } public String[][] getCdaMatrix(Integer lev) { lev = Optional.ofNullable(lev).orElse(MAP_DEFAULT_LEV); // redis if (null == this.cdaMatrix) { String cdaMatrixStr = redis.getValue(RedisConstant.AGV_MAP_ASTAR_CDA_FLAG, String.valueOf(lev)); if (!Cools.isEmpty(cdaMatrixStr)) { this.cdaMatrix = JSON.parseObject(cdaMatrixStr, String[][].class); } } // init if (null == this.cdaMatrix) { String[][] initCdaMatrix = this.initCdaMatrix(lev); setCdaMatrix(lev, initCdaMatrix); } // valid if (null == this.cdaMatrix) { throw new CoolException("the floor " + lev + " cannot found cda matrix !!!"); } return this.cdaMatrix; } public void setCdaMatrix(Integer lev, String[][] cdaMatrix) { redis.setValue(RedisConstant.AGV_MAP_ASTAR_CDA_FLAG, String.valueOf(lev), JSON.toJSONString(cdaMatrix)); this.cdaMatrix = cdaMatrix; } public int[][] getTurnMatrix(Integer lev) { lev = Optional.ofNullable(lev).orElse(MAP_DEFAULT_LEV); // redis if (null == this.turnMatrix) { String turnMatrixStr = redis.getValue(RedisConstant.AGV_MAP_ASTAR_TURN_FLAG, String.valueOf(lev)); if (!Cools.isEmpty(turnMatrixStr)) { this.turnMatrix = JSON.parseObject(turnMatrixStr, int[][].class); } } // init if (null == this.turnMatrix) { int[][] initTurnMatrix = this.initTurnMatrix(lev); setTurnMatrix(lev, initTurnMatrix); } // valid if (null == this.turnMatrix) { throw new CoolException("the floor " + lev + " cannot found turn matrix !!!"); } return this.turnMatrix; } public void setTurnMatrix(Integer lev, int[][] turnMatrix) { redis.setValue(RedisConstant.AGV_MAP_ASTAR_TURN_FLAG, String.valueOf(lev), JSON.toJSONString(turnMatrix)); this.turnMatrix = turnMatrix; } public int[][] getMapMatrix(Integer lev, List lockNodes) { lev = Optional.ofNullable(lev).orElse(MAP_DEFAULT_LEV); // redis if (null == this.mapMatrix) { String mapMatrixStr = redis.getValue(RedisConstant.AGV_MAP_ASTAR_FLAG, String.valueOf(lev)); if (!Cools.isEmpty(mapMatrixStr)) { this.mapMatrix = JSON.parseObject(mapMatrixStr, int[][].class); } } // init if (null == this.mapMatrix) { int[][] initMapMatrix = this.initMapMatrix(lev); setMapMatrix(lev, initMapMatrix); } // valid if (null == this.mapMatrix) { throw new CoolException("the floor " + lev + " cannot found map matrix !!!"); } return this.mapMatrix; } public void setMapMatrix(Integer lev, int[][] mapMatrix) { redis.setValue(RedisConstant.AGV_MAP_ASTAR_FLAG, String.valueOf(lev), JSON.toJSONString(mapMatrix)); this.mapMatrix = mapMatrix; } public String[][] getCodeMatrix(Integer lev) { lev = Optional.ofNullable(lev).orElse(MAP_DEFAULT_LEV); // redis if (null == this.codeMatrix) { String codeMatrixStr = redis.getValue(RedisConstant.AGV_MAP_ASTAR_CODE_FLAG, String.valueOf(lev)); if (!Cools.isEmpty(codeMatrixStr)) { this.codeMatrix = JSON.parseObject(codeMatrixStr, String[][].class); } } // init if (null == this.codeMatrix) { String[][] initCodeMatrix = this.initCodeMatrix(lev); setCodeMatrix(lev, initCodeMatrix); } // valid if (null == this.codeMatrix) { throw new CoolException("the floor " + lev + " cannot found code matrix !!!"); } return this.codeMatrix; } public void setCodeMatrix(Integer lev, String[][] codeMatrix) { redis.setValue(RedisConstant.AGV_MAP_ASTAR_CODE_FLAG, String.valueOf(lev), JSON.toJSONString(codeMatrix)); this.codeMatrix = codeMatrix; } public String[][] initWaveMatrix(Integer lev) { lev = Optional.ofNullable(lev).orElse(MAP_DEFAULT_LEV); String[][] codeMatrix = getCodeMatrix(lev); String[][] waveMatrix = 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])) { waveMatrix[i][j] = WaveNodeType.DISABLE.val; } else { waveMatrix[i][j] = WaveNodeType.ENABLE.val; } } } return waveMatrix; } public synchronized DynamicNode[][] initDynamicMatrix(Integer lev) { log.info("There is initializing Dynamic Matrix......"); lev = Optional.ofNullable(lev).orElse(MAP_DEFAULT_LEV); String[][] codeMatrix = getCodeMatrix(lev); DynamicNode[][] dynamicMatrix = new DynamicNode[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])) { dynamicMatrix[i][j] = new DynamicNode(DynamicNodeType.BLOCK.val); } else { dynamicMatrix[i][j] = new DynamicNode(DynamicNodeType.ACCESS.val); } } } return dynamicMatrix; } public synchronized String[][] initCdaMatrix(Integer lev) { 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])) { List cdaArr = new ArrayList<>(); cdaArr.add(xIdxList.get(j)); cdaArr.add(yIdxList.get(i)); cdaMatrix[i][j] = JSON.toJSONString(cdaArr); } else { Code currCode = codeService.getCacheByData(codeMatrix[i][j]); if (null != currCode) { List cdaArr = new ArrayList<>(); cdaArr.add(currCode.getX()); cdaArr.add(currCode.getY()); cdaMatrix[i][j] = JSON.toJSONString(cdaArr); } else { cdaMatrix[i][j] = CdaNodeType.EMPTY.val; } } } } return cdaMatrix; } public synchronized int[][] initTurnMatrix(Integer lev) { log.info("There is initializing Turn Matrix......"); lev = Optional.ofNullable(lev).orElse(MAP_DEFAULT_LEV); String[][] codeMatrix = getCodeMatrix(lev); int[][] turnMatrix = new int[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])) { turnMatrix[i][j] = TurnNodeType.NONE.val; } else { Code currCode = codeService.getCacheByData(codeMatrix[i][j]); List neighborCodeList = routeService.findCodeDataOfSingle(currCode.getId()); switch (neighborCodeList.size()) { case 0: case 1: turnMatrix[i][j] = TurnNodeType.STRAIGHT.val; break; case 2: String firstCode = neighborCodeList.get(0); assert !Cools.isEmpty(firstCode); String secondCode = neighborCodeList.get(1); assert !Cools.isEmpty(secondCode); int[] firstIdx = this.getCodeMatrixIdx(lev, firstCode); int[] secondIdx = this.getCodeMatrixIdx(lev, secondCode); if (firstIdx[0] != secondIdx[0] && firstIdx[1] != secondIdx[1]) { turnMatrix[i][j] = TurnNodeType.TURN.val; } else { turnMatrix[i][j] = TurnNodeType.STRAIGHT.val; } break; default: turnMatrix[i][j] = TurnNodeType.TURN.val; break; } } } } // System.out.println("===================================================="); // printMatrix(turnMatrix); return turnMatrix; } public synchronized int[][] initMapMatrix(Integer lev) { log.info("There is initializing Map Matrix......"); lev = Optional.ofNullable(lev).orElse(MAP_DEFAULT_LEV); String[][] codeMatrix = getCodeMatrix(lev); int[][] mapMatrix = new int[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])) { mapMatrix[i][j] = MapNodeType.DISABLE.val; } else { mapMatrix[i][j] = MapNodeType.ENABLE.val; } } } // printMatrix(mapMatrix); return mapMatrix; } public boolean validRouteCdaKey(String routeCdaKey) { if (Cools.isEmpty(routeCdaKey)) { return false; } Boolean result = this.routeCdaMap.get(routeCdaKey); if (null == result) { return false; } return result; } public synchronized void initRouteMap(Integer lev) { log.info("There is initializing Route Map......"); lev = Optional.ofNullable(lev).orElse(MAP_DEFAULT_LEV); Set routeKeys = redis.getMapKeys(RedisConstant.AGV_MAP_ROUTE_HASH_FLAG); Set routeCdaKeys = redis.getMapKeys(RedisConstant.AGV_MAP_ROUTE_CDA_HASH_FLAG); List routeList = routeService.list(new LambdaQueryWrapper().eq(Route::getStatus, StatusType.ENABLE.val)); if (routeKeys.size() == routeList.size() && routeKeys.size() == routeCdaKeys.size()) { for (String routeCdaKey : routeCdaKeys) { this.routeCdaMap.put(routeCdaKey, Boolean.TRUE); } return; } for (Route route : routeList) { Code startCode = codeService.getById(route.getStartCode()); int[] startCodeIdx = getCodeMatrixIdx(lev, startCode.getData()); Code endCode = codeService.getById(route.getEndCode()); int[] codeMatrixIdx = getCodeMatrixIdx(lev, endCode.getData()); String routeKey = RouteGenerator.generateRouteKey(startCode.getData(), endCode.getData()); if (Cools.isEmpty(routeKey)) { continue; } redis.setMap(RedisConstant.AGV_MAP_ROUTE_HASH_FLAG, routeKey, Boolean.TRUE); String routeCdaKey = RouteGenerator.generateRouteCdaKey(startCodeIdx, codeMatrixIdx); if (Cools.isEmpty(routeCdaKey)) { continue; } redis.setMap(RedisConstant.AGV_MAP_ROUTE_CDA_HASH_FLAG, routeCdaKey, Boolean.TRUE); this.routeCdaMap.put(routeCdaKey, Boolean.TRUE); } } public synchronized String[][] initCodeMatrix(Integer lev) { log.info("There is initializing Code Matrix......"); lev = Optional.ofNullable(lev).orElse(MAP_DEFAULT_LEV); List codeList = codeService.list(new LambdaQueryWrapper() .eq(Code::getStatus, 1) .orderByAsc(Code::getY) .orderByAsc(Code::getX) ); xIdxList = new ArrayList<>(); yIdxList = new ArrayList<>(); for (Code code : codeList) { Double x = code.getX(); Double y = code.getY(); if (null == x || null == y) { continue; } if (!xIdxList.contains(x)) { xIdxList.add(x); } if (!yIdxList.contains(y)) { yIdxList.add(y); } } xIdxList.sort((o1, o2) -> (int) ((o1 * 100) - (o2 * 100))); yIdxList.sort((o1, o2) -> (int) ((o1 * 100) - (o2 * 100))); // [][] 第一个是排的数量 第二个是列的数量 String[][] codeMatrix = new String[yIdxList.size()][xIdxList.size()]; for (Code code : codeList) { Double x = code.getX(); Double y = code.getY(); codeMatrix[yIdxList.indexOf(y)][xIdxList.indexOf(x)] = code.getData(); } for (int i = 0; i < codeMatrix.length; i++) { for (int j = 0; j < codeMatrix[i].length; j++) { if (codeMatrix[i][j] == null) { codeMatrix[i][j] = CodeNodeType.NONE.val; } } } printMatrix(codeMatrix); return codeMatrix; } public int[] getCodeMatrixIdx(Integer lev, String codeData) { if (Cools.isEmpty(codeData)) { return null; } lev = Optional.ofNullable(lev).orElse(MAP_DEFAULT_LEV); String[][] codeMatrix = this.getCodeMatrix(lev); for (int i = 0; i < codeMatrix.length; i++) { for (int j = 0; j < codeMatrix[i].length; j++) { if (codeMatrix[i][j].equals(codeData)) { return new int[]{i, j}; } } } return null; } public List getCodeMatrixIdxList(Integer lev, List codeDataList) { if (Cools.isEmpty(codeDataList)) { return new ArrayList<>(); } lev = Optional.ofNullable(lev).orElse(MAP_DEFAULT_LEV); String[][] codeMatrix = this.getCodeMatrix(lev); List codeMatrixIdxList = new ArrayList<>(); Map map = new HashMap<>(); Set codeDataSet = new HashSet<>(codeDataList); for (int i = 0; i < codeMatrix.length; i++) { for (int j = 0; j < codeMatrix[i].length; j++) { String codeData = codeMatrix[i][j]; if (codeDataSet.contains(codeData)) { map.put(codeData, new int[]{i, j}); } } } for (String codeData : codeDataList) { int[] codeMatrixIdx = map.get(codeData); if (codeMatrixIdx != null) { codeMatrixIdxList.add(codeMatrixIdx); } } return codeMatrixIdxList; } public void modifyDynamicMatrix(Integer lev, List codeIdxList, String vehicle) { this.modifyDynamicMatrix(lev, codeIdxList, vehicle, false); } public synchronized void modifyDynamicMatrix(Integer lev, List codeIdxList, String vehicle, boolean reset) { if (Cools.isEmpty(vehicle)) { return; } lev = Optional.ofNullable(lev).orElse(MAP_DEFAULT_LEV); DynamicNode[][] dynamicMatrix = getDynamicMatrix(lev); if (!reset) { // long time = System.currentTimeMillis() / 1000; int serial = 1; for (int[] codeMatrixIdx : codeIdxList) { dynamicMatrix[codeMatrixIdx[0]][codeMatrixIdx[1]] = new DynamicNode(vehicle, serial); serial++; } } else { for (int i = 0; i < dynamicMatrix.length; i++) { for (int j = 0; j < dynamicMatrix[i].length; j++) { DynamicNode dynamicNode = dynamicMatrix[i][j]; if (vehicle.equals(dynamicNode.getVehicle())) { dynamicMatrix[i][j] = new DynamicNode(DynamicNodeType.ACCESS.val); } } } } setDynamicMatrix(lev, dynamicMatrix); } public void clearDynamicMatrixByCodeList(Integer lev, List codeIdxList) { this.modifyDynamicMatrix(lev, codeIdxList, DynamicNodeType.ACCESS.val); } public int[][] filterMapData(int[][] mapMatrix, Integer lev, List lockNodes) { String[][] codeMatrix = getCodeMatrix(lev); for (int i = 0; i < codeMatrix.length; i++) { for (int j = 0; j < codeMatrix[i].length; j++) { String code = codeMatrix[i][j]; if (lockNodes.contains(code)) { mapMatrix[i][j] = MapNodeType.LOCKED.val; } } } return mapMatrix; } public void printMatrix(T[][] matrix) { for (T[] list : matrix) { for (T t : list) { System.out.format("%10s", t); } System.out.println(); } } public void printMatrix(int[][] matrix) { for (int[] list : matrix) { for (int t : list) { System.out.format("%10s", t); } System.out.println(); } } }