From 3b1fae6a1e336696b3c3391b1a9bd33f45d66041 Mon Sep 17 00:00:00 2001
From: tian <11429339@qq.com>
Date: Sun, 28 Sep 2025 17:46:16 +0800
Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E4=BA=86=E8=B7=AF=E5=BE=84?=
=?UTF-8?q?=E5=9C=A8=E6=96=9C=E9=9D=A2=EF=BC=88=E5=A6=82=E6=A5=BC=E6=A2=AF?=
=?UTF-8?q?=EF=BC=89=E4=B8=8A=E7=9A=84=E8=A7=84=E5=88=92?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/PathPlanning/AutoPathFinder.cs | 153 +++++---------------
src/PathPlanning/ChannelBasedGridBuilder.cs | 2 +-
src/PathPlanning/GridMap.cs | 40 +----
src/PathPlanning/GridMapGenerator.cs | 57 +++-----
src/PathPlanning/VerticalScanProcessor.cs | 71 +++++----
5 files changed, 107 insertions(+), 216 deletions(-)
diff --git a/src/PathPlanning/AutoPathFinder.cs b/src/PathPlanning/AutoPathFinder.cs
index 301a9a3..1f681d4 100644
--- a/src/PathPlanning/AutoPathFinder.cs
+++ b/src/PathPlanning/AutoPathFinder.cs
@@ -101,17 +101,14 @@ namespace NavisworksTransport.PathPlanning
// 5. 根据网格点通行高度区间对路径点Z坐标调整
var enhancedPath = ApplyGridHeightConstraints(pathResult.PathPoints, gridMap, vehicleHeight);
- // 6. 精确高度修正
- var heightCorrectedPath = ApplyPreciseHeightCorrection(enhancedPath, gridMap);
-
- // 8. 验证路径中所有点的高度约束(特别是门网格)
- ValidatePathHeightConstraints(heightCorrectedPath, gridMap, vehicleHeight);
+ // 6. 验证路径中所有点的高度约束(特别是门网格)
+ ValidatePathHeightConstraints(enhancedPath, gridMap, vehicleHeight);
// 更新PathFindingResult
- pathResult.PathPoints = heightCorrectedPath;
+ pathResult.PathPoints = enhancedPath;
pathResult.OriginalEndPoint = originalEnd;
- LogManager.Info($"[2.5D路径规划] 路径生成完成,最终包含 {heightCorrectedPath.Count} 个路径点,完成度: {pathResult.CompletionPercentage:F1}%");
+ LogManager.Info($"[2.5D路径规划] 路径生成完成,最终包含 {enhancedPath.Count} 个路径点,完成度: {pathResult.CompletionPercentage:F1}%");
// 路径优化 - 去除共线点
pathResult = OptimizePath(pathResult, gridMap);
@@ -198,10 +195,10 @@ namespace NavisworksTransport.PathPlanning
if (isPassable)
{
- if (cell.PassableHeights != null && cell.PassableHeights.Any())
+ if (cell.PassableHeight.MaxZ > cell.PassableHeight.MinZ)
{
// vehicleHeight已经是模型单位,直接比较即可
- bool heightOk = cell.PassableHeights.Any(interval => interval.GetSpan() >= vehicleHeight);
+ bool heightOk = cell.PassableHeight.GetSpan() >= vehicleHeight;
if (!heightOk)
{
heightConstrainedCells++;
@@ -209,7 +206,7 @@ namespace NavisworksTransport.PathPlanning
// 详细日志:记录被高度约束排除的单元格(仅记录前10个避免日志过多)
if (heightConstrainedCells <= 10)
{
- LogManager.Info($"[A*高度约束] 单元格({x},{y})被高度约束排除:车辆高度{vehicleHeight:F2}模型单位,可用区间:{string.Join(", ", cell.PassableHeights.Select(i => $"{i.MinZ:F2}-{i.MaxZ:F2}(跨度{i.GetSpan():F2})"))}");
+ LogManager.Info($"[A*高度约束] 单元格({x},{y})被高度约束排除:车辆高度{vehicleHeight:F2}模型单位,可用区间:{cell.PassableHeight.MinZ:F2}-{cell.PassableHeight.MaxZ:F2}(跨度{cell.PassableHeight.GetSpan():F2})");
}
else if (heightConstrainedCells == 11)
{
@@ -236,9 +233,9 @@ namespace NavisworksTransport.PathPlanning
{
var rightCell = gridMap.Cells[x + 1, y];
bool rightPassable = rightCell.IsWalkable;
- if (rightPassable && rightCell.PassableHeights != null && rightCell.PassableHeights.Any())
+ if (rightPassable && rightCell.PassableHeight.MaxZ > rightCell.PassableHeight.MinZ)
{
- rightPassable = rightCell.PassableHeights.Any(interval => interval.GetSpan() >= vehicleHeight);
+ rightPassable = rightCell.PassableHeight.GetSpan() >= vehicleHeight;
}
if (rightPassable)
{
@@ -253,9 +250,9 @@ namespace NavisworksTransport.PathPlanning
{
var bottomCell = gridMap.Cells[x, y + 1];
bool bottomPassable = bottomCell.IsWalkable;
- if (bottomPassable && bottomCell.PassableHeights != null && bottomCell.PassableHeights.Any())
+ if (bottomPassable && bottomCell.PassableHeight.MaxZ > bottomCell.PassableHeight.MinZ)
{
- bottomPassable = bottomCell.PassableHeights.Any(interval => interval.GetSpan() >= vehicleHeight);
+ bottomPassable = bottomCell.PassableHeight.GetSpan() >= vehicleHeight;
}
if (bottomPassable)
{
@@ -368,10 +365,10 @@ namespace NavisworksTransport.PathPlanning
// 检查基本可通行性和高度约束
bool isPassable = cell.IsWalkable;
- if (isPassable && cell.PassableHeights != null && cell.PassableHeights.Any())
+ if (isPassable && cell.PassableHeight.MaxZ > cell.PassableHeight.MinZ)
{
// vehicleHeight已经是模型单位,直接比较即可
- bool heightOk = cell.PassableHeights.Any(interval => interval.GetSpan() >= vehicleHeight);
+ bool heightOk = cell.PassableHeight.GetSpan() >= vehicleHeight;
if (!heightOk)
{
heightConstrainedCells++;
@@ -500,10 +497,10 @@ namespace NavisworksTransport.PathPlanning
if (!cell.IsWalkable)
return false;
- if (cell.PassableHeights != null && cell.PassableHeights.Any())
+ if (cell.PassableHeight.MaxZ > cell.PassableHeight.MinZ)
{
// vehicleHeight已经是模型单位,直接比较即可
- return cell.PassableHeights.Any(interval => interval.GetSpan() >= vehicleHeight);
+ return cell.PassableHeight.GetSpan() >= vehicleHeight;
}
return false;
@@ -1074,80 +1071,6 @@ namespace NavisworksTransport.PathPlanning
return turns;
}
- ///
- /// 对最终路径点应用精确高度校正,使路径点贴合通道表面
- ///
- /// 重要:使用GetChannelTopHeight确保车辆路径点位于正确的行驶表面
- /// - 楼板类通道:校正到楼板顶面(行驶面)而非底面
- /// - 走廊类通道:校正到可行驶的表面高度
- ///
- /// 原始路径点
- /// 网格地图(包含通道信息,通道可能是楼板、走廊等)
- /// 高度校正后的路径点
- private List ApplyPreciseHeightCorrection(List path, GridMap gridMap)
- {
- try
- {
- LogManager.Info($"[高度校正] 开始对 {path.Count} 个路径点进行精确高度校正");
-
- // 如果没有通道数据,直接返回原路径
- if (gridMap.ChannelItems == null || !gridMap.ChannelItems.Any())
- {
- LogManager.Info("[高度校正] 无通道数据,跳过高度校正");
- return path;
- }
-
- // 确保高度检测器可用
- if (gridMap.HeightDetector == null)
- {
- LogManager.Warning("[高度校正] 高度检测器不可用,跳过高度校正");
- return path;
- }
-
- var correctedPath = new List();
- int correctedCount = 0;
-
- for (int i = 0; i < path.Count; i++)
- {
- var originalPoint = path[i];
-
- try
- {
- // 🔥 关键修改:使用GetChannelTopHeight获取通道顶面高度,而不是底面高度
- // 因为通道是楼板,车辆应该在楼板顶面行驶
- var preciseHeight = gridMap.HeightDetector.GetChannelTopHeight(originalPoint, gridMap.ChannelItems);
-
- // 检查高度是否需要校正(容差1cm)
- const double heightTolerance = 0.01; // 1cm
- if (Math.Abs(originalPoint.Z - preciseHeight) > heightTolerance)
- {
- var correctedPoint = new Point3D(originalPoint.X, originalPoint.Y, preciseHeight);
- correctedPath.Add(correctedPoint);
- correctedCount++;
- }
- else
- {
- // 高度已经正确,无需校正
- correctedPath.Add(originalPoint);
- }
- }
- catch (Exception ex)
- {
- // 如果某个点的高度检测失败,使用原始点
- LogManager.Warning($"[高度校正] 点{i}高度校正失败: {ex.Message},使用原始高度");
- correctedPath.Add(originalPoint);
- }
- }
-
- LogManager.Info($"[高度校正] 高度校正完成,共校正了 {correctedCount}/{path.Count} 个点");
- return correctedPath;
- }
- catch (Exception ex)
- {
- LogManager.Error($"[高度校正] 路径高度校正失败: {ex.Message},返回原始路径");
- return path;
- }
- }
///
/// 修正路径的起点和终点为原始用户指定的坐标,避免网格转换造成的错位
@@ -1232,22 +1155,19 @@ namespace NavisworksTransport.PathPlanning
}
// 检查高度约束
- if (cell.PassableHeights != null && cell.PassableHeights.Any())
+ if (cell.PassableHeight.MaxZ > cell.PassableHeight.MinZ)
{
- foreach (var interval in cell.PassableHeights)
- {
- bool spanOk = interval.GetSpan() >= vehicleHeight;
- // 将绝对坐标转换为相对于网格底面的坐标
- double relativeZ = point.Z - cell.WorldPosition.Z;
- bool containsHeight = interval.Contains(relativeZ);
+ bool spanOk = cell.PassableHeight.GetSpan() >= vehicleHeight;
+ // 将绝对坐标转换为相对于网格底面的坐标
+ double relativeZ = point.Z - cell.WorldPosition.Z;
+ bool containsHeight = cell.PassableHeight.Contains(relativeZ);
- if (spanOk && containsHeight)
- {
- return true;
- }
+ if (spanOk && containsHeight)
+ {
+ return true;
}
- LogManager.Warning($"[高度检查] ❌ 所有高度区间都不满足要求");
+ LogManager.Warning($"[高度检查] ❌ 高度区间不满足要求");
return false;
}
@@ -1278,7 +1198,7 @@ namespace NavisworksTransport.PathPlanning
{
var gridPos = gridMap.WorldToGrid(point);
- // 检查网格有效性
+ // 检查网格位置有效性
if (!gridMap.IsValidGridPosition(gridPos))
{
adjustedPath.Add(point);
@@ -1287,13 +1207,18 @@ namespace NavisworksTransport.PathPlanning
var cell = gridMap.Cells[gridPos.X, gridPos.Y];
- var bestInterval = cell.PassableHeights
- .Where(interval => interval.GetSpan() >= vehicleHeight)
- .OrderBy(interval => interval.MinZ)
- .FirstOrDefault();
-
- var optimalZ = cell.WorldPosition.Z + bestInterval.MinZ;
- adjustedPath.Add(new Point3D(point.X, point.Y, optimalZ));
+ // 检查单个高度区间是否满足车辆高度要求
+ if (cell.PassableHeight.GetSpan() >= vehicleHeight)
+ {
+ // 使用高度区间的底部作为最优Z坐标
+ var optimalZ = cell.WorldPosition.Z + cell.PassableHeight.MinZ;
+ adjustedPath.Add(new Point3D(point.X, point.Y, optimalZ));
+ }
+ else
+ {
+ // 高度不足,保持原始点
+ adjustedPath.Add(point);
+ }
adjustedCount++;
}
@@ -1600,10 +1525,10 @@ namespace NavisworksTransport.PathPlanning
// 检查基本可通行性和高度约束
bool isPassable = cell.IsWalkable;
- if (isPassable && cell.PassableHeights != null && cell.PassableHeights.Any())
+ if (isPassable && cell.PassableHeight.MaxZ > cell.PassableHeight.MinZ)
{
// vehicleHeight已经是模型单位,直接比较即可
- bool heightOk = cell.PassableHeights.Any(interval => interval.GetSpan() >= vehicleHeight);
+ bool heightOk = cell.PassableHeight.GetSpan() >= vehicleHeight;
if (!heightOk)
{
heightConstrainedCells++;
diff --git a/src/PathPlanning/ChannelBasedGridBuilder.cs b/src/PathPlanning/ChannelBasedGridBuilder.cs
index 922e34b..a0be163 100644
--- a/src/PathPlanning/ChannelBasedGridBuilder.cs
+++ b/src/PathPlanning/ChannelBasedGridBuilder.cs
@@ -225,7 +225,7 @@ namespace NavisworksTransport.PathPlanning
IsWalkable = true,
CellType = CategoryAttributeManager.LogisticsElementType.通道,
IsInChannel = true,
- PassableHeights = new List(),
+ PassableHeight = new HeightInterval(),
ChannelType = ChannelType.Corridor,
WorldPosition = new Point3D(worldPos.X, worldPos.Y, gridCenterHeight),
RelatedModelItem = null
diff --git a/src/PathPlanning/GridMap.cs b/src/PathPlanning/GridMap.cs
index a8f0cb8..32105ee 100644
--- a/src/PathPlanning/GridMap.cs
+++ b/src/PathPlanning/GridMap.cs
@@ -163,7 +163,7 @@ namespace NavisworksTransport.PathPlanning
IsWalkable = false,
CellType = CategoryAttributeManager.LogisticsElementType.Unknown, // 修改:默认为未知/空洞类型
IsInChannel = false,
- PassableHeights = new List(),
+ PassableHeight = new HeightInterval(),
ChannelType = ChannelType.Other,
WorldPosition = worldPos
};
@@ -256,7 +256,7 @@ namespace NavisworksTransport.PathPlanning
IsWalkable = isWalkable,
CellType = cellType,
IsInChannel = cellType == CategoryAttributeManager.LogisticsElementType.通道,
- PassableHeights = new List(),
+ PassableHeight = new HeightInterval(),
ChannelType = cellType == CategoryAttributeManager.LogisticsElementType.通道 ? ChannelType.Corridor : ChannelType.Other,
WorldPosition = worldPos
};
@@ -277,26 +277,6 @@ namespace NavisworksTransport.PathPlanning
Cells[gridPosition.X, gridPosition.Y] = cell;
}
-
- ///
- /// 添加可通行高度区间到指定网格单元
- ///
- /// 网格坐标
- /// 高度区间
- public void AddPassableHeight(GridPoint2D gridPosition, HeightInterval heightInterval)
- {
- if (!IsValidGridPosition(gridPosition))
- return;
-
- var cell = Cells[gridPosition.X, gridPosition.Y];
- if (cell.PassableHeights == null)
- {
- cell.PassableHeights = new List();
- }
- cell.PassableHeights.Add(heightInterval);
- Cells[gridPosition.X, gridPosition.Y] = cell;
- }
-
///
/// 检查指定位置在指定高度是否可通行
///
@@ -312,12 +292,8 @@ namespace NavisworksTransport.PathPlanning
if (!cell.IsWalkable)
return false;
- // 如果没有设置高度区间,使用传统的可通行性判断
- if (cell.PassableHeights == null || !cell.PassableHeights.Any())
- return true;
-
// 检查是否有任何高度区间包含指定高度
- return cell.PassableHeights.Any(interval => interval.Contains(height));
+ return (cell.PassableHeight.MaxZ - cell.PassableHeight.MinZ) >= height;
}
///
@@ -589,7 +565,7 @@ namespace NavisworksTransport.PathPlanning
///
/// 可通行高度区间列表 - 支持2.5D路径规划
///
- public List PassableHeights { get; set; }
+ public HeightInterval PassableHeight { get; set; }
///
/// 通道类型 - 用于区分不同类型的通道
@@ -650,7 +626,7 @@ namespace NavisworksTransport.PathPlanning
IsWalkable = false,
CellType = CategoryAttributeManager.LogisticsElementType.障碍物,
IsInChannel = false,
- PassableHeights = new List(),
+ PassableHeight = new HeightInterval(),
ChannelType = ChannelType.Other
};
cell.Cost = cell.GetCost();
@@ -668,7 +644,7 @@ namespace NavisworksTransport.PathPlanning
IsWalkable = true,
CellType = CategoryAttributeManager.LogisticsElementType.楼板,
IsInChannel = false,
- PassableHeights = new List(),
+ PassableHeight = new HeightInterval(),
ChannelType = ChannelType.Other
};
cell.Cost = cell.GetCost();
@@ -687,7 +663,7 @@ namespace NavisworksTransport.PathPlanning
IsWalkable = isOpen,
CellType = CategoryAttributeManager.LogisticsElementType.门,
IsInChannel = isOpen,
- PassableHeights = new List(),
+ PassableHeight = new HeightInterval(),
ChannelType = ChannelType.Other
};
cell.Cost = cell.GetCost();
@@ -706,7 +682,7 @@ namespace NavisworksTransport.PathPlanning
IsWalkable = true,
CellType = CategoryAttributeManager.LogisticsElementType.通道,
IsInChannel = true,
- PassableHeights = new List(),
+ PassableHeight = new HeightInterval(),
ChannelType = channelType
};
cell.Cost = cell.GetCost();
diff --git a/src/PathPlanning/GridMapGenerator.cs b/src/PathPlanning/GridMapGenerator.cs
index b7addde..91170e6 100644
--- a/src/PathPlanning/GridMapGenerator.cs
+++ b/src/PathPlanning/GridMapGenerator.cs
@@ -298,10 +298,7 @@ namespace NavisworksTransport.PathPlanning
// 将门的高度范围存储在PassableHeights中供后续使用(使用相对坐标)
if (doorHeight > 0)
{
- cell.PassableHeights = new List
- {
- new HeightInterval(0, doorHeight)
- };
+ cell.PassableHeight = new HeightInterval(0, doorHeight);
}
// 将修改后的结构体设置回数组
@@ -343,10 +340,7 @@ namespace NavisworksTransport.PathPlanning
var cell = gridMap.Cells[x, y];
if (cell.IsWalkable)
{
- cell.PassableHeights = new List
- {
- new HeightInterval(0, scanHeightInModelUnits)
- };
+ cell.PassableHeight = new HeightInterval(0, scanHeightInModelUnits);
gridMap.Cells[x, y] = cell;
processedCount++;
}
@@ -461,12 +455,7 @@ namespace NavisworksTransport.PathPlanning
///
/// 网格地图
/// 高度区间数据
- ///
- /// 将高度区间信息集成到网格地图中
- ///
- /// 网格地图
- /// 高度区间数据
- private void IntegrateHeightIntervalsToGrid(GridMap gridMap, Dictionary> heightIntervals)
+ private void IntegrateHeightIntervalsToGrid(GridMap gridMap, Dictionary heightIntervals)
{
int updatedCells = 0;
int channelCellsWithHeightData = 0;
@@ -475,44 +464,39 @@ namespace NavisworksTransport.PathPlanning
foreach (var kvp in heightIntervals)
{
var point = kvp.Key;
- var intervals = kvp.Value;
-
+ var interval = kvp.Value;
+
// 将世界坐标转换为网格坐标
var gridPos = gridMap.WorldToGrid(new Point3D(point.X, point.Y, 0));
int gridX = gridPos.X;
int gridY = gridPos.Y;
-
+
// 确保坐标在有效范围内
if (gridX >= 0 && gridX < gridMap.Width && gridY >= 0 && gridY < gridMap.Height)
{
// 更新网格单元格的高度区间信息
var cell = gridMap.Cells[gridX, gridY];
-
- if (cell.PassableHeights == null)
- {
- cell.PassableHeights = new List();
- }
-
- cell.PassableHeights.Clear();
- cell.PassableHeights.AddRange(intervals);
+
+ // 直接设置高度区间
+ cell.PassableHeight = interval;
// 关键修复:只处理通道单元格的高度信息集成
// 非通道单元格不应该通过高度扫描而改变其类型或可通行性
if (cell.CellType == CategoryAttributeManager.LogisticsElementType.通道 && cell.IsInChannel)
{
channelCellsWithHeightData++;
-
- if (intervals.Any())
+
+ if (interval.MaxZ > interval.MinZ)
{
// 通道区域有足够净空高度,设置为可通行
// 🔥 关键修复:使用SetCell方法正确更新网格统计
var cellPos = new GridPoint2D(gridX, gridY);
gridMap.SetCell(cellPos, true, 1.0, CategoryAttributeManager.LogisticsElementType.通道);
-
+
// 设置世界坐标和高度信息
var updatedCell = gridMap.Cells[gridX, gridY];
updatedCell.WorldPosition = point;
- updatedCell.PassableHeights = new List(intervals);
+ updatedCell.PassableHeight = interval;
updatedCell.IsInChannel = true;
gridMap.Cells[gridX, gridY] = updatedCell;
}
@@ -521,14 +505,14 @@ namespace NavisworksTransport.PathPlanning
// 通道区域但净空高度不足,标记为不可通行但保持通道类型
var cellPos = new GridPoint2D(gridX, gridY);
gridMap.SetCell(cellPos, false, double.MaxValue, CategoryAttributeManager.LogisticsElementType.通道);
-
+
// 设置世界坐标和高度信息
var updatedCell = gridMap.Cells[gridX, gridY];
updatedCell.WorldPosition = point;
- updatedCell.PassableHeights = new List(intervals);
+ updatedCell.PassableHeight = interval;
updatedCell.IsInChannel = true;
gridMap.Cells[gridX, gridY] = updatedCell;
-
+
channelCellsBecomingUnwalkable++;
}
}
@@ -540,7 +524,7 @@ namespace NavisworksTransport.PathPlanning
// 仍然更新高度信息,但保持原有状态
cell.WorldPosition = point;
- cell.PassableHeights = new List(intervals);
+ cell.PassableHeight = interval;
gridMap.Cells[gridX, gridY] = cell;
}
updatedCells++;
@@ -1259,14 +1243,11 @@ namespace NavisworksTransport.PathPlanning
cell.RelatedModelItem = update.Item;
// 记录高度信息
- if (cell.PassableHeights == null)
- cell.PassableHeights = new List();
-
var groundHeight = cell.WorldPosition.Z;
- cell.PassableHeights.Add(new HeightInterval(
+ cell.PassableHeight = new HeightInterval(
update.BoundingBox.Min.Z - groundHeight,
update.BoundingBox.Max.Z - groundHeight
- ));
+ );
gridMap.Cells[update.X, update.Y] = cell;
updatedCells++;
diff --git a/src/PathPlanning/VerticalScanProcessor.cs b/src/PathPlanning/VerticalScanProcessor.cs
index 62d15d5..aa1549b 100644
--- a/src/PathPlanning/VerticalScanProcessor.cs
+++ b/src/PathPlanning/VerticalScanProcessor.cs
@@ -280,8 +280,8 @@ namespace NavisworksTransport.PathPlanning
/// 网格点列表
/// 扫描高度(从地面向上的距离)
/// 车辆高度(用于通行检查)
- /// 每个网格点的高度区间列表
- public Dictionary> ParallelScanHeightIntervals(
+ /// 每个网格点的高度区间
+ public Dictionary ParallelScanHeightIntervals(
IEnumerable gridPoints,
double scanHeight = 20.0,
double vehicleHeight = 3.0)
@@ -289,7 +289,7 @@ namespace NavisworksTransport.PathPlanning
LogManager.Info($"[垂直扫描处理器] 开始并行扫描高度区间,扫描高度: {scanHeight}m, 车辆高度: {vehicleHeight}m");
var startTime = DateTime.Now;
- var results = new ConcurrentDictionary>();
+ var results = new ConcurrentDictionary();
var pointsList = gridPoints?.ToList() ?? new List();
LogManager.Info($"[垂直扫描处理器] 准备处理{pointsList.Count}个点");
@@ -307,8 +307,8 @@ namespace NavisworksTransport.PathPlanning
{
if (gridPoint != null)
{
- var intervals = ScanVerticalLine(gridPoint, scanHeight, vehicleHeight);
- results[gridPoint] = intervals ?? new List();
+ var interval = ScanVerticalLine(gridPoint, scanHeight, vehicleHeight);
+ results[gridPoint] = interval;
}
}
catch (OutOfMemoryException)
@@ -316,7 +316,7 @@ namespace NavisworksTransport.PathPlanning
LogManager.Error($"[垂直扫描处理器] 内存不足,跳过点 {gridPoint}");
if (gridPoint != null)
{
- results[gridPoint] = new List();
+ results[gridPoint] = new HeightInterval();
}
throw; // 内存不足需要重新抛出
}
@@ -325,7 +325,7 @@ namespace NavisworksTransport.PathPlanning
LogManager.Error($"[垂直扫描处理器] 扫描点 {gridPoint} 失败: {ex.Message}");
if (gridPoint != null)
{
- results[gridPoint] = new List();
+ results[gridPoint] = new HeightInterval();
}
}
});
@@ -342,8 +342,8 @@ namespace NavisworksTransport.PathPlanning
{
if (gridPoint != null && !results.ContainsKey(gridPoint))
{
- var intervals = ScanVerticalLine(gridPoint, scanHeight, vehicleHeight);
- results[gridPoint] = intervals ?? new List();
+ var interval = ScanVerticalLine(gridPoint, scanHeight, vehicleHeight);
+ results[gridPoint] = interval;
}
}
catch (Exception serialEx)
@@ -351,14 +351,14 @@ namespace NavisworksTransport.PathPlanning
LogManager.Error($"[垂直扫描处理器] 串行扫描点 {gridPoint} 也失败: {serialEx.Message}");
if (gridPoint != null)
{
- results[gridPoint] = new List();
+ results[gridPoint] = new HeightInterval();
}
}
}
}
var elapsed = (DateTime.Now - startTime).TotalMilliseconds;
- var totalIntervals = results.Values.Sum(list => list.Count);
+ var validIntervals = results.Values.Count(interval => interval.MaxZ > interval.MinZ);
// 输出缓存统计信息
if (_cacheHits + _cacheMisses > 0)
@@ -367,14 +367,14 @@ namespace NavisworksTransport.PathPlanning
LogManager.Info($"[垂直扫描处理器] 缓存统计 - 命中: {_cacheHits}, 未命中: {_cacheMisses}, 命中率: {hitRate:F1}%, 缓存大小: {_candidateCache.Count}");
}
- LogManager.Info($"[垂直扫描处理器] 并行扫描完成,耗时: {elapsed:F1}ms, 扫描点: {pointsList.Count}, 总区间: {totalIntervals}");
+ LogManager.Info($"[垂直扫描处理器] 并行扫描完成,耗时: {elapsed:F1}ms, 扫描点: {pointsList.Count}, 有效区间: {validIntervals}");
// 清理缓存,为下次扫描做准备
_candidateCache.Clear();
_cacheHits = 0;
_cacheMisses = 0;
- return new Dictionary>(results);
+ return new Dictionary(results);
}
///
@@ -383,8 +383,8 @@ namespace NavisworksTransport.PathPlanning
/// 基础点(X,Y坐标)
/// 扫描高度
/// 车辆高度
- /// 可通行的高度区间列表
- public List ScanVerticalLine(Point3D basePoint, double scanHeight, double vehicleHeight)
+ /// 可通行的高度区间
+ public HeightInterval ScanVerticalLine(Point3D basePoint, double scanHeight, double vehicleHeight)
{
// 第一级筛选:邻域筛选 - 获取空间哈希邻域内的候选项
var candidateItems = GetCandidateItemsFromSpatialHash(basePoint);
@@ -396,9 +396,9 @@ namespace NavisworksTransport.PathPlanning
var intersectionResults = PerformIntersectionTests(heightFilteredItems, basePoint, scanHeight);
// 计算可通行区间
- var passableIntervals = CalculatePassableIntervals(intersectionResults, basePoint.Z, scanHeight, vehicleHeight);
+ var passableInterval = CalculatePassableInterval(intersectionResults, basePoint.Z, scanHeight, vehicleHeight);
- return passableIntervals;
+ return passableInterval;
}
@@ -625,8 +625,8 @@ namespace NavisworksTransport.PathPlanning
/// 基础Z坐标
/// 扫描高度
/// 车辆高度
- /// 可通行区间列表
- private List CalculatePassableIntervals(
+ /// 可通行区间
+ private HeightInterval CalculatePassableInterval(
List intersectionResults,
double baseZ,
double scanHeight,
@@ -664,8 +664,8 @@ namespace NavisworksTransport.PathPlanning
// 合并重叠的障碍物区间
var mergedObstacles = MergeOverlappingIntervals(obstacles);
- // 计算可通行区间
- var passableIntervals = new List();
+ // 计算最优可通行区间(取最大的一个)
+ HeightInterval bestInterval = new HeightInterval();
var scanRange = new HeightInterval(baseZ, baseZ + scanHeight);
// 如果没有找到地面,使用基础Z坐标作为默认地面
@@ -674,7 +674,7 @@ namespace NavisworksTransport.PathPlanning
floors.Add(new HeightInterval(baseZ - 0.1, baseZ + 0.1));
}
- // 对每个潜在的地面,计算其上方的可通行空间
+ // 对每个潜在的地面,计算其上方的可通行空间,取最大的
foreach (var floor in floors)
{
double floorTop = floor.MaxZ;
@@ -694,18 +694,21 @@ namespace NavisworksTransport.PathPlanning
if (clearHeight >= MIN_PASSABLE_HEIGHT)
{
var interval = new HeightInterval(floorTop, availableTop);
- passableIntervals.Add(interval);
+ if (interval.MaxZ - interval.MinZ > bestInterval.MaxZ - bestInterval.MinZ)
+ {
+ bestInterval = interval;
+ }
}
}
else
{
- // 有障碍物,计算障碍物之间的可通行空间
+ // 有障碍物,计算障碍物之间的可通行空间,取最大的
double currentBottom = floorTop;
-
+
foreach (var obstacle in conflictingObstacles)
{
double obstacleBottom = Math.Max(obstacle.MinZ, currentBottom);
-
+
if (obstacleBottom > currentBottom)
{
double clearHeight = obstacleBottom - currentBottom;
@@ -713,13 +716,16 @@ namespace NavisworksTransport.PathPlanning
if (clearHeight >= vehicleHeight)
{
var interval = new HeightInterval(currentBottom, obstacleBottom);
- passableIntervals.Add(interval);
+ if (interval.MaxZ - interval.MinZ > bestInterval.MaxZ - bestInterval.MinZ)
+ {
+ bestInterval = interval;
+ }
}
}
-
+
currentBottom = Math.Max(currentBottom, obstacle.MaxZ);
}
-
+
// 检查最后一个障碍物之后的空间
if (currentBottom < availableTop)
{
@@ -728,13 +734,16 @@ namespace NavisworksTransport.PathPlanning
if (clearHeight >= vehicleHeight)
{
var interval = new HeightInterval(currentBottom, availableTop);
- passableIntervals.Add(interval);
+ if (interval.MaxZ - interval.MinZ > bestInterval.MaxZ - bestInterval.MinZ)
+ {
+ bestInterval = interval;
+ }
}
}
}
}
- return passableIntervals;
+ return bestInterval;
}
#endregion