| | |
| | | package com.zy.core.thread.impl; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.core.common.SpringUtils; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import com.zy.asrs.utils.Utils; |
| | | import com.zy.common.model.NavigateNode; |
| | | import com.zy.common.model.enums.NavigationMapType; |
| | | import com.zy.common.utils.NavigatePositionConvert; |
| | | import com.zy.common.utils.NavigateUtils; |
| | | import com.zy.common.utils.RedisUtil; |
| | | import com.zy.common.utils.ShuttleOperaUtils; |
| | | import com.zy.core.News; |
| | | import com.zy.core.cache.SlaveConnection; |
| | | import com.zy.core.enums.RedisKeyType; |
| | | import com.zy.core.enums.SlaveType; |
| | | import com.zy.core.model.TrafficControlDataModel; |
| | | import com.zy.core.model.command.ShuttleAssignCommand; |
| | | import com.zy.core.model.command.ShuttleRedisCommand; |
| | | import com.zy.core.model.param.OperateTrafficControlParam; |
| | | import com.zy.core.model.protocol.ShuttleProtocol; |
| | | import com.zy.core.thread.ShuttleThread; |
| | | import com.zy.core.thread.TrafficControlThread; |
| | | import com.zy.core.utils.TrafficControlUtils; |
| | | import org.springframework.scheduling.annotation.Async; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.*; |
| | | import java.util.function.Function; |
| | | import java.util.stream.Collectors; |
| | | |
| | | public class TrafficControlImplThread implements TrafficControlThread { |
| | | |
| | | private RedisUtil redisUtil; |
| | | private boolean detecting = false; |
| | | private boolean updateDetect = false; |
| | | private Long detectTime = System.currentTimeMillis(); |
| | | private HashMap<String, Integer> deviceMap = null; |
| | | private HashMap<Integer, HashMap<String, List<Integer>>> levNodesMap = null; |
| | | |
| | | |
| | | private List<TrafficControlDataModel> applyList = new ArrayList<>(); |
| | | private HashMap<Integer,Long> shuttleReportErrorMap = new HashMap<>(); |
| | | private HashMap<Integer,Long> pathIdleShuttleMap = new HashMap<>(); |
| | | private HashMap<Integer,Long> applyRecordsMap = new HashMap<>(); |
| | | private HashMap<String, List<NavigateNode>> taskNodesMap = new HashMap<>(); |
| | | private List<TrafficControlDataModel> trafficControlDataList = new ArrayList<>(); |
| | | private List<TrafficControlDataModel> trafficControlDataListRead = new ArrayList<>(); |
| | | |
| | | public TrafficControlImplThread(RedisUtil redisUtil) { |
| | | this.redisUtil = redisUtil; |
| | |
| | | Object object = redisUtil.get(RedisKeyType.TRAFFIC_CONTROL_MAP.key); |
| | | if(object != null) { |
| | | trafficControlDataList = (List<TrafficControlDataModel>) object; |
| | | trafficControlDataListRead = trafficControlDataList.stream() |
| | | .map(model -> new TrafficControlDataModel( |
| | | model.getShuttleNo(), |
| | | model.getTaskNo(), |
| | | new ArrayList<>(model.getNodeList()), |
| | | new ArrayList<>(model.getTotalNodeList()) |
| | | )) |
| | | .collect(Collectors.toList()); |
| | | } |
| | | |
| | | // List<Integer> shuttleNoList = new ArrayList<>(); |
| | | // while (true) { |
| | | // try { |
| | | // DeviceConfigService deviceConfigService = null; |
| | | // try { |
| | | // deviceConfigService = SpringUtils.getBean(DeviceConfigService.class); |
| | | // }catch (Exception e){} |
| | | // |
| | | // if(deviceConfigService == null){ |
| | | // continue; |
| | | // } |
| | | // |
| | | // if(shuttleNoList.isEmpty()){ |
| | | // List<DeviceConfig> shuttleList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>() |
| | | // .eq("device_type", String.valueOf(SlaveType.Shuttle))); |
| | | // for (DeviceConfig deviceConfig : shuttleList) { |
| | | // shuttleNoList.add(deviceConfig.getDeviceNo()); |
| | | // } |
| | | // } |
| | | // |
| | | // if((updateDetect) || ((System.currentTimeMillis() - detectTime) > 1000 * 2)) { |
| | | // detect(shuttleNoList); |
| | | // } |
| | | // }catch (Exception e){ |
| | | // e.printStackTrace(); |
| | | // } |
| | | // } |
| | | |
| | | } |
| | | |
| | | public synchronized void detect(List<Integer> shuttleNoList) { |
| | | detecting = true; |
| | | updateDetect = false; |
| | | ObjectMapper objectMapper = null; |
| | | try { |
| | | objectMapper = SpringUtils.getBean(ObjectMapper.class); |
| | | }catch (Exception e){} |
| | | |
| | | if(objectMapper == null){ |
| | | return; |
| | | } |
| | | |
| | | HashMap<String, List<NavigateNode>> tmpTaskNodesMap = new HashMap<>(); |
| | | for (Integer shuttleNo : shuttleNoList) { |
| | | ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo); |
| | | if (shuttleThread == null) { |
| | | continue; |
| | | } |
| | | |
| | | ShuttleProtocol shuttleProtocol = shuttleThread.getStatus(); |
| | | if (shuttleProtocol == null) { |
| | | continue; |
| | | } |
| | | |
| | | if (shuttleProtocol.getTaskNo() == 0) { |
| | | continue; |
| | | } |
| | | |
| | | if (shuttleProtocol.getCurrentLocNo() == null) { |
| | | continue; |
| | | } |
| | | |
| | | int lev = Utils.getLev(shuttleProtocol.getCurrentLocNo()); |
| | | |
| | | Object obj = redisUtil.get(RedisKeyType.SHUTTLE_WORK_FLAG.key + shuttleProtocol.getTaskNo()); |
| | | if (obj == null) { |
| | | continue; |
| | | } |
| | | |
| | | ShuttleRedisCommand redisCommand = null; |
| | | while (true) { |
| | | try { |
| | | redisCommand = objectMapper.readValue(String.valueOf(obj), ShuttleRedisCommand.class); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | List<TrafficControlDataModel> allTrafficControl = getAllTrafficControl(); |
| | | //更新交管信息 |
| | | redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_MAP.key, allTrafficControl); |
| | | |
| | | if (redisCommand == null) { |
| | | continue; |
| | | } |
| | | for (TrafficControlDataModel dataModel : allTrafficControl) { |
| | | Integer shuttleNo = dataModel.getShuttleNo(); |
| | | Integer taskNo = dataModel.getTaskNo(); |
| | | |
| | | ShuttleAssignCommand assignCommand = redisCommand.getAssignCommand(); |
| | | if (assignCommand == null) { |
| | | continue; |
| | | } |
| | | |
| | | List<NavigateNode> nodeList = assignCommand.getNodesDeepCopy(); |
| | | if (nodeList == null || nodeList.isEmpty()) { |
| | | continue; |
| | | } |
| | | |
| | | tmpTaskNodesMap.put(shuttleProtocol.getTaskNo() + "-" + shuttleNo, nodeList); |
| | | } |
| | | this.taskNodesMap = tmpTaskNodesMap; |
| | | HashMap<Integer, HashMap<String, List<Integer>>> levNodesMap = calcNodeList(); |
| | | |
| | | HashMap<Integer, HashMap<String, List<Integer>>> levBlockMap = new HashMap<>(); |
| | | //过滤不需要管制节点 |
| | | for (Map.Entry<Integer, HashMap<String, List<Integer>>> entry : levNodesMap.entrySet()) { |
| | | Integer lev = entry.getKey(); |
| | | HashMap<String, List<Integer>> value = entry.getValue(); |
| | | |
| | | HashMap<String, List<Integer>> blockMap = new HashMap<>(); |
| | | for (Map.Entry<String, List<Integer>> listEntry : value.entrySet()) { |
| | | String locNo = listEntry.getKey(); |
| | | List<Integer> shuttleNos = listEntry.getValue(); |
| | | if (shuttleNos.size() <= 1) { |
| | | continue; |
| | | } |
| | | blockMap.put(locNo, shuttleNos); |
| | | } |
| | | |
| | | levBlockMap.put(lev, blockMap); |
| | | } |
| | | |
| | | //计算堵塞范围 |
| | | List<List<String>> allLocList = new ArrayList<>(); |
| | | List<List<Integer>> allDeviceNodes = new ArrayList<>(); |
| | | for (Map.Entry<Integer, HashMap<String, List<Integer>>> entry : levBlockMap.entrySet()) { |
| | | Integer lev = entry.getKey(); |
| | | HashMap<String, List<Integer>> nodes = entry.getValue(); |
| | | |
| | | Set<String> sets = new HashSet<>(); |
| | | for (Map.Entry<String, List<Integer>> val : nodes.entrySet()) { |
| | | String locNo = val.getKey(); |
| | | sets.add(locNo); |
| | | } |
| | | |
| | | List<List<String>> locList = TrafficControlUtils.groupNodes(sets); |
| | | List<List<Integer>> deviceNodes = new ArrayList<>(); |
| | | |
| | | //get devices |
| | | for (List<String> list : locList) { |
| | | List<List<Integer>> tmpDeviceNodes = new ArrayList<>(); |
| | | for (String loc : list) { |
| | | List<Integer> shuttleNos = nodes.get(loc); |
| | | if(!tmpDeviceNodes.contains(shuttleNos)) { |
| | | tmpDeviceNodes.add(shuttleNos); |
| | | Object object1 = redisUtil.get(RedisKeyType.TRAFFIC_CONTROL_SUCCESS_APPLY.key + shuttleNo + "_" + taskNo); |
| | | if(object1 == null) { |
| | | redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_SUCCESS_APPLY.key + shuttleNo + "_" + taskNo, 1, 60 * 60); |
| | | } |
| | | } |
| | | //节点并集-获取堵塞设备编号 |
| | | List<List<Integer>> deviceList = mergeConnectedComponents(tmpDeviceNodes); |
| | | deviceNodes.addAll(deviceList); |
| | | } |
| | | |
| | | allLocList.addAll(locList); |
| | | allDeviceNodes.addAll(deviceNodes); |
| | | } |
| | | |
| | | System.out.println(JSON.toJSONString(allLocList)); |
| | | System.out.println(JSON.toJSONString(allDeviceNodes)); |
| | | // //分配堵塞节点可执行设备 |
| | | // findDeviceByBlockList(allLocList, allDeviceNodes); |
| | | |
| | | detecting = false; |
| | | detectTime = System.currentTimeMillis(); |
| | | |
| | | // //发布堵塞节点可用设备编号 |
| | | // redisUtil.set(RedisKeyType.TASK_BLOCK_ENABLE_DEVICE_MAP.key, trafficControlDataList); |
| | | } |
| | | |
| | | // //分配堵塞节点可执行设备 |
| | | // public void findDeviceByBlockList(List<List<String>> allLocList, List<List<Integer>> blockNodes) { |
| | | // HashMap<String, Integer> map = new HashMap<>(); |
| | | // if (deviceMap == null) { |
| | | // Object object = redisUtil.get(RedisKeyType.TASK_BLOCK_ENABLE_DEVICE_MAP.key); |
| | | // if (object != null) { |
| | | // map = (HashMap<String, Integer>) object; |
| | | // } |
| | | // } else { |
| | | // map = deviceMap; |
| | | // } |
| | | // |
| | | // HashMap<String, Integer> newMap = new HashMap<>(); |
| | | // |
| | | // for (int i = 0; i < blockNodes.size(); i++) { |
| | | // List<Integer> blockNode = blockNodes.get(i); |
| | | // List<String> locs = allLocList.get(i); |
| | | // |
| | | // String key = JSON.toJSONString(locs); |
| | | // |
| | | // Integer value = -1; |
| | | // if (map.containsKey(key)) { |
| | | // value = map.get(key); |
| | | // map.remove(key); |
| | | // |
| | | // if (value > 0) { |
| | | // ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, value); |
| | | // if (shuttleThread == null) { |
| | | // continue; |
| | | // } |
| | | // |
| | | // ShuttleProtocol shuttleProtocol = shuttleThread.getStatus(); |
| | | // if (shuttleProtocol == null) { |
| | | // continue; |
| | | // } |
| | | // |
| | | // if (shuttleProtocol.getTaskNo() == 0) { |
| | | // value = searchDevice(locs, blockNode, newMap); |
| | | // } |
| | | // |
| | | // if (!shuttleProtocol.getTrafficControl()) { |
| | | // value = searchDevice(locs, blockNode, newMap); |
| | | // } |
| | | // }else { |
| | | // value = searchDevice(locs, blockNode, newMap); |
| | | // } |
| | | // } else { |
| | | // value = searchDevice(locs, blockNode, newMap); |
| | | // } |
| | | // newMap.put(key, value); |
| | | // } |
| | | // |
| | | // deviceMap = newMap; |
| | | // //发布堵塞节点可用设备编号 |
| | | // redisUtil.set(RedisKeyType.TASK_BLOCK_ENABLE_DEVICE_MAP.key, newMap); |
| | | // } |
| | | |
| | | public Integer searchDevice(List<String> locs, List<Integer> blockNode, HashMap<String, Integer> deviceMap) { |
| | | NavigateUtils navigateUtils = null; |
| | | try { |
| | | navigateUtils = SpringUtils.getBean(NavigateUtils.class); |
| | | }catch (Exception e){} |
| | | |
| | | if(navigateUtils == null){ |
| | | return -1; |
| | | } |
| | | |
| | | Integer value = -1; |
| | | for (Integer shuttleNo : blockNode) { |
| | | ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo); |
| | | if (shuttleThread == null) { |
| | | continue; |
| | | } |
| | | |
| | | ShuttleProtocol shuttleProtocol = shuttleThread.getStatus(); |
| | | if (shuttleProtocol == null) { |
| | | continue; |
| | | } |
| | | |
| | | if (!shuttleThread.isDeviceIdle()) { |
| | | continue; |
| | | } |
| | | |
| | | if (shuttleProtocol.getTaskNo() == 0) { |
| | | continue; |
| | | } |
| | | |
| | | if (!shuttleProtocol.getTrafficControl()) { |
| | | continue;//小车未申请交通管制 |
| | | } |
| | | |
| | | //检测小车是否已经分配 |
| | | if (deviceMap.containsValue(shuttleNo)) { |
| | | continue; |
| | | } |
| | | |
| | | List<NavigateNode> trafficControlNodes = shuttleProtocol.getTrafficControlNodes(); |
| | | List<String> trafficControlLocs = new ArrayList<>(); |
| | | for (NavigateNode node : trafficControlNodes) { |
| | | trafficControlLocs.add(Utils.getLocNo(node.getX(), node.getY(), node.getZ())); |
| | | } |
| | | |
| | | //检测当前小车节点是否匹配交通管制节点 |
| | | boolean result = false; |
| | | for (String loc : locs) { |
| | | if (trafficControlLocs.contains(loc)) { |
| | | result = true; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (!result) { |
| | | continue; |
| | | } |
| | | |
| | | //check path |
| | | String currentLocNo = shuttleProtocol.getCurrentLocNo(); |
| | | for (String loc : locs) { |
| | | if (loc.equals(currentLocNo)) { |
| | | continue; |
| | | } |
| | | List<NavigateNode> nodeList = navigateUtils.calc(currentLocNo, loc, NavigationMapType.getNormalWithDevice(), Utils.getShuttlePoints(shuttleNo, Utils.getLev(loc)), null); |
| | | if (nodeList == null) { |
| | | break; |
| | | } |
| | | } |
| | | |
| | | value = shuttleNo; |
| | | break; |
| | | } |
| | | |
| | | return value; |
| | | } |
| | | |
| | | //节点并集 |
| | | public List<List<Integer>> mergeConnectedComponents(List<List<Integer>> lists) { |
| | | // 1. 收集所有唯一元素 |
| | | Set<Integer> allElements = new HashSet<>(); |
| | | for (List<Integer> list : lists) { |
| | | allElements.addAll(list); |
| | | } |
| | | |
| | | // 2. 初始化并查集 |
| | | Map<Integer, Integer> parent = new HashMap<>(); |
| | | for (Integer element : allElements) { |
| | | parent.put(element, element); |
| | | } |
| | | |
| | | // 3. 定义查找根节点的函数(带路径压缩) |
| | | Function<Integer, Integer> find = x -> { |
| | | int root = x; |
| | | while (parent.get(root) != root) { |
| | | root = parent.get(root); |
| | | } |
| | | // 路径压缩 |
| | | int current = x; |
| | | while (parent.get(current) != root) { |
| | | int next = parent.get(current); |
| | | parent.put(current, root); |
| | | current = next; |
| | | } |
| | | return root; |
| | | }; |
| | | |
| | | // 4. 遍历每个列表并合并元素 |
| | | for (List<Integer> list : lists) { |
| | | if (list.isEmpty()) continue; |
| | | int first = list.get(0); |
| | | for (int i = 1; i < list.size(); i++) { |
| | | int a = first; |
| | | int b = list.get(i); |
| | | int rootA = find.apply(a); |
| | | int rootB = find.apply(b); |
| | | if (rootA != rootB) { |
| | | parent.put(rootB, rootA); // 合并集合 |
| | | } |
| | | Thread.sleep(200); |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | // 5. 按根节点分组 |
| | | Map<Integer, Set<Integer>> components = new HashMap<>(); |
| | | for (Integer element : allElements) { |
| | | int root = find.apply(element); |
| | | components.computeIfAbsent(root, k -> new TreeSet<>()).add(element); |
| | | } |
| | | |
| | | // 6. 转换为有序列表 |
| | | List<List<Integer>> result = new ArrayList<>(); |
| | | for (Set<Integer> set : components.values()) { |
| | | result.add(new ArrayList<>(set)); |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | private HashMap<Integer, HashMap<String, List<Integer>>> calcNodeList() { |
| | | HashMap<Integer, HashMap<String, List<Integer>>> levNodesMap = new HashMap<>(); |
| | | for (Map.Entry<String, List<NavigateNode>> entry : taskNodesMap.entrySet()) { |
| | | String key = entry.getKey(); |
| | | String[] split = key.split("-"); |
| | | Integer taskNo = Integer.parseInt(split[0]); |
| | | Integer shuttleNo = Integer.parseInt(split[1]); |
| | | |
| | | List<NavigateNode> nodeList = entry.getValue(); |
| | | NavigateNode node1 = nodeList.get(0); |
| | | int lev = node1.getZ(); |
| | | |
| | | HashMap<String, List<Integer>> nodeMap = new HashMap<>(); |
| | | if(levNodesMap.containsKey(lev)) { |
| | | nodeMap = levNodesMap.get(lev); |
| | | } |
| | | |
| | | for (NavigateNode node : nodeList) { |
| | | String locNo = Utils.getLocNo(node.getX(), node.getY(), lev); |
| | | List<Integer> shuttleNos = new ArrayList<>(); |
| | | if (nodeMap.containsKey(locNo)) { |
| | | shuttleNos = nodeMap.get(locNo); |
| | | } |
| | | |
| | | if (!shuttleNos.contains(shuttleNo)) { |
| | | shuttleNos.add(shuttleNo); |
| | | } |
| | | nodeMap.put(locNo, shuttleNos); |
| | | } |
| | | levNodesMap.put(lev, nodeMap); |
| | | } |
| | | this.levNodesMap = levNodesMap; |
| | | return levNodesMap; |
| | | } |
| | | |
| | | @Override |
| | | public synchronized boolean applyTrafficControl(List<NavigateNode> totalNodeList, List<NavigateNode> nodeList, Integer shuttleNo, Integer taskNo) { |
| | | //更新交管信息 |
| | | redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_MAP.key, trafficControlDataList); |
| | | public synchronized boolean processApply(TrafficControlDataModel applyData) { |
| | | ShuttleOperaUtils shuttleOperaUtils = SpringUtils.getBean(ShuttleOperaUtils.class); |
| | | if (shuttleOperaUtils == null) { |
| | | return false; |
| | | } |
| | | |
| | | if (applyData == null) { |
| | | return false; |
| | | } |
| | | |
| | | if (applyData.getShuttleNo() == null || applyData.getTaskNo() == null || applyData.getNodeList() == null || applyData.getTotalNodeList() == null) { |
| | | return false; |
| | | } |
| | | |
| | | List<TrafficControlDataModel> allTrafficControlList = getAllTrafficControl(); |
| | | |
| | | Integer shuttleNo = applyData.getShuttleNo(); |
| | | Integer taskNo = applyData.getTaskNo(); |
| | | List<NavigateNode> nodeList = applyData.getNodeList(); |
| | | List<NavigateNode> totalNodeList = applyData.getTotalNodeList(); |
| | | |
| | | NavigateNode startNode = totalNodeList.get(0); |
| | | List<int[]> shuttlePoints = Utils.getShuttlePoints(shuttleNo, startNode.getZ()); |
| | |
| | | } |
| | | |
| | | //检测车子是否存在管制 |
| | | for (int i = 0; i < trafficControlDataList.size(); i++) { |
| | | TrafficControlDataModel controlDataModel = trafficControlDataList.get(i); |
| | | for (int i = 0; i < allTrafficControlList.size(); i++) { |
| | | TrafficControlDataModel controlDataModel = allTrafficControlList.get(i); |
| | | if(shuttleNo.equals(controlDataModel.getShuttleNo())) { |
| | | //存在管制 |
| | | if(!controlDataModel.getTaskNo().equals(taskNo)) { |
| | |
| | | } |
| | | } |
| | | |
| | | News.info("traffic running {},{}", shuttleNo, taskNo); |
| | | // News.info("traffic running {},{}", shuttleNo, taskNo); |
| | | return true;//已经管制允许执行 |
| | | } |
| | | } |
| | |
| | | //检测路径是否有小车 |
| | | for (String loc : totalLocList) { |
| | | if(shuttleLocList.contains(loc)) { |
| | | ShuttleThread pathShuttleThread = Utils.searchShuttle(loc); |
| | | if (pathShuttleThread == null) { |
| | | return false; |
| | | } |
| | | |
| | | ShuttleProtocol shuttleProtocol = pathShuttleThread.getStatus(); |
| | | if(shuttleProtocol == null) { |
| | | return false; |
| | | } |
| | | |
| | | if (pathShuttleThread.isIdle()) { |
| | | if(pathIdleShuttleMap.containsKey(shuttleProtocol.getShuttleNo())) { |
| | | Long idleTime = pathIdleShuttleMap.get(shuttleProtocol.getShuttleNo()); |
| | | if((System.currentTimeMillis() - idleTime) > 1000 * 10) { |
| | | //检测障碍物车 |
| | | boolean checkObstacle = shuttleOperaUtils.checkObstacle(shuttleProtocol.getCurrentLocNo(), new ArrayList<Integer>() {{ |
| | | add(shuttleNo); |
| | | }}); |
| | | pathIdleShuttleMap.remove(shuttleProtocol.getShuttleNo()); |
| | | } |
| | | }else { |
| | | pathIdleShuttleMap.put(shuttleProtocol.getShuttleNo(), System.currentTimeMillis()); |
| | | } |
| | | } |
| | | return false;//node has shuttle |
| | | } |
| | | } |
| | | |
| | | //检测节点是否被使用 |
| | | for (TrafficControlDataModel controlDataModel : trafficControlDataList) { |
| | | for (TrafficControlDataModel controlDataModel : allTrafficControlList) { |
| | | List<NavigateNode> list = controlDataModel.getTotalNodeList(); |
| | | for (int i = 0; i < list.size(); i++) { |
| | | NavigateNode node = list.get(i); |
| | |
| | | } |
| | | |
| | | //交管接收 |
| | | TrafficControlDataModel model = new TrafficControlDataModel(); |
| | | model.setShuttleNo(shuttleNo); |
| | | model.setTaskNo(taskNo); |
| | | model.setNodeList(nodeList); |
| | | model.setTotalNodeList(totalNodeList); |
| | | trafficControlDataList.add(model); |
| | | OperateTrafficControlParam param = new OperateTrafficControlParam(); |
| | | param.setDataModel(applyData); |
| | | param.setOperaType("add"); |
| | | operateTrafficControl(param); |
| | | |
| | | applyRecordsMap.remove(shuttleNo); |
| | | redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_SUCCESS_APPLY.key + shuttleNo + "_" + taskNo, 1, 60 * 60); |
| | | News.info("receipt traffic {},{}", shuttleNo, taskNo); |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public synchronized boolean trafficReport(List<NavigateNode> nodeList, Integer shuttleNo, Integer taskNo) { |
| | | public boolean applyTrafficControl(List<NavigateNode> totalNodeList, List<NavigateNode> nodeList, Integer shuttleNo, Integer taskNo) { |
| | | Set<String> keys = redisUtil.searchKeys(RedisKeyType.TRAFFIC_CONTROL_APPLY.key + shuttleNo + "_"); |
| | | if (!keys.isEmpty()) { |
| | | return false; |
| | | } |
| | | |
| | | TrafficControlDataModel model = new TrafficControlDataModel(); |
| | | model.setShuttleNo(shuttleNo); |
| | | model.setTaskNo(taskNo); |
| | | model.setNodeList(nodeList); |
| | | model.setTotalNodeList(totalNodeList); |
| | | redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_APPLY.key + shuttleNo + "_" + System.currentTimeMillis(), model); |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public boolean trafficReport(List<NavigateNode> nodeList, Integer shuttleNo, Integer taskNo) { |
| | | //检测车子是否存在管制 |
| | | List<TrafficControlDataModel> allTrafficControlList = getAllTrafficControl(); |
| | | for (int i = 0; i < allTrafficControlList.size(); i++) { |
| | | TrafficControlDataModel controlDataModel = allTrafficControlList.get(i); |
| | | if(shuttleNo.equals(controlDataModel.getShuttleNo())) { |
| | | if(controlDataModel.getTaskNo().equals(taskNo)) { |
| | | OperateTrafficControlParam param = new OperateTrafficControlParam(); |
| | | param.setDataModel(controlDataModel); |
| | | param.setOperaType("report"); |
| | | param.setReportNodeList(nodeList); |
| | | redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_REPORT_LIST.key + shuttleNo + "_" + System.currentTimeMillis(), param); |
| | | return true; |
| | | } |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | @Override |
| | | public synchronized boolean trafficReportError(Integer shuttleNo, Integer taskNo) { |
| | | ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo); |
| | | if (shuttleThread == null) { |
| | | return false; |
| | | } |
| | | |
| | | if(shuttleReportErrorMap.containsKey(shuttleNo)) { |
| | | Long errorTime = shuttleReportErrorMap.get(shuttleNo); |
| | | if((System.currentTimeMillis() - errorTime) > 1000 * 10) { |
| | | shuttleReportErrorMap.remove(shuttleNo); |
| | | shuttleThread.restartCalcPath(); |
| | | } |
| | | }else { |
| | | shuttleReportErrorMap.put(shuttleNo, System.currentTimeMillis()); |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public boolean cancelTrafficControl(Integer shuttleNo, Integer taskNo) { |
| | | TrafficControlDataModel dataModel = queryTrafficControl(shuttleNo, taskNo); |
| | | if (dataModel == null) { |
| | | return false; |
| | | } |
| | | |
| | | OperateTrafficControlParam param = new OperateTrafficControlParam(); |
| | | param.setDataModel(dataModel); |
| | | param.setOperaType("cancel"); |
| | | param.setForceCancel(false); |
| | | return operateTrafficControl(param); |
| | | } |
| | | |
| | | @Override |
| | | public boolean forceCancelTrafficControl(Integer shuttleNo) { |
| | | TrafficControlDataModel dataModel = queryTrafficControl(shuttleNo); |
| | | if (dataModel == null) { |
| | | return false; |
| | | } |
| | | |
| | | OperateTrafficControlParam param = new OperateTrafficControlParam(); |
| | | param.setDataModel(dataModel); |
| | | param.setOperaType("cancel"); |
| | | param.setForceCancel(true); |
| | | return operateTrafficControl(param); |
| | | } |
| | | |
| | | @Override |
| | | public TrafficControlDataModel queryTrafficControl(Integer shuttleNo, Integer taskNo) { |
| | | //检测车子是否存在管制 |
| | | List<TrafficControlDataModel> allTrafficControlList = getAllTrafficControl(); |
| | | for (int i = 0; i < allTrafficControlList.size(); i++) { |
| | | TrafficControlDataModel controlDataModel = allTrafficControlList.get(i); |
| | | if(shuttleNo.equals(controlDataModel.getShuttleNo())) { |
| | | if(controlDataModel.getTaskNo().equals(taskNo)) { |
| | | return controlDataModel; |
| | | } |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public TrafficControlDataModel queryTrafficControl(Integer shuttleNo) { |
| | | //检测车子是否存在管制 |
| | | List<TrafficControlDataModel> allTrafficControlList = getAllTrafficControl(); |
| | | for (int i = 0; i < allTrafficControlList.size(); i++) { |
| | | TrafficControlDataModel controlDataModel = allTrafficControlList.get(i); |
| | | if(shuttleNo.equals(controlDataModel.getShuttleNo())) { |
| | | return controlDataModel; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public List<TrafficControlDataModel> getAllTrafficControl() { |
| | | return trafficControlDataListRead; |
| | | } |
| | | |
| | | @Override |
| | | public synchronized boolean operateTrafficControl(OperateTrafficControlParam param) { |
| | | long startTime = System.currentTimeMillis(); |
| | | String operaType = param.getOperaType(); |
| | | News.info("Operate Traffic Control is Start " + operaType); |
| | | |
| | | boolean result = false; |
| | | if (operaType.equals("add")) { |
| | | result = addTrafficControlDataList(param); |
| | | } else if (operaType.equals("cancel")) { |
| | | result = removeTrafficControlDataList(param); |
| | | } else if (operaType.equals("report")) { |
| | | result = reportTrafficControlDataList(param); |
| | | } |
| | | |
| | | this.trafficControlDataListRead = trafficControlDataList.stream() |
| | | .map(model -> new TrafficControlDataModel( |
| | | model.getShuttleNo(), |
| | | model.getTaskNo(), |
| | | new ArrayList<>(model.getNodeList()), |
| | | new ArrayList<>(model.getTotalNodeList()) |
| | | )) |
| | | .collect(Collectors.toList()); |
| | | News.info("Operate Traffic Control is end " + (System.currentTimeMillis() - startTime) + "ms"); |
| | | return result; |
| | | } |
| | | |
| | | public synchronized boolean addTrafficControlDataList(OperateTrafficControlParam param) { |
| | | TrafficControlDataModel dataModel = param.getDataModel(); |
| | | trafficControlDataList.add(dataModel); |
| | | return true; |
| | | } |
| | | |
| | | public synchronized boolean removeTrafficControlDataList(OperateTrafficControlParam param) { |
| | | //检测车子是否存在管制 |
| | | TrafficControlDataModel dataModel = param.getDataModel(); |
| | | Boolean forceCancel = param.getForceCancel(); |
| | | |
| | | Integer shuttleNo = dataModel.getShuttleNo(); |
| | | Integer taskNo = dataModel.getTaskNo(); |
| | | |
| | | int idx = -1; |
| | | for (int i = 0; i < trafficControlDataList.size(); i++) { |
| | | TrafficControlDataModel controlDataModel = trafficControlDataList.get(i); |
| | | if(shuttleNo.equals(controlDataModel.getShuttleNo())) { |
| | | if (forceCancel) { |
| | | idx = i; |
| | | break; |
| | | }else { |
| | | if(controlDataModel.getTaskNo().equals(taskNo)) { |
| | | idx = i; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | if(idx == -1) { |
| | | return false; |
| | | } |
| | | |
| | | trafficControlDataList.remove(idx);//取消管制 |
| | | redisUtil.del(RedisKeyType.TRAFFIC_CONTROL_SUCCESS_APPLY.key + shuttleNo + "_" + taskNo); |
| | | return true; |
| | | } |
| | | |
| | | public synchronized boolean reportTrafficControlDataList(OperateTrafficControlParam param) { |
| | | //检测车子是否存在管制 |
| | | TrafficControlDataModel dataModel = param.getDataModel(); |
| | | List<NavigateNode> reportNodeList = param.getReportNodeList(); |
| | | |
| | | Integer shuttleNo = dataModel.getShuttleNo(); |
| | | Integer taskNo = dataModel.getTaskNo(); |
| | | |
| | | for (int i = 0; i < trafficControlDataList.size(); i++) { |
| | | TrafficControlDataModel controlDataModel = trafficControlDataList.get(i); |
| | | if(shuttleNo.equals(controlDataModel.getShuttleNo())) { |
| | |
| | | List<NavigateNode> totalNodeList = controlDataModel.getTotalNodeList(); |
| | | |
| | | List<String> reportList = new ArrayList<>(); |
| | | for (NavigateNode node : nodeList) { |
| | | for (NavigateNode node : reportNodeList) { |
| | | reportList.add(Utils.getLocNo(node.getX(), node.getY(), node.getZ())); |
| | | } |
| | | |
| | |
| | | |
| | | controlDataModel.setTotalNodeList(newTotalNodeList); |
| | | trafficControlDataList.set(i, controlDataModel); |
| | | shuttleReportErrorMap.remove(shuttleNo); |
| | | return true; |
| | | } |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | @Override |
| | | public synchronized boolean cancelTrafficControl(Integer shuttleNo, Integer taskNo) { |
| | | //检测车子是否存在管制 |
| | | for (int i = 0; i < trafficControlDataList.size(); i++) { |
| | | TrafficControlDataModel controlDataModel = trafficControlDataList.get(i); |
| | | if(shuttleNo.equals(controlDataModel.getShuttleNo())) { |
| | | if(controlDataModel.getTaskNo().equals(taskNo)) { |
| | | trafficControlDataList.remove(i);//取消管制 |
| | | return true; |
| | | } |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | @Override |
| | | public boolean forceCancelTrafficControl(Integer shuttleNo) { |
| | | //检测车子是否存在管制 |
| | | for (int i = 0; i < trafficControlDataList.size(); i++) { |
| | | TrafficControlDataModel controlDataModel = trafficControlDataList.get(i); |
| | | if(shuttleNo.equals(controlDataModel.getShuttleNo())) { |
| | | trafficControlDataList.remove(i);//取消管制 |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | @Override |
| | | public TrafficControlDataModel queryTrafficControl(Integer shuttleNo) { |
| | | //检测车子是否存在管制 |
| | | for (int i = 0; i < trafficControlDataList.size(); i++) { |
| | | TrafficControlDataModel controlDataModel = trafficControlDataList.get(i); |
| | | if(shuttleNo.equals(controlDataModel.getShuttleNo())) { |
| | | return controlDataModel; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public List<TrafficControlDataModel> getAllTrafficControl() { |
| | | return trafficControlDataList; |
| | | } |
| | | |
| | | @Override |