修改z值的判断为通道网格z值的最小和最大值

This commit is contained in:
tian 2025-09-29 10:48:21 +08:00
parent 37e7a31a55
commit e061ec4318
3 changed files with 112 additions and 39 deletions

View File

@ -96,14 +96,67 @@ namespace NavisworksTransport.PathPlanning
LogManager.Info($"[通道网格构建器] 成功投影 {processedChannels.Count}/{channelItems.Count} 个通道");
// 5. 计算可通行网格的Z值范围
var (walkableMinZ, walkableMaxZ, walkableCount) = CalculateWalkableGridZRange(gridMap);
return new ChannelCoverage
{
GridMap = gridMap,
ChannelItems = processedChannels,
TotalBounds = totalBounds
TotalBounds = totalBounds,
WalkableMinZ = walkableMinZ,
WalkableMaxZ = walkableMaxZ,
WalkableGridCount = walkableCount
};
}
/// <summary>
/// 计算可通行网格的Z值范围
/// 遍历所有可通行网格基于实际WorldPosition.Z坐标计算最小值和最大值
/// </summary>
/// <param name="gridMap">网格地图</param>
/// <returns>包含最小Z值、最大Z值和可通行网格数量的元组</returns>
private (double minZ, double maxZ, int walkableCount) CalculateWalkableGridZRange(GridMap gridMap)
{
double minZ = double.MaxValue;
double maxZ = double.MinValue;
int walkableCount = 0;
LogManager.Info("[通道Z值计算] 开始计算可通行网格Z值范围");
for (int x = 0; x < gridMap.Width; x++)
{
for (int y = 0; y < gridMap.Height; y++)
{
var cell = gridMap.Cells[x, y];
// 只计算可通行的网格
if (cell.IsWalkable)
{
walkableCount++;
double cellZ = cell.WorldPosition.Z;
if (cellZ < minZ)
minZ = cellZ;
if (cellZ > maxZ)
maxZ = cellZ;
}
}
}
// 如果没有可通行网格,返回默认值
if (walkableCount == 0)
{
LogManager.Warning("[通道Z值计算] 未找到可通行网格使用默认Z值范围");
minZ = 0.0;
maxZ = 0.0;
}
LogManager.Info($"[通道Z值计算] 计算完成 - 可通行网格: {walkableCount}个, Z范围: [{minZ:F2}, {maxZ:F2}], 高度差: {maxZ - minZ:F2}");
return (minZ, maxZ, walkableCount);
}
/// <summary>
/// 将通道投影到网格

View File

@ -788,6 +788,21 @@ namespace NavisworksTransport.PathPlanning
/// </summary>
public BoundingBox3D TotalBounds { get; set; }
/// <summary>
/// 可通行网格的最小Z坐标基于实际网格位置
/// </summary>
public double WalkableMinZ { get; set; } = double.MaxValue;
/// <summary>
/// 可通行网格的最大Z坐标基于实际网格位置
/// </summary>
public double WalkableMaxZ { get; set; } = double.MinValue;
/// <summary>
/// 可通行网格数量
/// </summary>
public int WalkableGridCount { get; set; } = 0;
/// <summary>
/// 获取统计信息
/// </summary>
@ -809,8 +824,12 @@ namespace NavisworksTransport.PathPlanning
}
}
var zRangeInfo = WalkableGridCount > 0
? $", Z范围: [{WalkableMinZ:F2}, {WalkableMaxZ:F2}], 可通行网格: {WalkableGridCount}个"
: ", Z范围: 未计算";
return $"通道覆盖统计: {ChannelItems.Count} 个通道物品, {channelCellCount} 个通道网格单元, " +
$"网格大小: {GridMap?.Width}x{GridMap?.Height}";
$"网格大小: {GridMap?.Width}x{GridMap?.Height}{zRangeInfo}";
}
}

View File

