| | |
| | | import java.io.*; |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * JSON文件读取工具类 |
| | | * 用于读取环境配置和路径映射文件 |
| | | * JSON文件读取 |
| | | */ |
| | | public class JsonUtils { |
| | | |
| | | /** |
| | | * 读取JSON文件内容 |
| | | * |
| | | * @param filePath 文件路径 |
| | | * @return JSON字符串内容 |
| | | * @throws IOException 文件读取异常 |
| | |
| | | } |
| | | |
| | | /** |
| | | * 解析路径映射JSON内容 |
| | | * 正确解析path_mapping.json的实际格式:{"path_id_to_coordinates": {...}} |
| | | * 解析路径映射JSON |
| | | * |
| | | * @param jsonContent JSON内容 |
| | | * @return 路径映射Map,key为路径编号,value为坐标信息 |
| | |
| | | Map<String, Map<String, Integer>> pathMapping = new HashMap<>(); |
| | | |
| | | try { |
| | | // 找到path_id_to_coordinates部分 |
| | | String pathIdSection = extractJsonSection(jsonContent, "path_id_to_coordinates"); |
| | | if (pathIdSection == null) { |
| | | System.err.println("未找到path_id_to_coordinates部分"); |
| | |
| | | } |
| | | |
| | | /** |
| | | * 加载和解析路径映射文件 |
| | | * 正确解析path_mapping.json的实际格式:{"path_id_to_coordinates": {...}} |
| | | * 路径映射 |
| | | * |
| | | * @param filePath 文件地址 |
| | | * @return 路径映射Map,key为路径编号,value为坐标信息 |
| | |
| | | Map<String, Map<String, Integer>> pathMapping = new HashMap<>(); |
| | | ObjectMapper objectMapper = new ObjectMapper(); |
| | | try { |
| | | // 先解析为顶层Map<String, Object> |
| | | Map<String, Object> topLevelMap = objectMapper.readValue( |
| | | new File(filePath), |
| | | Map.class |
| | |
| | | return pathMapping; |
| | | } |
| | | |
| | | // 处理 path_id_to_coordinates(将坐标列表转换为第一个坐标的path_id映射) |
| | | // 处理 path_id_to_coordinates |
| | | Map<String, Object> pathIdCoords = (Map<String, Object>) topLevelMap.get("path_id_to_coordinates"); |
| | | for (Map.Entry<String, Object> entry : pathIdCoords.entrySet()) { |
| | | // 保存方式: 路径ID:{"x": , "y":} |
| | | String pathId = entry.getKey(); |
| | | Object coordsObj = entry.getValue(); |
| | | if (coordsObj instanceof List) { |
| | |
| | | } |
| | | |
| | | /** |
| | | * 解析环境配置JSON内容 |
| | | * 解析environment.json中的stations信息 |
| | | * 环境配置JSON |
| | | * |
| | | * @param jsonContent JSON内容 |
| | | * @return 环境配置Map |
| | |
| | | Map<String, Object> config = new HashMap<>(); |
| | | |
| | | try { |
| | | // 解析width |
| | | if (jsonContent.contains("\"width\":")) { |
| | | String widthStr = jsonContent.substring(jsonContent.indexOf("\"width\":") + 8); |
| | | widthStr = widthStr.substring(0, widthStr.indexOf(",")).trim(); |
| | |
| | | } |
| | | } |
| | | |
| | | // 解析height |
| | | if (jsonContent.contains("\"height\":")) { |
| | | String heightStr = jsonContent.substring(jsonContent.indexOf("\"height\":") + 9); |
| | | heightStr = heightStr.substring(0, heightStr.indexOf(",")).trim(); |
| | |
| | | } |
| | | } |
| | | |
| | | // 解析stations信息 |
| | | Map<String, Map<String, Object>> stations = parseStations(jsonContent); |
| | | config.put("stations", stations); |
| | | config.put("stationCount", stations.size()); |
| | |
| | | } |
| | | |
| | | /** |
| | | * 加载和解析环境配置文件 |
| | | * 解析environment.json中的stations信息 |
| | | * |
| | | * @param filePath 文件地址 |
| | |
| | | Map.class |
| | | ); |
| | | |
| | | // 解析width |
| | | if (topLevelMap.containsKey("width")) { |
| | | environmentMap.put("width", Integer.parseInt(topLevelMap.get("width").toString())); |
| | | } else { |
| | | environmentMap.put("width", 78); |
| | | } |
| | | |
| | | // 解析height |
| | | if (topLevelMap.containsKey("width")) { |
| | | environmentMap.put("height", Integer.parseInt(topLevelMap.get("height").toString())); |
| | | } else { |
| | | environmentMap.put("height", 50); |
| | | } |
| | | |
| | | // 解析stations信息 |
| | | if (topLevelMap.containsKey("stations")) { |
| | | Map<String, Map<String, Object>> stations = new HashMap<>(); |
| | | Map<String, Object> stationMap = (Map<String, Object>) topLevelMap.get("stations"); |
| | |
| | | for (String line : lines) { |
| | | line = line.trim(); |
| | | |
| | | // 查找工作站ID |
| | | if (line.startsWith("\"") && line.contains("\":{")) { |
| | | int endIndex = line.indexOf("\":{"); |
| | | currentStation = line.substring(1, endIndex); |
| | | stations.put(currentStation, new HashMap<>()); |
| | | } |
| | | |
| | | // 解析capacity |
| | | if (currentStation != null && line.contains("\"capacity\":")) { |
| | | String capacityStr = line.substring(line.indexOf("\"capacity\":") + 11); |
| | | capacityStr = capacityStr.substring(0, capacityStr.indexOf(",")).trim(); |
| | |
| | | } |
| | | } |
| | | |
| | | // 解析load_position和unload_position |
| | | if (currentStation != null && line.contains("\"load_position\":")) { |
| | | List<Integer> loadPos = parsePosition(stationsSection, currentStation, "load_position"); |
| | | if (loadPos != null) { |
| | |
| | | } |
| | | |
| | | /** |
| | | * 提取JSON中的特定部分 |
| | | * 提取JSON中特定部分 |
| | | * |
| | | * @param jsonContent JSON内容 |
| | | * @param sectionName 部分名称 |
| | |
| | | return new int[]{coordMap.get("x"), coordMap.get("y")}; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * 加载实际物理坐标映射 |
| | | * |
| | | * @param filePath 文件路径 |
| | | * @return 实际坐标映射 Map<pathId, double[]{x_mm, y_mm}> |
| | | */ |
| | | public static Map<String, double[]> loadRealCoordinateMapping(String filePath) { |
| | | Map<String, double[]> coordinateMapping = new HashMap<>(); |
| | | ObjectMapper objectMapper = new ObjectMapper(); |
| | | |
| | | try { |
| | | Map<String, Object> topLevelMap = objectMapper.readValue(new File(filePath), Map.class); |
| | | |
| | | if (!topLevelMap.containsKey("path_id_to_coordinates")) { |
| | | System.err.println("未找到path_id_to_coordinates部分"); |
| | | return coordinateMapping; |
| | | } |
| | | |
| | | Map<String, Object> pathIdCoords = (Map<String, Object>) topLevelMap.get("path_id_to_coordinates"); |
| | | for (Map.Entry<String, Object> entry : pathIdCoords.entrySet()) { |
| | | String pathId = entry.getKey(); |
| | | Object coordsObj = entry.getValue(); |
| | | |
| | | if (coordsObj instanceof List) { |
| | | List<?> coordsList = (List<?>) coordsObj; |
| | | if (!coordsList.isEmpty()) { |
| | | Map<?, ?> coordMap = (Map<?, ?>) coordsList.get(0); |
| | | double x = ((Number) coordMap.get("x")).doubleValue(); |
| | | double y = ((Number) coordMap.get("y")).doubleValue(); |
| | | coordinateMapping.put(pathId, new double[]{x, y}); |
| | | } |
| | | } |
| | | } |
| | | |
| | | System.out.println("成功加载实际坐标映射,包含 " + coordinateMapping.size() + " 个路径点"); |
| | | |
| | | } catch (FileNotFoundException e) { |
| | | System.err.println("实际坐标文件不存在: " + e.getMessage()); |
| | | } catch (IOException e) { |
| | | System.err.println("实际坐标文件读取错误: " + e.getMessage()); |
| | | } catch (Exception e) { |
| | | System.err.println("加载实际坐标文件失败: " + e.getMessage()); |
| | | } |
| | | |
| | | return coordinateMapping; |
| | | } |
| | | |
| | | /** |
| | | * 获取路径点的实际坐标 |
| | | * |
| | | * @param pathId 路径点ID |
| | | * @param realCoordinateMap 实际坐标映射 |
| | | * @return 坐标数组 [x_mm, y_mm],如果未找到返回null |
| | | */ |
| | | public static double[] getRealCoordinate(String pathId, Map<String, double[]> realCoordinateMap) { |
| | | return realCoordinateMap.get(pathId); |
| | | } |
| | | |
| | | /** |
| | |
| | | int dy = coord1[1] - coord2[1]; |
| | | return Math.sqrt(dx * dx + dy * dy); |
| | | } |
| | | |
| | | /** |
| | | * 加载环境路径连通性数据(environment.json中的paths和obstacles) |
| | | * |
| | | * @param filePath 环境文件路径 |
| | | * @return 环境连通性数据 |
| | | */ |
| | | public static EnvironmentConnectivity loadEnvironmentConnectivity(String filePath) { |
| | | EnvironmentConnectivity connectivity = new EnvironmentConnectivity(); |
| | | ObjectMapper objectMapper = new ObjectMapper(); |
| | | |
| | | try { |
| | | Map<String, Object> topLevelMap = objectMapper.readValue(new File(filePath), Map.class); |
| | | |
| | | // 加载可通行路径 |
| | | if (topLevelMap.containsKey("paths")) { |
| | | List<Map<String, Object>> pathsList = (List<Map<String, Object>>) topLevelMap.get("paths"); |
| | | for (Map<String, Object> pathPoint : pathsList) { |
| | | Integer x = (Integer) pathPoint.get("x"); |
| | | Integer y = (Integer) pathPoint.get("y"); |
| | | if (x != null && y != null) { |
| | | connectivity.addValidPath(x, y); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 加载障碍物 |
| | | if (topLevelMap.containsKey("obstacles")) { |
| | | List<Map<String, Object>> obstaclesList = (List<Map<String, Object>>) topLevelMap.get("obstacles"); |
| | | for (Map<String, Object> obstacle : obstaclesList) { |
| | | Integer x = (Integer) obstacle.get("x"); |
| | | Integer y = (Integer) obstacle.get("y"); |
| | | if (x != null && y != null) { |
| | | connectivity.addObstacle(x, y); |
| | | } |
| | | } |
| | | } |
| | | |
| | | System.out.println("成功加载环境连通性数据:" + |
| | | connectivity.getValidPathsCount() + " 个可通行点," + |
| | | connectivity.getObstaclesCount() + " 个障碍物点"); |
| | | |
| | | } catch (FileNotFoundException e) { |
| | | System.err.println("环境文件不存在: " + e.getMessage()); |
| | | } catch (IOException e) { |
| | | System.err.println("环境文件读取错误: " + e.getMessage()); |
| | | } catch (Exception e) { |
| | | System.err.println("加载环境连通性数据失败: " + e.getMessage()); |
| | | } |
| | | |
| | | return connectivity; |
| | | } |
| | | |
| | | /** |
| | | * 环境连通性数据类 |
| | | */ |
| | | public static class EnvironmentConnectivity { |
| | | private final Set<String> validPaths = new HashSet<>(); |
| | | private final Set<String> obstacles = new HashSet<>(); |
| | | |
| | | public void addValidPath(int x, int y) { |
| | | validPaths.add(x + "," + y); |
| | | } |
| | | |
| | | public void addObstacle(int x, int y) { |
| | | obstacles.add(x + "," + y); |
| | | } |
| | | |
| | | public boolean isValidPath(int x, int y) { |
| | | return validPaths.contains(x + "," + y); |
| | | } |
| | | |
| | | public boolean isObstacle(int x, int y) { |
| | | return obstacles.contains(x + "," + y); |
| | | } |
| | | |
| | | public boolean isTraversable(int x, int y) { |
| | | return isValidPath(x, y) && !isObstacle(x, y); |
| | | } |
| | | |
| | | public int getValidPathsCount() { |
| | | return validPaths.size(); |
| | | } |
| | | |
| | | public int getObstaclesCount() { |
| | | return obstacles.size(); |
| | | } |
| | | |
| | | /** |
| | | * 获取有效的相邻节点 |
| | | */ |
| | | public List<int[]> getValidNeighbors(int x, int y) { |
| | | List<int[]> neighbors = new ArrayList<>(); |
| | | int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; // 上下左右 |
| | | |
| | | for (int[] dir : directions) { |
| | | int newX = x + dir[0]; |
| | | int newY = y + dir[1]; |
| | | |
| | | if (isTraversable(newX, newY)) { |
| | | neighbors.add(new int[]{newX, newY}); |
| | | } |
| | | } |
| | | |
| | | return neighbors; |
| | | } |
| | | } |
| | | } |