diff --git a/src/PathPlanning/GridMapGenerator.cs b/src/PathPlanning/GridMapGenerator.cs
index 09e8911..7880466 100644
--- a/src/PathPlanning/GridMapGenerator.cs
+++ b/src/PathPlanning/GridMapGenerator.cs
@@ -62,11 +62,23 @@ namespace NavisworksTransport.PathPlanning
{
LogManager.Info("【生成网格地图】开始生成网格地图");
var startTime = DateTime.Now;
-
- // 重要:将米制网格大小转换为模型单位
+
+ // 第一步:统一转换所有米制参数为模型单位
double metersToModelUnitsConversionFactor = UnitsConverter.GetMetersToUnitsConversionFactor(Application.ActiveDocument.Units);
double cellSizeInModelUnits = cellSize * metersToModelUnitsConversionFactor;
- LogManager.Info($"【生成网格地图】网格大小单位转换: {cellSize}米 → {cellSizeInModelUnits:F2}模型单位 (转换系数: {metersToModelUnitsConversionFactor:F2})");
+ 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: 构建通道覆盖网格");
@@ -88,15 +100,14 @@ namespace NavisworksTransport.PathPlanning
// 2. 直接遍历处理障碍物(包围盒检测) - 使用高性能优化版本
LogManager.Info("【生成网格地图】步骤2: 高性能包围盒遍历处理障碍物");
- double scanHeight = vehicleHeight + safetyMargin; // 扫描高度 = 车辆高度 + 安全间隙
- double minChannelTopZ = channelCoverage.MinChannelTopZ; // 提取最小通道顶面高度
- ProcessObstaclesWithBoundingBoxOptimized(document, channelCoverage.GridMap, channelRelatedItems, scanHeight, minChannelTopZ);
+ double minChannelTopZ = channelCoverage.MinChannelTopZ; // 提取最小通道顶面高度(模型单位)
+ ProcessObstaclesWithBoundingBoxOptimized(document, channelCoverage.GridMap, channelRelatedItems, scanHeightInModelUnits, minChannelTopZ);
LogManager.Info($"【阶段2完成】障碍物处理后网格统计: {channelCoverage.GridMap.GetStatistics()}");
// 2.5. 为所有可通行网格设置PassableHeights确保高度约束检查
LogManager.Info("【生成网格地图】步骤2.5: 为可通行网格设置高度约束");
- SetChannelPassableHeights(channelCoverage.GridMap, scanHeight);
+ SetChannelPassableHeights(channelCoverage.GridMap, scanHeightInModelUnits);
LogManager.Info($"【阶段2.5完成】高度约束设置后网格统计: {channelCoverage.GridMap.GetStatistics()}");
// 2.6. 单独处理门元素,设置为可通行,并设置通行高度
@@ -108,10 +119,8 @@ namespace NavisworksTransport.PathPlanning
if (vehicleRadius > 0 || safetyMargin > 0)
{
LogManager.Info("【生成网格地图】步骤3: 应用车辆膨胀");
- double metersToModelUnits = UnitsConverter.GetMetersToUnitsConversionFactor(Application.ActiveDocument.Units);
- double totalInflationRadius = (vehicleRadius + safetyMargin) * metersToModelUnits;
- ApplyVehicleInflation(channelCoverage.GridMap, totalInflationRadius);
- LogManager.Info($"【生成网格地图】车辆膨胀完成,膨胀半径: {totalInflationRadius:F2}模型单位");
+ ApplyVehicleInflation(channelCoverage.GridMap, totalInflationRadiusInModelUnits);
+ LogManager.Info($"【生成网格地图】车辆膨胀完成,膨胀半径: {totalInflationRadiusInModelUnits:F2}模型单位");
LogManager.Info($"【阶段3完成】车辆膨胀后网格统计: {channelCoverage.GridMap.GetStatistics()}");
}
@@ -195,7 +204,7 @@ namespace NavisworksTransport.PathPlanning
// 获取门的限高属性
string heightLimitStr = CategoryAttributeManager.GetLogisticsPropertyValue(doorItem, CategoryAttributeManager.LogisticsProperties.HEIGHT_LIMIT);
- double configuredHeight = CategoryAttributeManager.ParseLogisticsLimitValue(heightLimitStr, "限高");
+ double configuredHeight = CategoryAttributeManager.ParseLogisticsLimitValue(heightLimitStr, "限高");
// 计算门的实际物理高度
double actualDoorHeight = bbox.Max.Z - bbox.Min.Z;
@@ -270,14 +279,10 @@ namespace NavisworksTransport.PathPlanning
/// 为所有可通行网格设置PassableHeights确保高度约束检查
///
/// 网格地图
- /// 扫描高度(车辆高度+安全间隙)
- private void SetChannelPassableHeights(GridMap gridMap, double scanHeight)
+ /// 扫描高度(模型单位)
+ private void SetChannelPassableHeights(GridMap gridMap, double scanHeightInModelUnits)
{
- // scanHeight是米,需要转换为模型单位
- double metersToModelUnits = UnitsConverter.GetMetersToUnitsConversionFactor(Application.ActiveDocument.Units);
- double scanHeightInModelUnits = scanHeight * metersToModelUnits;
-
- LogManager.Info($"【高度约束设置】开始为所有可通行网格设置高度约束,扫描高度: {scanHeight:F2}米 ({scanHeightInModelUnits:F2}模型单位)");
+ LogManager.Info($"【高度约束设置】开始为所有可通行网格设置高度约束,扫描高度: {scanHeightInModelUnits:F2}模型单位");
int processedCount = 0;
for (int x = 0; x < gridMap.Width; x++)
@@ -563,17 +568,17 @@ namespace NavisworksTransport.PathPlanning
/// 在障碍物周围扩展不可通行区域,考虑车辆尺寸
///
/// 网格地图
- /// 车辆半径
- public void ApplyVehicleInflation(GridMap gridMap, double vehicleRadius)
+ /// 车辆半径(模型单位)
+ private void ApplyVehicleInflation(GridMap gridMap, double vehicleRadiusInModelUnits)
{
- if (vehicleRadius <= 0) return;
+ if (vehicleRadiusInModelUnits <= 0) return;
try
- {
+ {
// 计算膨胀半径(网格单元格数)
- int inflationRadius = (int)Math.Ceiling(vehicleRadius / gridMap.CellSize);
+ int inflationRadius = (int)Math.Ceiling(vehicleRadiusInModelUnits / gridMap.CellSize);
LogManager.Info($"[高效膨胀] 膨胀半径: {inflationRadius}个网格单元");
-
+
// 使用高效的距离变换算法
ApplyVehicleInflationOptimized(gridMap, inflationRadius);
}
@@ -977,7 +982,7 @@ namespace NavisworksTransport.PathPlanning
List geometryItems,
HashSet channelItemsSet,
GridMap gridMap,
- double scanHeight,
+ double scanHeightInModelUnits,
double minChannelTopZ)
{
LogManager.Info("[轻量级后处理] 开始处理Search API筛选结果");
@@ -1038,7 +1043,7 @@ namespace NavisworksTransport.PathPlanning
}
// 快速计算:高度范围检查(纯数值计算,无API调用)
- properties.IsInScanHeightRange = IsInScanHeightRange(properties.BoundingBox, minChannelTopZ, scanHeight);
+ properties.IsInScanHeightRange = IsInScanHeightRange(properties.BoundingBox, minChannelTopZ, scanHeightInModelUnits);
if (!properties.IsInScanHeightRange)
{
skippedByHeight++;
@@ -1068,9 +1073,9 @@ namespace NavisworksTransport.PathPlanning
/// Navisworks文档
/// 网格地图
/// 通道模型项列表
- /// 扫描高度范围
+ /// 扫描高度范围(模型单位)
/// 最小通道顶面高度,用作扫描基准
- private void ProcessObstaclesWithBoundingBoxOptimized(Document document, GridMap gridMap, HashSet channelItems, double scanHeight, double minChannelTopZ)
+ private void ProcessObstaclesWithBoundingBoxOptimized(Document document, GridMap gridMap, HashSet channelItems, double scanHeightInModelUnits, double minChannelTopZ)
{
try
{
@@ -1085,7 +1090,7 @@ namespace NavisworksTransport.PathPlanning
LogManager.Info($"[高性能障碍物处理] 输入统计 - 几何体项目: {geometryItems.Count}, 通道元素: {channelItemsSet.Count}");
// 阶段2:轻量级后处理(只对预筛选结果进行必要的API调用)
- var itemCache = PostProcessGeometryItems(geometryItems, channelItemsSet, gridMap, scanHeight, minChannelTopZ);
+ var itemCache = PostProcessGeometryItems(geometryItems, channelItemsSet, gridMap, scanHeightInModelUnits, minChannelTopZ);
// 阶段3:条件过滤(并行数值计算)- 使用50%CPU核心优化
LogManager.Info("[高性能障碍物处理] 阶段3: 并行条件过滤");
@@ -1354,16 +1359,16 @@ namespace NavisworksTransport.PathPlanning
/// 检查包围盒是否在扫描高度范围内
///
/// 包围盒
- /// 最小通道顶面高度,用作扫描基准
- /// 扫描高度范围
+ /// 最小通道顶面高度,用作扫描基准(模型单位)
+ /// 扫描高度范围(模型单位)
/// 是否在高度范围内
- private bool IsInScanHeightRange(BoundingBox3D bbox, double minChannelTopZ, double scanHeight)
+ private bool IsInScanHeightRange(BoundingBox3D bbox, double minChannelTopZ, double scanHeightInModelUnits)
{
try
{
// 使用最低通道顶面高度作为扫描基准,避免门高度干扰
- var scanMinZ = minChannelTopZ; // 最低通道顶面
- var scanMaxZ = minChannelTopZ + scanHeight; // 从最低通道顶面向上扫描
+ var scanMinZ = minChannelTopZ; // 最低通道顶面(模型单位)
+ var scanMaxZ = minChannelTopZ + scanHeightInModelUnits; // 从最低通道顶面向上扫描(模型单位)
// 检查包围盒的Z范围是否与扫描范围有重叠
return !(bbox.Max.Z < scanMinZ || bbox.Min.Z > scanMaxZ);