#
vincentlu
2 天以前 7ce12b33107fb33941df7e1589bf1a6716539377
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/AvoidWaveCalculator.java
@@ -2,10 +2,12 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zy.acs.common.utils.Utils;
import com.zy.acs.framework.common.Cools;
import com.zy.acs.framework.exception.CoolException;
import com.zy.acs.manager.common.config.RedisProperties;
import com.zy.acs.manager.common.utils.MapDataUtils;
import com.zy.acs.manager.core.constant.MapDataConstant;
import com.zy.acs.manager.core.domain.PathDto;
import com.zy.acs.manager.core.domain.VehicleFootprint;
import com.zy.acs.manager.core.service.astart.CodeNodeType;
import com.zy.acs.manager.core.service.astart.DynamicNodeType;
import com.zy.acs.manager.core.service.astart.MapDataDispatcher;
import com.zy.acs.manager.core.service.astart.NavigateNode;
@@ -14,7 +16,6 @@
import com.zy.acs.manager.manager.entity.AgvDetail;
import com.zy.acs.manager.manager.entity.AgvModel;
import com.zy.acs.manager.manager.entity.Code;
import com.zy.acs.manager.manager.enums.AgvModelType;
import com.zy.acs.manager.manager.service.AgvDetailService;
import com.zy.acs.manager.manager.service.AgvModelService;
import com.zy.acs.manager.manager.service.AgvService;
@@ -28,13 +29,13 @@
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@@ -45,7 +46,7 @@
 */
