| | |
| | | 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.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 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()); |
| | | } |
| | | |
| | | while (true) { |
| | | try { |
| | | if (applyList.isEmpty()) { |
| | | continue; |
| | | } |
| | | |
| | | TrafficControlDataModel dataModel = applyList.get(0); |
| | | processApply(dataModel); |
| | | applyList.remove(0); |
| | | List<TrafficControlDataModel> allTrafficControl = getAllTrafficControl(); |
| | | //更新交管信息 |
| | | redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_MAP.key, allTrafficControl); |
| | | Thread.sleep(200); |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | } |
| | |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public synchronized boolean processApply(TrafficControlDataModel applyData) { |
| | | ShuttleOperaUtils shuttleOperaUtils = SpringUtils.getBean(ShuttleOperaUtils.class); |
| | | if (shuttleOperaUtils == 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(); |
| | | |
| | | //更新交管信息 |
| | | redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_MAP.key, trafficControlDataList); |
| | | |
| | | 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)) { |
| | |
| | | } |
| | | |
| | | //检测节点是否被使用 |
| | | 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); |
| | |
| | | } |
| | | |
| | | //交管接收 |
| | | trafficControlDataList.add(applyData); |
| | | 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 applyTrafficControl(List<NavigateNode> totalNodeList, List<NavigateNode> 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 { |
| | | 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 synchronized boolean trafficReport(List<NavigateNode> nodeList, Integer shuttleNo, Integer taskNo) { |
| | | 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);//取消管制 |
| | | 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())); |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | 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<TrafficControlDataModel> getAllTrafficControl() { |
| | | return trafficControlDataList; |
| | | } |
| | | |
| | | @Override |