| | |
| | | |
| | | 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 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; |
| | |
| | | } |
| | | } |
| | | |
| | | 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; |
| | | } |
| | | // 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; |
| | | // } |
| | | |
| | | private boolean calcWaveScopeByJava(Integer lev, AgvModel agvModel) { |
| | | assert null != agvModel.getDiameter(); |
| | | // assert null != agvModel.getDiameter(); |
| | | String[][] codeMatrix = mapDataDispatcher.getCodeMatrix(lev); |
| | | String[][] waveMatrix = mapDataDispatcher.initWaveMatrix(lev); |
| | | DynamicNode[][] dynamicMatrix = mapDataDispatcher.getDynamicMatrix(lev); |
| | | |
| | | // 当前调度车型的最大旋转半径 |
| | | double bufferRadius = buildFootprint(agvModel).maxExtent(); |
| | | double bufferRadius = MapDataUtils.buildFootprint(agvModel).maxExtent(); |
| | | |
| | | Map<String, VehicleFootprint> footprintCache = new HashMap<>(); |
| | | |
| | |
| | | |
| | | VehicleFootprint footprint = footprintCache.computeIfAbsent(vehicle, this::loadFootprint); |
| | | |
| | | 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); |
| | | } |
| | | 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()]; |
| | |
| | | if (model == null) { |
| | | throw new CoolException(agvNo + " does not have an model."); |
| | | } |
| | | return this.buildFootprint(model); |
| | | } |
| | | |
| | | private double toMapLength(Integer mm) { |
| | | if (mm == null || mm <= 0) { |
| | | throw new IllegalArgumentException("Invalid map length: " + mm); |
| | | } |
| | | return MapDataUtils.getVehicleWaveSafeDistance(mm, MapDataConstant.MAX_DISTANCE_BETWEEN_ADJACENT_AGV_FACTOR); |
| | | } |
| | | |
| | | private double resolveAvoidDistance(AgvModel agvModel) { |
| | | if (agvModel == null || agvModel.getDiameter() == null || agvModel.getDiameter() <= 0) { |
| | | return 0D; |
| | | } |
| | | return MapDataUtils.getVehicleWaveSafeDistance(agvModel.getDiameter(), MapDataConstant.MAX_DISTANCE_BETWEEN_ADJACENT_AGV_FACTOR); |
| | | } |
| | | |
| | | private VehicleFootprint buildFootprint(AgvModel agvModel) { |
| | | if (null == agvModel) { |
| | | throw new IllegalArgumentException("AgvModel is null"); |
| | | } |
| | | if (agvModel.getHeadOffset() == null || agvModel.getHeadOffset() <= 0) { |
| | | throw new IllegalArgumentException("Invalid head offset: " + agvModel.getHeadOffset()); |
| | | } |
| | | if (agvModel.getTailOffset() == null || agvModel.getTailOffset() <= 0) { |
| | | throw new IllegalArgumentException("Invalid tail offset: " + agvModel.getTailOffset()); |
| | | } |
| | | if (agvModel.getWidth() == null || agvModel.getWidth() <= 0) { |
| | | throw new IllegalArgumentException("Invalid width: " + agvModel.getWidth()); |
| | | } |
| | | |
| | | double head = toMapLength(agvModel.getHeadOffset()); |
| | | double tail = toMapLength(agvModel.getTailOffset()); |
| | | double halfWidth = toMapLength(agvModel.getWidth()) / 2; |
| | | |
| | | return new VehicleFootprint(head, tail, halfWidth); |
| | | return MapDataUtils.buildFootprint(model); |
| | | } |
| | | |
| | | private File loadPythonFile() { |