From d808837cd368c3772962be591aa6532bcc0cf3e4 Mon Sep 17 00:00:00 2001
From: jianghaiyue <jianghaiyue@zkyt.com>
Date: 星期一, 22 九月 2025 12:11:37 +0800
Subject: [PATCH] 更新版本

---
 algo-zkd/src/main/java/com/algo/service/AStarPathPlanner.java |  208 +++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 180 insertions(+), 28 deletions(-)

diff --git a/algo-zkd/src/main/java/com/algo/service/AStarPathPlanner.java b/algo-zkd/src/main/java/com/algo/service/AStarPathPlanner.java
index 4ae0129..5fe5554 100644
--- a/algo-zkd/src/main/java/com/algo/service/AStarPathPlanner.java
+++ b/algo-zkd/src/main/java/com/algo/service/AStarPathPlanner.java
@@ -4,12 +4,12 @@
 import com.algo.model.PathCode;
 import com.algo.model.PlannedPath;
 import com.algo.util.JsonUtils;
+import com.algo.util.PathTimeCalculator;
 
 import java.util.*;
 
 /**
  * A*璺緞瑙勫垝鍣ㄥ疄鐜�
- * 浣跨敤3D A*绠楁硶杩涜CTU鏃剁┖璺緞瑙勫垝锛屾敮鎸佺墿鐞嗙害鏉�
  */
 public class AStarPathPlanner implements PathPlanner {
 
@@ -22,6 +22,11 @@
      * 閭绘帴琛�
      */
     private final Map<String, List<Map<String, String>>> adjacencyList;
+
+    /**
+     * 鐜杩為�氭�ф暟鎹�
+     */
+    private final JsonUtils.EnvironmentConnectivity environmentConnectivity;
 
     /**
      * 鏃堕棿绮惧害锛堟绉掞級
@@ -39,7 +44,7 @@
     private final int maxSearchDepth = 15000;
 
     /**
-     * 璺濈缂撳瓨 - 浼樺寲锛氱紦瀛樿窛绂昏绠楃粨鏋�
+     * 璺濈缂撳瓨
      */
     private final Map<String, Double> distanceCache = new HashMap<>();
 
@@ -47,6 +52,16 @@
      * 蹇�熻矾寰勭紦瀛�
      */
     private final Map<String, List<String>> fastPathCache = new HashMap<>();
+    
+    /**
+     * 瀹為檯鍧愭爣鏄犲皠 
+     */
+    private Map<String, double[]> realCoordinateMapping;
+    
+    /**
+     * 璺緞鏃堕棿璁$畻鍣�
+     */
+    private PathTimeCalculator timeCalculator;
 
     /**
      * 鏋勯�犲嚱鏁�
@@ -57,13 +72,38 @@
         this.pathMapping = pathMapping;
         this.adjacencyList = new HashMap<>();
 
-        // 鐩存帴鏋勫缓閭绘帴琛�
-        buildAdjacencyList();
+        // 鍔犺浇鐜杩為�氭�ф暟鎹�
+        this.environmentConnectivity = JsonUtils.loadEnvironmentConnectivity("environment.json");
+
+        // 鏋勫缓鐜鎰熺煡鐨勯偦鎺ヨ〃
+        buildEnvironmentAwareAdjacencyList();
+        
+        // 鍔犺浇瀹為檯鍧愭爣鏄犲皠
+        loadRealCoordinateMapping();
+        
+        // 鍒濆鍖栨椂闂磋绠楀櫒
+        this.timeCalculator = new PathTimeCalculator(pathMapping, realCoordinateMapping);
 
         // 棰勮绠楀父鐢ㄨ窛绂�
         precomputeCommonDistances();
 
         System.out.println("A*璺緞瑙勫垝鍣ㄥ垵濮嬪寲瀹屾垚锛岄偦鎺ヨ〃鍖呭惈 " + adjacencyList.size() + " 涓妭鐐�");
+    }
+    
+    /**
+     * 鍔犺浇瀹為檯鍧愭爣鏄犲皠
+     */
+    private void loadRealCoordinateMapping() {
+        try {
+            this.realCoordinateMapping = JsonUtils.loadRealCoordinateMapping("man_code.json");
+            if (realCoordinateMapping == null || realCoordinateMapping.isEmpty()) {
+                System.out.println("鏈兘鍔犺浇瀹為檯鍧愭爣鏄犲皠锛屼娇鐢ㄧ綉鏍煎潗鏍�");
+                this.realCoordinateMapping = new HashMap<>();
+            }
+        } catch (Exception e) {
+            System.err.println("鍔犺浇瀹為檯鍧愭爣鏄犲皠澶辫触: " + e.getMessage());
+            this.realCoordinateMapping = new HashMap<>();
+        }
     }
 
     @Override
@@ -278,7 +318,7 @@
             }
         }
 
