NavisworksTransport/doc/working/空轨支持方案.md

522 lines
16 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.

# 空轨支持方案
## 一、需求分析
### 1.1 核心需求
1. **新增空轨属性**:在物流属性系统中增加"空轨"类型
2. **空轨路径生成**
- 空轨走向固定,只需设置起点和终点
- 自动提取空轨几何体的下表面中心线作为路径
3. **路径类型区分**:路径需要标记为"地面路径"或"空轨路径"
4. **动画运行模式**
- 地面路径:物体中心点在路径点上
- 空轨路径:物体悬挂在空轨下方运行(物体中心 = 路径点 - 物体高度/2
5. **碰撞检测**
- 统一使用3D碰撞检测
- 空轨路径需要排除空轨本身
6. **限制条件**:空轨暂时只支持人工路径,不支持自动路径规划
### 1.2 使用场景
- **地面路径**:转运车在楼面、走廊、通道上运行
- **空轨路径**:悬挂式输送设备在空轨上运行
### 1.3 已确认信息
1.**空轨模型**:已存在,不需要建模规范
2.**空轨类型**:不需要分类型,只有一个"空轨"类型
3.**物体悬挂**:物体悬挂在空轨下方
4.**碰撞检测**:需要排除空轨本身
5.**数据库迁移**:不需要,新字段使用默认值
6.**向后兼容**:不需要向后兼容性
7.**碰撞检测统一**地面路径和空轨路径都使用3D碰撞检测
8.**轨道几何**:轨道不是水平的,需要精确计算几何体数据
---
## 二、架构影响分析
### 2.1 涉及的核心模块
| 模块 | 影响程度 | 改动内容 |
|------|---------|---------|
| **物流属性系统** | 🟢 低 | 新增"空轨"枚举值 |
| **路径数据模型** | 🟡 中 | 新增路径类型字段 |
| **路径规划系统** | 🟡 中 | 新增空轨路径生成逻辑 |
| **动画系统** | 🟡 中 | 根据路径类型调整物体位置 |
| **碰撞检测系统** | 🟢 低 | 空轨路径排除空轨本身 |
| **UI界面** | 🟡 中 | 路径类型选择、空轨路径生成 |
---
## 三、详细实施方案
### 3.1 第一阶段基础数据结构1天
#### 3.1.1 新增空轨属性
**文件**`CategoryAttributeManager.cs`
```csharp
public enum LogisticsElementType
{
// ... 现有类型 ...
/// <summary>
/// 空轨 - 空中运输路径物体悬挂运行权重0.7
/// </summary>
空轨 = 9,
}
```
#### 3.1.2 路径类型枚举
**文件**`PathPlanningModels.cs`
```csharp
/// <summary>
/// 路径类型
/// </summary>
public enum PathType
{
/// <summary>
/// 地面路径 - 物体在地面运行
/// </summary>
Ground = 0,
/// <summary>
/// 空轨路径 - 物体悬挂在空轨下方运行
/// </summary>
Rail = 1,
}
```
#### 3.1.3 路径数据模型扩展
**文件**`PathRouteViewModel.cs`
```csharp
private PathType _pathType = PathType.Ground;
public PathType PathType
{
get => _pathType;
set => SetProperty(ref _pathType, value);
}
```
#### 3.1.4 路径数据库适配
**文件**`PathDatabase.cs`
```csharp
// 保存路径时,保存路径类型
public void SavePath(PathRouteViewModel path)
{
// ... 现有逻辑 ...
// 新增:保存路径类型
}
// 加载路径时,读取路径类型
public PathRouteViewModel LoadPath(string pathId)
{
// ... 现有逻辑 ...
// 新增:读取路径类型
}
```
---
### 3.2 第二阶段空轨路径生成2天
#### 3.2.1 复用现有几何计算
**现有代码复用**
- `ChannelHeightDetector.AnalyzeChannelGeometry()` - 分析通道几何
- `ChannelHeightDetector.CalculatePreciseHeightAtPosition()` - 计算精确高度
- `GeometryHelper.ExtractTriangles()` - 提取三角形
- `GeometryHelper.RayTriangleIntersect()` - 射线-三角形交点检测
#### 3.2.2 新增底部高度检测方法
**文件**`ChannelHeightDetector.cs`
新增方法:
- `GetChannelBottomHeight(Point3D position, IEnumerable<ModelItem> channelItems)` - 获取通道底面高度
- `CalculateBottomPreciseHeightAtPosition(Point3D position, ChannelHeightInfo heightInfo, ModelItem channel)` - 计算底面精确高度
- `TryRaycastFromBelow(Point3D position, ModelItem channel, double floorHeight, out double height)` - 从下方射线投射
- `PerformRayTriangleIntersectionFromBelow(Point3D position, List<Triangle3D> triangles)` - 从下往上射线-三角形交点检测
- `TryGetGeometricBottomHeight(Point3D position, ModelItem channel, out double height)` - View API获取底面高度
- `AnalyzeBottomSurfaceHeightAtPosition(Point3D position, ModelItem channel, double floorHeight, double ceilingHeight)` - 分析底面表面高度
- `TryMultiPointBottomSampling(Point3D position, ModelItem channel)` - 多点采样获取底面高度
#### 3.2.3 空轨中心线提取工具
**文件**`RailGeometryHelper.cs`(新建)
```csharp
/// <summary>
/// 空轨几何体辅助工具
/// 负责提取空轨的下表面中心线
/// </summary>
public static class RailGeometryHelper
{
/// <summary>
/// 从空轨几何体提取下表面中心线
/// </summary>
/// <param name="railModel">空轨模型项</param>
/// <param name="startPoint">起点2D坐标</param>
/// <param name="endPoint">终点2D坐标</param>
/// <returns>路径点列表包含精确的Z坐标</returns>
public static List<Point3D> ExtractRailCenterLine(
ModelItem railModel,
Point3D startPoint,
Point3D endPoint)
{
var pathPoints = new List<Point3D>();
try
{
LogManager.Debug($"[空轨] 开始提取空轨中心线: {railModel.DisplayName}");
// 1. 创建高度检测器实例
var heightDetector = new ChannelHeightDetector();
var railItems = new List<ModelItem> { railModel };
// 2. 计算起点和终点在X-Y平面上的投影距离
double distance2D = Math.Sqrt(
Math.Pow(endPoint.X - startPoint.X, 2) +
Math.Pow(endPoint.Y - startPoint.Y, 2)
);
if (distance2D < 0.01)
{
LogManager.Warning("[空轨] 起点和终点重合");
return pathPoints;
}
// 3. 在起点和终点之间采样计算每个采样点的精确Z坐标
int sampleCount = Math.Max(2, (int)Math.Ceiling(distance2D / 0.5)); // 每0.5米一个采样点
for (int i = 0; i < sampleCount; i++)
{
double t = (double)i / (sampleCount - 1);
// 线性插值计算X、Y坐标
double x = startPoint.X + t * (endPoint.X - startPoint.X);
double y = startPoint.Y + t * (endPoint.Y - startPoint.Y);
double z = startPoint.Z; // 初始Z坐标
// 调用现有的GetChannelBottomHeight方法获取精确底面高度
var samplePoint = new Point3D(x, y, z); // Z坐标会被方法更新
var bottomHeight = heightDetector.GetChannelBottomHeight(samplePoint, railItems);
pathPoints.Add(new Point3D(x, y, bottomHeight));
}
LogManager.Debug($"[空轨] 生成 {pathPoints.Count} 个路径点,总长度: {distance2D:F2}m");
}
catch (Exception ex)
{
LogManager.Error($"[空轨] 提取空轨中心线失败: {ex.Message}");
}
return pathPoints;
}
}
```
#### 3.2.4 路径编辑器扩展
**文件**`PathEditingViewModel.cs`
新增方法:
- `GeneratePathFromRail(ModelItem railModel, Point3D startPoint, Point3D endPoint)` - 从空轨生成路径
- `SelectRailModelCommand` - 选择空轨命令
- `SetPathStartPointCommand` - 设置起点命令
- `SetPathEndPointCommand` - 设置终点命令
- `GeneratePathFromRailCommand` - 生成路径命令
新增属性:
- `SelectedPathType` - 选中的路径类型
- `PathTypes` - 路径类型数组
- `IsRailPathType` - 是否为空轨路径类型
- `SelectedRailModel` - 选中的空轨模型
- `SelectedRailModelName` - 选中的空轨模型名称
- `PathStartPoint` - 路径起点
- `PathStartPointDisplay` - 路径起点显示
- `PathEndPoint` - 路径终点
- `PathEndPointDisplay` - 路径终点显示
---
### 3.3 第三阶段动画系统适配1天
#### 3.3.1 物体位置计算
**文件**`PathAnimationManager.cs`
```csharp
/// <summary>
/// 计算物体在路径点上的位置
/// </summary>
private Point3D CalculateObjectPosition(Point3D pathPoint, PathType pathType)
{
if (pathType == PathType.Rail)
{
// 空轨路径:物体悬挂在空轨下方
// 物体中心点 = 空轨点 - 物体高度的一半
double objectCenterZ = pathPoint.Z - _virtualObjectHeight / 2;
return new Point3D(pathPoint.X, pathPoint.Y, objectCenterZ);
}
else
{
// 地面路径:物体中心点在路径点上
return pathPoint;
}
}
```
#### 3.3.2 传递路径类型
**文件**`PathAnimationManager.cs`
修改方法:
- `GenerateAnimationFrames(List<Point3D> pathPoints, PathType pathType)` - 传递路径类型参数
- `PrecomputeCollisions(List<Point3D> pathPoints, PathType pathType, List<ModelItem> railModels)` - 传递路径类型和空轨模型列表
- `DetectFrameCollisions(AnimationFrame frame, PathType pathType, List<ModelItem> collisionExclusions)` - 传递路径类型和排除列表
---
### 3.4 第四阶段碰撞检测适配1天
#### 3.4.1 空轨排除逻辑
**文件**`PathAnimationManager.cs`
修改方法:
- `PrecomputeCollisions(List<Point3D> pathPoints, PathType pathType, List<ModelItem> railModels)` - 新增空轨排除列表
- `DetectFrameCollisions(AnimationFrame frame, PathType pathType, List<ModelItem> collisionExclusions)` - 使用排除列表过滤
**核心逻辑**
```csharp
// 创建碰撞排除列表
var collisionExclusions = new List<ModelItem>();
// 如果是空轨路径,将空轨模型加入排除列表
if (pathType == PathType.Rail && railModels != null)
{
collisionExclusions.AddRange(railModels);
LogManager.Info($"[碰撞检测] 已排除 {railModels.Count} 个空轨模型");
}
// 在碰撞检测循环中跳过排除列表中的项目
foreach (var modelItem in allModelItems)
{
// 跳过排除列表中的项目(包括空轨本身)
if (collisionExclusions.Contains(modelItem))
{
continue;
}
// 统一使用3D碰撞检测
double distance = BoundingBoxGeometryUtils.CalculateDistance(objectBoundingBox, modelBoundingBox);
if (distance <= 0) // 相交或接触
{
collisions.Add(new CollisionResult
{
Item1 = _animatedObject,
Item2 = modelItem,
Distance = distance
});
}
}
```
---
### 3.5 第五阶段UI界面适配1天
#### 3.5.1 路径类型选择
**文件**`PathEditingViewModel.cs`
新增属性:
- `PathTypes` - 路径类型数组
- `SelectedPathType` - 选中的路径类型
- `IsRailPathType` - 是否为空轨路径类型
#### 3.5.2 命令
**文件**`PathEditingViewModel.cs`
新增命令:
- `GeneratePathFromRailCommand` - 从空轨生成路径命令
- `SelectRailModelCommand` - 选择空轨命令
- `SetPathStartPointCommand` - 设置起点命令
- `SetPathEndPointCommand` - 设置终点命令
#### 3.5.3 UI布局
**文件**`LogisticsControlPanel.xaml`
新增控件:
- 路径类型选择 ComboBox
- 空轨选择 StackPanel仅在选择空轨类型时显示
- 选择空轨按钮
- 设置起点按钮
- 设置终点按钮
- 生成路径按钮
---
## 四、实施步骤
### 第一阶段基础数据结构1天
1. ✅ 新增"空轨"物流属性类型
2. ✅ 新增路径类型枚举
3. ✅ 扩展路径数据模型
4. ✅ 适配数据库读写
### 第二阶段空轨路径生成2天
1. ✅ 在 `ChannelHeightDetector` 中新增底部高度检测方法
2. ✅ 复用现有的几何计算代码
3. ✅ 实现 `RailGeometryHelper`(调用现有方法)
4. ✅ 扩展路径编辑器
5. ✅ UI界面适配
6. ✅ 集成测试
### 第三阶段动画系统适配1天
1. ✅ 物体位置计算适配
2. ✅ 传递路径类型参数
3. ✅ 动画播放测试
### 第四阶段碰撞检测适配1天
1. ✅ 实现空轨排除逻辑
2. ✅ 统一使用3D碰撞检测
3. ✅ 碰撞报告适配
4. ✅ 集成测试
### 第五阶段测试和优化1天
1. ✅ 功能测试
2. ✅ 性能测试
3. ✅ 用户验收测试
**总计**6天
---
## 五、风险评估
| 风险项 | 风险等级 | 缓解措施 |
|--------|---------|---------|
| 空轨几何体提取失败 | 🟢 低 | 空轨模型已存在,直接使用 |
| 物体悬挂位置计算错误 | 🟡 中 | 充分测试,提供可视化验证 |
| 碰撞检测误报 | 🟡 中 | 排除空轨本身,调整检测参数 |
| 性能下降 | 🟢 低 | 空轨路径数量少,影响有限 |
| 几何计算性能 | 🟡 中 | 复用现有代码,优化采样策略 |
---
## 六、总结
### 6.1 方案优势
-**代码复用最大化**:充分利用现有的几何计算代码
-**架构统一**:空轨和地面路径使用相同的高度检测框架
-**改动最小化**:只需新增底部检测方法,其他全部复用
-**易于维护**:几何计算逻辑集中管理
-**向后兼容**:不需要迁移,新字段使用默认值
-**碰撞检测统一**统一使用3D检测简化逻辑
### 6.2 关键技术点
1. **复用现有代码**`ChannelHeightDetector` 的几何计算方法
2. **新增底部检测**`GetChannelBottomHeight()` 方法
3. **物体悬挂计算**:物体中心 = 空轨点 - 物体高度/2
4. **碰撞检测统一**统一使用3D检测
5. **排除空轨本身**:通过排除列表过滤空轨模型
6. **精确几何计算**:支持倾斜、弯曲的轨道
### 6.3 技术难点
- 需要处理大量三角形面片(性能优化)
- 需要处理重叠三角形(选择最高点)
- 需要处理采样点不在任何三角形内的情况(使用默认值)
### 6.4 预期成果
- ✅ 支持空轨路径生成
- ✅ 支持物体悬挂运行
- ✅ 支持空轨碰撞检测(排除空轨本身)
- ✅ 保持与现有地面路径功能的兼容性
---
## 七、附录
### 7.1 文件清单
#### 新增文件
- `RailGeometryHelper.cs` - 空轨几何体辅助工具
#### 修改文件
- `CategoryAttributeManager.cs` - 新增空轨枚举
- `PathPlanningModels.cs` - 新增路径类型枚举
- `PathRouteViewModel.cs` - 新增路径类型字段
- `PathDatabase.cs` - 适配路径类型读写
- `ChannelHeightDetector.cs` - 新增底部高度检测方法
- `PathEditingViewModel.cs` - 扩展路径编辑功能
- `PathAnimationManager.cs` - 适配物体位置和碰撞检测
- `LogisticsControlPanel.xaml` - UI界面适配
### 7.2 方法清单
#### 新增方法ChannelHeightDetector.cs
- `GetChannelBottomHeight(Point3D position, IEnumerable<ModelItem> channelItems)` - 获取通道底面高度
- `CalculateBottomPreciseHeightAtPosition(Point3D position, ChannelHeightInfo heightInfo, ModelItem channel)` - 计算底面精确高度
- `TryRaycastFromBelow(Point3D position, ModelItem channel, double floorHeight, out double height)` - 从下方射线投射
- `PerformRayTriangleIntersectionFromBelow(Point3D position, List<Triangle3D> triangles)` - 从下往上射线-三角形交点检测
- `TryGetGeometricBottomHeight(Point3D position, ModelItem channel, out double height)` - View API获取底面高度
- `AnalyzeBottomSurfaceHeightAtPosition(Point3D position, ModelItem channel, double floorHeight, double ceilingHeight)` - 分析底面表面高度
- `TryMultiPointBottomSampling(Point3D position, ModelItem channel)` - 多点采样获取底面高度
#### 新增方法RailGeometryHelper.cs
- `ExtractRailCenterLine(ModelItem railModel, Point3D startPoint, Point3D endPoint)` - 提取空轨中心线
#### 新增方法PathEditingViewModel.cs
- `GeneratePathFromRail(ModelItem railModel, Point3D startPoint, Point3D endPoint)` - 从空轨生成路径
#### 新增方法PathAnimationManager.cs
- `CalculateObjectPosition(Point3D pathPoint, PathType pathType)` - 计算物体位置
#### 修改方法PathAnimationManager.cs
- `GenerateAnimationFrames(List<Point3D> pathPoints, PathType pathType)` - 传递路径类型参数
- `PrecomputeCollisions(List<Point3D> pathPoints, PathType pathType, List<ModelItem> railModels)` - 传递路径类型和空轨模型列表
- `DetectFrameCollisions(AnimationFrame frame, PathType pathType, List<ModelItem> collisionExclusions)` - 传递路径类型和排除列表
---