#
Junjie
7 天以前 2c1e3b7b10c0d4afbf09a9151e132f1ee85b9c6f
src/main/java/com/zy/core/thread/impl/TrafficControlImplThread.java
@@ -1,13 +1,8 @@
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;
@@ -15,16 +10,14 @@
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 {
@@ -36,6 +29,7 @@
    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;
@@ -47,17 +41,33 @@
        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;
                List<TrafficControlDataModel> allTrafficControl = getAllTrafficControl();
                //更新交管信息
                redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_MAP.key, allTrafficControl);
                for (TrafficControlDataModel dataModel : allTrafficControl) {
                    Integer shuttleNo = dataModel.getShuttleNo();
                    Integer taskNo = dataModel.getTaskNo();
                    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);
                    }
                }
                TrafficControlDataModel dataModel = applyList.get(0);
                processApply(dataModel);
                applyList.remove(0);
                Thread.sleep(200);
            }catch (Exception e){
                e.printStackTrace();
            }
@@ -65,6 +75,7 @@
    }
    @Override
    public synchronized boolean processApply(TrafficControlDataModel applyData) {
        ShuttleOperaUtils shuttleOperaUtils = SpringUtils.getBean(ShuttleOperaUtils.class);
        if (shuttleOperaUtils == null) {
@@ -79,13 +90,12 @@
            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());
@@ -103,8 +113,8 @@
        }
        //检测车子是否存在管制
        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)) {
@@ -178,7 +188,7 @@
        }
        //检测节点是否被使用
        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);
@@ -194,40 +204,207 @@
        }
        //交管接收
        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);//取消管制
        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())) {
@@ -236,7 +413,7 @@
                    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()));
                    }
@@ -256,84 +433,6 @@
            }
        }
        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