-        // 鍑忓皯绛夊緟閫夐」 - 鍙湪蹇呰鏃剁瓑寰咃紙20%姒傜巼锛�
+        // 鍑忓皯绛夊緟閫夐」
         if (Math.random() < 0.2) {
             long waitTime = timeResolution;
             long waitUntilTime = current.timePoint + waitTime;
@@ -308,27 +348,61 @@
     /**
      * 鏃剁┖鍚彂寮忓嚱鏁�
      *
-     * @param coord1         褰撳墠鍧愭爣
-     * @param coord2         鐩爣鍧愭爣
+     * @param coord1         褰撳墠鍧愭爣锛堢綉鏍硷級
+     * @param coord2         鐩爣鍧愭爣锛堢綉鏍硷級
      * @param currentTime    褰撳墠鏃堕棿
      * @param physicalConfig 鐗╃悊閰嶇疆
      * @return 鍚彂寮忓��
      */
     private double spaceTimeHeuristic(int[] coord1, int[] coord2, long currentTime, CTUPhysicalConfig physicalConfig) {
-        // 绌洪棿璺濈
+        String pathId1 = findPathIdByCoordinate(coord1);
+        String pathId2 = findPathIdByCoordinate(coord2);
+        
+        if (pathId1 != null && pathId2 != null) {
+            double[] realCoord1 = JsonUtils.getRealCoordinate(pathId1, realCoordinateMapping);
+            double[] realCoord2 = JsonUtils.getRealCoordinate(pathId2, realCoordinateMapping);
+            
+            if (realCoord1 != null && realCoord2 != null) {
+                // 浣跨敤瀹為檯璺濈璁$畻
+                double realDistance = CTUPhysicalConfig.calculateRealDistance(realCoord1, realCoord2);
+                
+                // 鏃堕棿鎴愭湰浼拌锛堝亣璁惧钩鍧囬�熷害锛�
+                double timeEstimate = realDistance / physicalConfig.getNormalSpeed();
+                
+                // 鑰冭檻杞悜鎴愭湰
+                double turnPenalty = realDistance > 0.5 ? physicalConfig.getTurnTime90() / 2.0 : 0;
+                
+                return timeEstimate + turnPenalty;
+            }
+        }
+        
+        // 鍓嶆柟妗堬細浣跨敤缃戞牸鍧愭爣
         double spatialDistance = Math.abs(coord1[0] - coord2[0]) + Math.abs(coord1[1] - coord2[1]);
-
-        // 鏃堕棿鎴愭湰浼拌
         double timeEstimate = spatialDistance * physicalConfig.getStandardPointDistance() / physicalConfig.getNormalSpeed();
-
-        // 鑰冭檻杞悜鎴愭湰
         double turnPenalty = spatialDistance > 1 ? physicalConfig.getTurnTime90() : 0;
 
         return timeEstimate + turnPenalty;
     }
+    
+    /**
+     * 鏍规嵁缃戞牸鍧愭爣鏌ユ壘璺緞ID
+     */
+    private String findPathIdByCoordinate(int[] coord) {
+        if (coord == null) return null;
+        
+        for (Map.Entry<String, Map<String, Integer>> entry : pathMapping.entrySet()) {
+            Map<String, Integer> coordMap = entry.getValue();
+            if (coordMap != null && 
+                coord[0] == coordMap.getOrDefault("x", -1) && 
+                coord[1] == coordMap.getOrDefault("y", -1)) {
+                return entry.getKey();
+            }
+        }
+        return null;
+    }
 
     /**
-     * 璁$畻绉诲姩鏃堕棿
+     * 璁$畻绮剧‘鐨勭Щ鍔ㄦ椂闂达紝鍩轰簬瀹為檯鍧愭爣鍜岀墿鐞嗗弬鏁�
      *
      * @param fromCode       璧峰浠g爜
      * @param toCode         鐩爣浠g爜
@@ -337,14 +411,70 @@
      * @return 绉诲姩鏃堕棿锛堟绉掞級
      */
     private long calculateTravelTime(String fromCode, String toCode, String direction, CTUPhysicalConfig physicalConfig) {
-        // 鍩烘湰绉诲姩鏃堕棿
+        // 鑾峰彇瀹為檯鍧愭爣
+        double[] fromCoord = JsonUtils.getRealCoordinate(fromCode, realCoordinateMapping);
+        double[] toCoord = JsonUtils.getRealCoordinate(toCode, realCoordinateMapping);
+        
+        if (fromCoord == null || toCoord == null) {
+            // fallback鍒扮綉鏍煎潗鏍囪绠�
+            return calculateFallbackTravelTime(fromCode, toCode, physicalConfig);
+        }
+        
+        // 璁$畻瀹為檯璺濈锛堢背锛�
+        double realDistance = CTUPhysicalConfig.calculateRealDistance(fromCoord, toCoord);
+        
+        if (realDistance == 0.0) {
+            return 100; // 鏈�灏忔椂闂�100ms
+        }
+        
+        // 鍋囪璧峰鍜岀粨鏉熼�熷害锛堝彲浠ユ牴鎹笂涓嬫枃杩涗竴姝ヤ紭鍖栵級
+        double startSpeed = 0.0; // 鍋囪浠庨潤姝㈠紑濮�
+        double endSpeed = 0.0;   // 鍋囪缁撴潫鏃跺仠姝�
+        double targetSpeed = physicalConfig.getNormalSpeed();
+        
+        // 璁$畻绮剧‘鐨勭Щ鍔ㄦ椂闂�
+        double movementTime = physicalConfig.calculatePreciseMovementTime(
+            realDistance, startSpeed, endSpeed, targetSpeed
+        );
+        
+        // 璁$畻杞悜鏃堕棿
+        double turnTime = calculateTurnTime(fromCode, toCode, physicalConfig);
+        
+        return Math.max(100, (long) ((movementTime + turnTime) * 1000));
+    }
+    
+    /**
+     * 璁$畻杞悜鏃堕棿
+     */
+    private double calculateTurnTime(String fromCode, String toCode, CTUPhysicalConfig physicalConfig) {
+        
+        double[] fromCoord = JsonUtils.getRealCoordinate(fromCode, realCoordinateMapping);
+        double[] toCoord = JsonUtils.getRealCoordinate(toCode, realCoordinateMapping);
+        
+        if (fromCoord == null || toCoord == null) {
+            return physicalConfig.getTurnTime90() / 4.0; // 骞冲潎杞悜鏃堕棿
+        }
+        
+        // 璁$畻鏂瑰悜鍙樺寲
+        double dx = toCoord[0] - fromCoord[0];
+        double dy = toCoord[1] - fromCoord[1];
+        
+        // 鐩寸嚎杩愬姩鏃犻渶杞悜
+        if (Math.abs(dx) < 1.0 && Math.abs(dy) < 1.0) {
+            return 0.0;
+        }
+        
+        return physicalConfig.getTurnTime90() / 2.0;
+    }
+    
+    /**
+     * 澶囩敤鏃堕棿璁$畻鏂规硶锛堝綋鏃犳硶鑾峰彇瀹為檯鍧愭爣鏃朵娇鐢級
+     */
+    private long calculateFallbackTravelTime(String fromCode, String toCode, CTUPhysicalConfig physicalConfig) {
         double distance = physicalConfig.getStandardPointDistance();
         double speed = physicalConfig.getNormalSpeed();
         long moveTime = (long) ((distance / speed) * 1000);
-
-        // 杞悜鏃堕棿
-        long turnTime = (long) (physicalConfig.getTurnTime90() * 1000 / 4); // 鍋囪骞冲潎杞悜鏃堕棿
-
+        long turnTime = (long) (physicalConfig.getTurnTime90() * 1000 / 4);
         return moveTime + turnTime;
     }
 
@@ -384,14 +514,17 @@
             }
 
             PathCode pathCode = new PathCode(node.code, direction);