@Slf4j
@Component
@DependsOn("getMapDataDispatcher")
@DependsOn("mapDataDispatcher")
public class AvoidWaveCalculator {
    private static final ReentrantLock lock = new ReentrantLock(Boolean.TRUE);
@@ -83,7 +84,7 @@
    }
    public boolean calcWaveScope() {
    public boolean calcWaveScope(AgvModel agvModel) {
        Integer lev = MapDataDispatcher.MAP_DEFAULT_LEV;
        boolean lockAcquired = false;
@@ -96,7 +97,7 @@
            }
//            return this.calcWaveScopeByPython(lev);
            return this.calcWaveScopeByJava(lev);
            return this.calcWaveScopeByJava(lev, agvModel);
        } catch (Exception e) {
@@ -115,92 +116,122 @@
        }
    }
    private boolean calcWaveScopeByPython(Integer lev) throws Exception {
        // python
        AgvModel agvModel = agvModelService.selectByType(AgvModelType.CTU_BOX_TRANSPORT_AGV.toString());    // can be optimized
        Double avoidDistance = MapDataUtils.getVehicleWaveSafeDistance(agvModel.getDiameter(), MapDataConstant.MAX_DISTANCE_BETWEEN_ADJACENT_AGV_FACTOR);
//    private boolean calcWaveScopeByPython(Integer lev, AgvModel agvModel) throws Exception {
//        if (null == agvModel.getDiameter() || agvModel.getDiameter() <= 0) {
//            log.warn("There is no diameter or diameter value was wrong...");
//        }
//
//        // python
//        Double avoidDistance = MapDataUtils.getVehicleWaveSafeDistance(agvModel.getDiameter(), MapDataConstant.MAX_DISTANCE_BETWEEN_ADJACENT_AGV_FACTOR);
//
//        if (null == pythonFile) {
//            pythonFile = loadPythonFile();
//        }
//
//        ProcessBuilder processBuilder = new ProcessBuilder(
//                "python" // 或者 "python3" 取决于系统配置
//                , pythonFile.getAbsolutePath()
//                , String.valueOf(avoidDistance)
//                , redisProperties.getHost()
//                , redisProperties.getPassword()
//                , String.valueOf(redisProperties.getPort())
//                , String.valueOf(redisProperties.getIndex())
//        );
//
//        processBuilder.redirectErrorStream(true);
//
//        Process process = processBuilder.start();
//
//        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
//        String line;
//        StringBuilder builder = new StringBuilder();
//        while ((line = reader.readLine()) != null) {
//            builder.append(line);
//        }
//
//        int exitCode = process.waitFor();
//        if (exitCode != 0) {
//            log.error("Python script exited with error code: {}", exitCode);
//            log.error("python error:{}", builder.toString());
//            return false;
//        }
//        reader.close();
//
//        if (builder.length() <= 0) {
//            return false;
//        }
//
//        String result = builder.toString();
//
//        if (Cools.isEmpty(result)) {
//            return false;
//        }
//        if (!"1".equals(result)) {
//            log.error("Failed to call python");
//            return false;
//        }
//
//        return true;
//    }
        if (null == pythonFile) {
            pythonFile = loadPythonFile();
        }
        ProcessBuilder processBuilder = new ProcessBuilder(
                "python" // 或者 "python3" 取决于系统配置
                , pythonFile.getAbsolutePath()
                , String.valueOf(avoidDistance)
                , redisProperties.getHost()
                , redisProperties.getPassword()
                , String.valueOf(redisProperties.getPort())
                , String.valueOf(redisProperties.getIndex())
        );
        processBuilder.redirectErrorStream(true);
        Process process = processBuilder.start();
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line;
        StringBuilder builder = new StringBuilder();
        while ((line = reader.readLine()) != null) {
            builder.append(line);
        }
        int exitCode = process.waitFor();
        if (exitCode != 0) {
            log.error("Python script exited with error code: {}", exitCode);
            log.error("python error:{}", builder.toString());
            return false;
        }
        reader.close();
        if (builder.length() <= 0) {
            return false;
        }
        String result = builder.toString();
        if (Cools.isEmpty(result)) {
            return false;
        }
        if (!"1".equals(result)) {
            log.error("Failed to call python");
            return false;
        }
        return true;
    }
    private boolean calcWaveScopeByJava(Integer lev) throws Exception {
        AgvModel agvModel = agvModelService.selectByType(AgvModelType.CTU_BOX_TRANSPORT_AGV.toString());    // can be optimized
        Double avoidDistance = MapDataUtils.getVehicleWaveSafeDistance(agvModel.getDiameter(), MapDataConstant.MAX_DISTANCE_BETWEEN_ADJACENT_AGV_FACTOR);
        // java
    private boolean calcWaveScopeByJava(Integer lev, AgvModel agvModel) {
//        assert null != agvModel.getDiameter();
        String[][] codeMatrix = mapDataDispatcher.getCodeMatrix(lev);
        String[][] waveMatrix = mapDataDispatcher.initWaveMatrix(lev);
        // lock path
        DynamicNode[][] dynamicMatrix = mapDataDispatcher.getDynamicMatrix(lev);
        // 当前调度车型的最大旋转半径
        double bufferRadius = MapDataUtils.buildFootprint(agvModel).maxExtent();
        Map<String, VehicleFootprint> footprintCache = new HashMap<>();
        for (int i = 0; i < dynamicMatrix.length; i++) {
            for (int j = 0; j < dynamicMatrix[i].length; j++) {
                DynamicNode dynamicNode = dynamicMatrix[i][j];
                String vehicle = dynamicNode.getVehicle();
                if (!DynamicNodeType.ACCESS.val.equals(vehicle) && !DynamicNodeType.BLOCK.val.equals(vehicle)) {
                if (DynamicNodeType.ACCESS.val.equals(vehicle) || DynamicNodeType.BLOCK.val.equals(vehicle)) {
                    continue;
                }
                String codeData = codeMatrix[i][j];
                if (CodeNodeType.NONE.val.equals(codeData)) {
                    continue;
                }
                    List<NavigateNode> includeList = mapService.getWaveScopeByCode(lev, codeMatrix[i][j], avoidDistance);
                VehicleFootprint footprint = footprintCache.computeIfAbsent(vehicle, this::loadFootprint);
                    for (NavigateNode navigateNode : includeList) {
                        String waveNode = waveMatrix[navigateNode.getX()][navigateNode.getY()]; // overlay
                        waveMatrix[navigateNode.getX()][navigateNode.getY()] = MapDataUtils.generateWaveNode(waveNode, vehicle);
                    }
                double radius = footprint.maxExtent() + bufferRadius;
                List<NavigateNode> includeList = mapService.getWaveScopeByCode(lev, codeData, radius);
//                List<NavigateNode> includeList;
//                Double nodeDirection = dynamicNode.getDirection();
//                if (dynamicNode.isTurn()) {
//                    double radius = footprint.maxExtent() + bufferRadius;
//                    includeList = mapService.getWaveScopeByCode(lev, codeData, radius);
//                } else if (nodeDirection != null) {
//                    double headingRad = Math.toRadians(90 - nodeDirection);
//                    includeList = mapService.getWaveScopeByCode(lev, codeData, footprint, headingRad, bufferRadius);
//                } else {
//                    double radius = footprint.maxExtent() + bufferRadius;
//                    includeList = mapService.getWaveScopeByCode(lev, codeData, radius);
//                }
                for (NavigateNode navigateNode : includeList) {
                    String waveNode = waveMatrix[navigateNode.getX()][navigateNode.getY()];
                    waveMatrix[navigateNode.getX()][navigateNode.getY()] = MapDataUtils.generateWaveNode(waveNode, vehicle);
                }
            }
        }
//            mapDataDispatcher.printMatrix(waveMatrix);
        mapDataDispatcher.setWaveMatrix(lev, waveMatrix);
        return true;
    }
    private VehicleFootprint loadFootprint(String agvNo) {
        AgvModel model = agvModelService.getByAgvNo(agvNo);
        if (model == null) {
            throw new CoolException(agvNo + " does not have an model.");
        }
        return MapDataUtils.buildFootprint(model);
    }
    private File loadPythonFile() {
@@ -234,7 +265,7 @@
        if (null == dynamicMatrix) {
            dynamicMatrix = mapDataDispatcher.getDynamicMatrix(null);
        }
        AgvDetail agvDetail = agvDetailService.selectByAgvId(agv.getId());
        AgvDetail agvDetail = agvDetailService.selectMajorByAgvId(agv.getId());
        if (null == agvDetail) {
            return;
        }
@@ -253,7 +284,12 @@
        DynamicNode dynamicNode = dynamicMatrix[codeMatrixIdx[0]][codeMatrixIdx[1]];
        String vehicle = dynamicNode.getVehicle();
        if (vehicle.equals(DynamicNodeType.ACCESS.val)) {
            mapDataDispatcher.modifyDynamicMatrix(null, Utils.singletonList(codeMatrixIdx), agv.getUuid());
            mapDataDispatcher.modifyDynamicMatrix(
                    null,
                    Utils.singletonList(codeMatrixIdx),
                    agv.getUuid(),
                    Utils.singletonList(new PathDto(code.getData(), MapService.mapToNearest(agvDetail.getAgvAngle())))
            );
        }
    }