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<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<>();
|
|
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<TrafficControlDataModel>) 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<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());
|
|
int[] currentShuttlePoint = Utils.getShuttlePoint(shuttleNo);
|
if(currentShuttlePoint == null) {
|
return false;
|
}
|
String currentShuttleLoc = Utils.getLocNo(currentShuttlePoint[0], currentShuttlePoint[1], startNode.getZ());
|
|
List<String> 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<String> 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<Integer>() {{
|
add(shuttleNo);
|
}});
|
pathIdleShuttleMap.remove(shuttleProtocol.getShuttleNo());
|
}
|
}else {
|
pathIdleShuttleMap.put(shuttleProtocol.getShuttleNo(), System.currentTimeMillis());
|
}
|
}
|
return false;//node has shuttle
|
}
|
}
|
|
//检测节点是否被使用
|
for (TrafficControlDataModel controlDataModel : trafficControlDataList) {
|
List<NavigateNode> 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<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 {
|
return false;
|
}
|
|
return true;
|
}
|
|
@Override
|
public synchronized boolean trafficReport(List<NavigateNode> 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<NavigateNode> newTotalNodeList = new ArrayList<>();
|
List<NavigateNode> totalNodeList = controlDataModel.getTotalNodeList();
|
|
List<String> 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<TrafficControlDataModel> getAllTrafficControl() {
|
return trafficControlDataList;
|
}
|
|
@Override
|
public boolean connect() {
|
return false;
|
}
|
|
@Override
|
public void close() {
|
|
}
|
|
}
|