@ -57,8 +57,25 @@ namespace NavisworksTransport.PathPlanning
{
try
{
// 生成缓存键
var cacheKey = GridMapCacheKey.CreateFrom(bounds, cellSize, vehicleRadius, safetyMargin, vehicleHeight);
// 第一步:统一转换所有米制参数为模型单位
double metersToModelUnitsConversionFactor = UnitsConverter.GetMetersToUnitsConversionFactor(Application.ActiveDocument.Units);
double cellSizeInModelUnits = cellSize * metersToModelUnitsConversionFactor;
double vehicleRadiusInModelUnits = vehicleRadius * metersToModelUnitsConversionFactor;
double safetyMarginInModelUnits = safetyMargin * metersToModelUnitsConversionFactor;
double vehicleHeightInModelUnits = vehicleHeight * metersToModelUnitsConversionFactor;
double scanHeightInModelUnits = vehicleHeightInModelUnits + safetyMarginInModelUnits; // 扫描高度 = 车辆高度 + 安全间隙
double totalInflationRadiusInModelUnits = vehicleRadiusInModelUnits + safetyMarginInModelUnits; // 膨胀半径 = 车辆半径 + 安全间隙
LogManager.Info($"【生成网格地图】参数单位转换完成 (转换系数: {metersToModelUnitsConversionFactor:F2}):");
LogManager.Info($" 网格大小: {cellSize}米 → {cellSizeInModelUnits:F2}模型单位");
LogManager.Info($" 车辆半径: {vehicleRadius}米 → {vehicleRadiusInModelUnits:F2}模型单位");
LogManager.Info($" 安全间隙: {safetyMargin}米 → {safetyMarginInModelUnits:F2}模型单位");
LogManager.Info($" 车辆高度: {vehicleHeight}米 → {vehicleHeightInModelUnits:F2}模型单位");
LogManager.Info($" 扫描高度: {scanHeightInModelUnits:F2}模型单位");
LogManager.Info($" 膨胀半径: {totalInflationRadiusInModelUnits:F2}模型单位");
// 生成缓存键(使用转换后的模型单位参数确保一致性)
var cacheKey = GridMapCacheKey.CreateFrom(bounds, cellSizeInModelUnits, vehicleRadiusInModelUnits, safetyMarginInModelUnits, vehicleHeightInModelUnits);
// 尝试从缓存获取
var cachedGridMap = GlobalGridMapCache.Instance.Get(cacheKey, 5000); // 预估生成需要5秒
@ -83,23 +100,6 @@ namespace NavisworksTransport.PathPlanning
LogManager.Info($"【生成网格地图】缓存键: {cacheKey}");
var startTime = DateTime.Now;
// 第一步:统一转换所有米制参数为模型单位
double metersToModelUnitsConversionFactor = UnitsConverter.GetMetersToUnitsConversionFactor(Application.ActiveDocument.Units);
double cellSizeInModelUnits = cellSize * metersToModelUnitsConversionFactor;
double vehicleRadiusInModelUnits = vehicleRadius * metersToModelUnitsConversionFactor;
double safetyMarginInModelUnits = safetyMargin * metersToModelUnitsConversionFactor;
double vehicleHeightInModelUnits = vehicleHeight * metersToModelUnitsConversionFactor;
double scanHeightInModelUnits = vehicleHeightInModelUnits + safetyMarginInModelUnits; // 扫描高度 = 车辆高度 + 安全间隙
double totalInflationRadiusInModelUnits = vehicleRadiusInModelUnits + safetyMarginInModelUnits; // 膨胀半径 = 车辆半径 + 安全间隙
LogManager.Info($"【生成网格地图】参数单位转换完成 (转换系数: {metersToModelUnitsConversionFactor:F2}):");
LogManager.Info($" 网格大小: {cellSize}米 → {cellSizeInModelUnits:F2}模型单位");
LogManager.Info($" 车辆半径: {vehicleRadius}米 → {vehicleRadiusInModelUnits:F2}模型单位");
LogManager.Info($" 安全间隙: {safetyMargin}米 → {safetyMarginInModelUnits:F2}模型单位");
LogManager.Info($" 车辆高度: {vehicleHeight}米 → {vehicleHeightInModelUnits:F2}模型单位");
LogManager.Info($" 扫描高度: {scanHeightInModelUnits:F2}模型单位");
LogManager.Info($" 膨胀半径: {totalInflationRadiusInModelUnits:F2}模型单位");
// 1. 使用通道构建器构建基础通道覆盖网格
LogManager.Info("【生成网格地图】步骤1: 构建通道覆盖网格");
var channelCoverage = _channelBuilder.BuildChannelCoverage(cellSizeInModelUnits);
@ -1069,13 +1069,14 @@ namespace NavisworksTransport.PathPlanning
{
try
{
var properties = new ItemProperties();
// 已知条件HasGeometry = trueSearch API保证
properties.HasGeometry = true;
// 快速筛除1通道相关项目HashSet查找极快
properties.IsChannelItem = channelItemsSet.Contains(item);
var properties = new ItemProperties
{
// 已知条件HasGeometry = trueSearch API保证
HasGeometry = true,
// 快速筛除1通道相关项目HashSet查找极快
IsChannelItem = channelItemsSet.Contains(item)
};
if (properties.IsChannelItem)
{
skippedByChannel++;
@ -1168,13 +1169,13 @@ namespace NavisworksTransport.PathPlanning
var filterElapsed = (DateTime.Now - filterStart).TotalMilliseconds;
LogManager.Info($"[高性能障碍物处理] 阶段3完成: 从缓存中筛选出 {validItems.Count} 个有效项,耗时: {filterElapsed:F1}ms");
// 获取通道高度范围信息
var channelBounds = channelCoverage.TotalBounds;
var channelMinZ = channelBounds.Min.Z;
var channelMaxZ = channelBounds.Max.Z;
var channelHeightRange = channelMaxZ - channelMinZ;
LogManager.Info($"[高性能障碍物处理] 通道高度信息 - 最低点: {channelMinZ:F2}, 最高点: {channelMaxZ:F2}");
LogManager.Info($"[高性能障碍物处理] 通道高度范围: {channelHeightRange:F2}, 加车辆高度后扫描范围: [{channelMinZ:F2}, {channelMaxZ + scanHeightInModelUnits:F2}]");
// 获取可通行网格的实际高度范围信息
var walkableMinZ = channelCoverage.WalkableMinZ;
var walkableMaxZ = channelCoverage.WalkableMaxZ;
var walkableGridCount = channelCoverage.WalkableGridCount;
var walkableHeightRange = walkableMaxZ - walkableMinZ;
LogManager.Info($"[高性能障碍物处理] 可通行网格高度信息 - 最低点: {walkableMinZ:F2}, 最高点: {walkableMaxZ:F2}");
LogManager.Info($"[高性能障碍物处理] 可通行网格数量: {walkableGridCount}, 高度范围: {walkableHeightRange:F2}, 加车辆高度后扫描范围: [{walkableMinZ:F2}, {walkableMaxZ + scanHeightInModelUnits:F2}]");
// 阶段4网格覆盖计算并行几何计算- 使用50%CPU核心优化 + 基于通道的精确高度检查
LogManager.Info("[高性能障碍物处理] 阶段4: 并行网格覆盖计算 + 基于通道高度的精确高度检查");
@ -1197,10 +1198,10 @@ namespace NavisworksTransport.PathPlanning
var centerCell = gridMap.Cells[centerGridPos.X, centerGridPos.Y];
// 使用通道高度范围计算扫描范围
// 扫描范围:从通道最低点开始,到通道最高点+车辆高度+安全间隙
var scanMin = channelMinZ;
var scanMax = channelMaxZ + scanHeightInModelUnits;
// 使用可通行网格高度范围计算扫描范围
// 扫描范围:从可通行网格最低点开始,到可通行网格最高点+车辆高度+安全间隙
var scanMin = walkableMinZ;
var scanMax = walkableMaxZ + scanHeightInModelUnits;
// 只有与该网格高度范围重叠的几何体才进入处理
bool isInRange = !(bbox.Max.Z <= scanMin || bbox.Min.Z > scanMax);