-
-            // 娣诲姞鏃堕棿淇℃伅
-            // pathCode.setArrivalTime(node.timePoint);
-
             codeList.add(pathCode);
         }
 
-        return new PlannedPath("", "", codeList);
+        PlannedPath plannedPath = new PlannedPath("", "", codeList);
+        
+        // 浣跨敤缁熶竴鐨勬椂闂磋绠楀櫒璁$畻绮剧‘鏃堕棿
+        long startTime = pathNodes.get(0).timePoint;
+        CTUPhysicalConfig defaultConfig = createDefaultPhysicalConfig();
+        timeCalculator.calculatePathTiming(plannedPath, startTime, defaultConfig, 0.0);
+        
+        return plannedPath;
     }
 
     /**
@@ -472,6 +605,15 @@
 
     @Override
     public double calculateDistance(String startCode, String endCode) {
+        // 浼樺厛浣跨敤瀹為檯鍧愭爣
+        double[] startRealCoord = JsonUtils.getRealCoordinate(startCode, realCoordinateMapping);
+        double[] endRealCoord = JsonUtils.getRealCoordinate(endCode, realCoordinateMapping);
+        
+        if (startRealCoord != null && endRealCoord != null) {
+            return CTUPhysicalConfig.calculateRealDistance(startRealCoord, endRealCoord);
+        }
+        
+        // 鍓嶆柟妗堬細浣跨敤缃戞牸鍧愭爣
         int[] startCoord = JsonUtils.getCoordinate(startCode, pathMapping);
         int[] endCoord = JsonUtils.getCoordinate(endCode, pathMapping);
 
@@ -493,9 +635,9 @@
     }
 
     /**
-     * 鏋勫缓閭绘帴琛�
+     * 鏋勫缓鐜鎰熺煡鐨勯偦鎺ヨ〃
      */
