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.protocol.ShuttleProtocol; import com.zy.core.thread.ShuttleThread; import com.zy.core.thread.TrafficControlThread; import com.zy.core.utils.TrafficControlUtils; import java.io.IOException; import java.util.*; import java.util.function.Function; public class TrafficControlImplThread implements TrafficControlThread { private RedisUtil redisUtil; private List applyList = new ArrayList<>(); private HashMap shuttleReportErrorMap = new HashMap<>(); private HashMap pathIdleShuttleMap = new HashMap<>(); private HashMap applyRecordsMap = new HashMap<>(); private HashMap> taskNodesMap = new HashMap<>(); private List trafficControlDataList = new ArrayList<>(); public TrafficControlImplThread(RedisUtil redisUtil) { this.redisUtil = redisUtil; } @Override public void run() { //从缓存恢复交管信息 Object object = redisUtil.get(RedisKeyType.TRAFFIC_CONTROL_MAP.key); if(object != null) { trafficControlDataList = (List) object; } while (true) { try { if (applyList.isEmpty()) { continue; } TrafficControlDataModel dataModel = applyList.get(0); processApply(dataModel); applyList.remove(0); }catch (Exception e){ e.printStackTrace(); } } } 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; } Integer shuttleNo = applyData.getShuttleNo(); Integer taskNo = applyData.getTaskNo(); List nodeList = applyData.getNodeList(); List totalNodeList = applyData.getTotalNodeList(); //更新交管信息 redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_MAP.key, trafficControlDataList); NavigateNode startNode = totalNodeList.get(0); List shuttlePoints = Utils.getShuttlePoints(shuttleNo, startNode.getZ()); int[] currentShuttlePoint = Utils.getShuttlePoint(shuttleNo); if(currentShuttlePoint == null) { return false; } String currentShuttleLoc = Utils.getLocNo(currentShuttlePoint[0], currentShuttlePoint[1], startNode.getZ()); List shuttleLocList = new ArrayList<>(); for (int[] shuttlePoint : shuttlePoints) { String locNo = Utils.getLocNo(shuttlePoint[0], shuttlePoint[1], startNode.getZ()); shuttleLocList.add(locNo); } //检测车子是否存在管制 for (int i = 0; i < trafficControlDataList.size(); i++) { TrafficControlDataModel controlDataModel = trafficControlDataList.get(i); if(shuttleNo.equals(controlDataModel.getShuttleNo())) { //存在管制 if(!controlDataModel.getTaskNo().equals(taskNo)) { return false; } for (NavigateNode node : nodeList) { String locNo = Utils.getLocNo(node.getX(), node.getY(), node.getZ()); if(shuttleLocList.contains(locNo)) { ShuttleThread shuttleThread = Utils.searchShuttle(locNo); if(shuttleThread != null) { shuttleThread.restartCalcPath(); } } } // News.info("traffic running {},{}", shuttleNo, taskNo); return true;//已经管制允许执行 } } ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo); if (shuttleThread == null) { return false; } if (!applyRecordsMap.containsKey(shuttleNo)) { applyRecordsMap.put(shuttleNo, System.currentTimeMillis()); } Long applyRecordTime = applyRecordsMap.get(shuttleNo); if ((System.currentTimeMillis() - applyRecordTime) > 1000 * 10) { shuttleThread.restartCalcPath(); } List totalLocList = new ArrayList<>(); for (NavigateNode node : totalNodeList) { String locNo = Utils.getLocNo(node.getX(), node.getY(), node.getZ()); totalLocList.add(locNo); } //检测路径是否有小车 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() {{ add(shuttleNo); }}); pathIdleShuttleMap.remove(shuttleProtocol.getShuttleNo()); } }else { pathIdleShuttleMap.put(shuttleProtocol.getShuttleNo(), System.currentTimeMillis()); } } return false;//node has shuttle } } //检测节点是否被使用 for (TrafficControlDataModel controlDataModel : trafficControlDataList) { List list = controlDataModel.getTotalNodeList(); for (int i = 0; i < list.size(); i++) { NavigateNode node = list.get(i); String locNo = Utils.getLocNo(node.getX(), node.getY(), node.getZ()); if (i == 0 && currentShuttleLoc.equals(locNo)) { continue;//..todo wait watch problem } if(totalLocList.contains(locNo)) { return false; } } } //交管接收 trafficControlDataList.add(applyData); applyRecordsMap.remove(shuttleNo); News.info("receipt traffic {},{}", shuttleNo, taskNo); return true; } @Override public synchronized boolean applyTrafficControl(List totalNodeList, List nodeList, Integer shuttleNo, Integer taskNo) { boolean add = true; for (TrafficControlDataModel controlDataModel : applyList) { if(controlDataModel.getShuttleNo().equals(shuttleNo)) { add = false; break; } } if (add) { TrafficControlDataModel model = new TrafficControlDataModel(); model.setShuttleNo(shuttleNo); model.setTaskNo(taskNo); model.setNodeList(nodeList); model.setTotalNodeList(totalNodeList); applyList.add(model); }else { return false; } return true; } @Override public synchronized boolean trafficReport(List nodeList, 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)) { List newTotalNodeList = new ArrayList<>(); List totalNodeList = controlDataModel.getTotalNodeList(); List reportList = new ArrayList<>(); for (NavigateNode node : nodeList) { reportList.add(Utils.getLocNo(node.getX(), node.getY(), node.getZ())); } for (NavigateNode node : totalNodeList) { String locNo = Utils.getLocNo(node.getX(), node.getY(), node.getZ()); if(reportList.contains(locNo)) { continue; } newTotalNodeList.add(node); } controlDataModel.setTotalNodeList(newTotalNodeList); trafficControlDataList.set(i, controlDataModel); shuttleReportErrorMap.remove(shuttleNo); return true; } } } return false; } @Override public 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 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, 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)) { return controlDataModel; } } } return null; } @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 getAllTrafficControl() { return trafficControlDataList; } @Override public boolean connect() { return false; } @Override public void close() { } }