NavisworksTransport/doc/working/2025-01-08-multi-layer-gridmap-solution.md

195 lines
5.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 多高度层GridMap解决方案
**日期**: 2025-01-08
**问题**: 楼梯与楼板在同一(x,y)坐标重叠时2D网格投影导致互相覆盖
**目标**: 支持多高度层同时保留RoyT.AStar高性能算法
---
## 问题分析
### 场景描述
- **楼梯**: 倾斜通道,在(x,y)位置有不同Z高度
- **楼梯下方楼板**: 水平通道,在相同(x,y)位置也可通行
- **当前问题**: 两者投影到同一2D网格坐标(x,y),后处理的覆盖前处理的
### 核心矛盾
- 2D网格投影系统无法处理垂直空间层叠
- 起点在楼面(Z=3.0m),终点在楼梯(Z=5.0m)的路径无法正确规划
---
## 解决方案
### 核心思路
1. **保留RoyT.AStar**: 2D A*算法不变继续产生最优2D路径
2. **扩展数据结构**: GridCell支持多个HeightLayer
3. **投影改为追加**: 通道投影不覆盖,而是添加新层
4. **路径后处理选层**: A*产生2D路径后为每个路径点智能选择高度层
### 关键洞察
- **2D路径已经最优**: RoyT.AStar产生的2D网格序列`[(x1,y1), (x2,y2), ..., (xn,yn)]`不需要改变
- **只需选Z坐标**: 为每个2D点选择正确的高度层形成3D路径
- **基于高度趋势**: 根据当前位置到终点的剩余高度变化,选择最合适的层
---
## 技术设计
### 1. 数据结构扩展
#### HeightLayer结构
```csharp
public struct HeightLayer
{
public double Z; // 该层的Z坐标
public HeightInterval PassableHeight; // 可通行高度范围(用于物体检查)
public ModelItem SourceItem; // 来源模型项
public double SpeedLimit; // 限速
public CategoryAttributeManager.LogisticsElementType Type; // 层类型
}
```
#### GridCell扩展
```csharp
public struct GridCell
{
// ... 保留所有现有字段 ...
// 新增:多高度层支持
public List<HeightLayer> HeightLayers { get; set; }
}
```
### 2. 通道投影改为追加模式
**文件**: `src/PathPlanning/ChannelBasedGridBuilder.cs`
**方法**: `RasterizeTriangleToGrid()`
**修改前**:
```csharp
var cell = GridCellBuilder.Channel(preciseWorldPosition, channel, channelSpeedLimit);
gridMap.PlaceCell(gridPos, cell); // 覆盖
```
**修改后**:
```csharp
var layer = new HeightLayer
{
Z = gridCenterHeight,
PassableHeight = new HeightInterval(0, 0), // 初始化,后续设置
SourceItem = channel,
SpeedLimit = channelSpeedLimit,
Type = CategoryAttributeManager.GetLogisticsElementType(channel)
};
gridMap.AddHeightLayer(gridPos, layer); // 追加
```
### 3. PassableHeight计算适配
**保留现有逻辑**: `SetChannelPassableHeights()` 已经很完善
**修改点**: 从设置单层GridCell改为设置多个HeightLayer
```csharp
// 为每个高度层设置PassableHeight
if (cell.HeightLayers != null && cell.HeightLayers.Any())
{
for (int i = 0; i < cell.HeightLayers.Count; i++)
{
var layer = cell.HeightLayers[i];
layer.PassableHeight = new HeightInterval(0, scanHeightInModelUnits);
cell.HeightLayers[i] = layer;
}
}
```
### 4. 路径后处理智能选层
**核心算法**: `AssignLayerBased3DCoordinates()`
**选层策略**:
```
1. 起点锁定: 选择包含start.Z的层
2. 终点锁定: 选择包含end.Z的层
3. 中间点选层:
- 计算剩余高度变化: remainingHeight = end.Z - current.Z
- 计算期望每步变化: desiredChange = remainingHeight / remainingSteps
- 目标Z: targetZ = prevZ + desiredChange
- 选择最接近targetZ且净空足够的层
```
**示例执行**:
```
场景: 起点楼面(3.0m) → 终点楼梯(5.0m)
2D路径: [(0,0), (1,1), (2,2), (3,3)]
赋值过程:
1. (0,0): Z=3.0 (起点锁定楼面层)
2. (1,1): remainingHeight=2.0, steps=2, desiredChange=1.0
targetZ=4.0, 选择楼梯层3.5m (更接近4.0)
3. (2,2): remainingHeight=1.5, steps=1, desiredChange=1.5
targetZ=5.0, 选择楼梯层4.5m
4. (3,3): Z=5.0 (终点锁定楼梯层)
最终路径: [(0,0,3.0), (1,1,3.5), (2,2,4.5), (3,3,5.0)]
✅ 平滑爬升!
```
---
## 实施计划
### 步骤1: 扩展GridCell支持多层
- **文件**: `src/PathPlanning/GridMap.cs`
- **内容**: 新增HeightLayer结构、扩展GridCell、添加AddHeightLayer()和FindLayerContainingZ()方法
### 步骤2: 通道投影改为追加模式
- **文件**: `src/PathPlanning/ChannelBasedGridBuilder.cs`
- **内容**: 修改RasterizeTriangleToGrid()从PlaceCell改为AddHeightLayer
### 步骤3: 适配PassableHeight计算
- **文件**: `src/PathPlanning/GridMapGenerator.cs`
- **内容**: 修改SetChannelPassableHeights()支持多层
### 步骤4: 实现智能选层算法
- **文件**: `src/PathPlanning/AutoPathFinder.cs`
- **内容**: 新增AssignLayerBased3DCoordinates()和SelectBestLayer()方法,替换现有路径后处理
### 步骤5: 测试验证
- 起点楼面 → 终点楼梯(验证爬升)
- 起点楼梯 → 终点楼面(验证下降)
- 楼梯下方通行(验证多层并存)
---
## 关键约束
1. **保留RoyT.AStar**: 不修改A*算法,保持高性能
2. **不考虑向后兼容**: 直接改为多层架构
3. **保留现有PassableHeight逻辑**: 只适配到多层结构
4. **最小化改动**: 只修改必要的数据结构和投影逻辑
---
## 预期效果
- ✅ 解决楼梯-楼板重叠问题
- ✅ 自动选择最优高度层
- ✅ 平滑的高度过渡
- ✅ 保持RoyT.AStar高性能
- ✅ 代码改动最小化
---
## 文件修改清单
1. `src/PathPlanning/GridMap.cs` - 数据结构扩展
2. `src/PathPlanning/ChannelBasedGridBuilder.cs` - 投影逻辑修改
3. `src/PathPlanning/GridMapGenerator.cs` - PassableHeight计算适配
4. `src/PathPlanning/AutoPathFinder.cs` - 路径后处理智能选层
---
**状态**: 设计完成,待实施
**预计工作量**: 4个文件约200行代码修改