-    private void buildAdjacencyList() {
+    private void buildEnvironmentAwareAdjacencyList() {
         // 鍒涘缓鍧愭爣鍒扮紪鍙风殑涓存椂鏄犲皠
         Map<String, String> tempCoordToCode = new HashMap<>();
         for (Map.Entry<String, Map<String, Integer>> entry : pathMapping.entrySet()) {
@@ -523,6 +665,12 @@
             int x = coordMap.get("x");
             int y = coordMap.get("y");
 
+            // 鐜鎰熺煡锛氭鏌ュ綋鍓嶈妭鐐规槸鍚﹀彲閫氳
+            if (!environmentConnectivity.isTraversable(x, y)) {
+                adjacencyList.put(code, new ArrayList<>()); // 涓嶅彲閫氳鐨勮妭鐐规病鏈夐偦灞�
+                continue;
+            }
+
             List<Map<String, String>> neighbors = new ArrayList<>();
 
             // 妫�鏌ュ洓涓柟鍚戠殑閭诲眳
@@ -532,7 +680,9 @@
                 String coordKey = newX + "," + newY;
 
                 String neighborCode = tempCoordToCode.get(coordKey);
-                if (neighborCode != null) {
+                
+                // 鐜鎰熺煡锛氬彧鏈夊綋閭诲眳鑺傜偣涔熷彲閫氳鏃舵墠娣诲姞杩炴帴
+                if (neighborCode != null && environmentConnectivity.isTraversable(newX, newY)) {
                     Map<String, String> neighbor = new HashMap<>();
                     neighbor.put("code", neighborCode);
                     neighbor.put("direction", directionAngles[i]);
@@ -542,6 +692,8 @@
 
             adjacencyList.put(code, neighbors);
         }
+        
+        System.out.println("鐜鎰熺煡閭绘帴琛ㄦ瀯寤哄畬鎴愶紝杩囨护浜嗕笉鍙�氳鐨勮繛鎺�");
     }
 
     /**
@@ -673,7 +825,7 @@
     }
 
     /**
-     * 蹇�熻矾寰勮鍒� - 鍏堝皾璇曠畝鍖栫┖闂磋矾寰勮鍒�
+     * 蹇�熻矾寰勮鍒� 
      * 瀵逛簬杩戣窛绂昏矾寰勶紝鐩存帴杩斿洖缁撴灉閬垮厤澶嶆潅鐨勬椂绌鸿绠�
      */
     private PlannedPath tryFastPathPlanning(String startCode, String endCode, List<double[]> constraints) {
@@ -722,7 +874,7 @@
         openSet.offer(startNode);
         gScores.put(startCode, 0.0);
 
-        // 绠�鍖栫殑绾︽潫妫�鏌ュ櫒
+        // 绾︽潫妫�鏌ュ櫒
         FastConstraintChecker constraintChecker = new FastConstraintChecker(constraints);
 
         int searchDepth = 0;

--
Gitblit v1.9.1