# 路径分析功能深化设计方案 > 版本: 1.0 > 日期: 2026-02-14 > 适用范围: 大型装置内精密组件物流仿真 --- ## 一、项目背景与目标 ### 1.1 背景 - **应用场景**: 大型装置内进行精密组件物流仿真 - **核心目标**: 确保组件能安全到达安装位置(终点) - **最高优先级**: 减少碰撞(安全性) - **次要优先级**: 路径复杂度/效率(时间成本) - **不涉及**: 经济成本 ### 1.2 设计原则 1. **实用优先**: 指标不在于多,而在于有用 2. **聚焦终点**: 核心目标是"找出到同一安装位置的最佳路径" 3. **可解释性**: 每个指标和评分都要有明确的物理意义 4. **可操作性**: 建议要具体,告诉用户"怎么做" --- ## 二、策略模式 ### 2.1 三种分析策略 | 策略 | 权重配置(安全/效率/转弯/直达) | 适用场景 | |-----|--------------------------------|---------| | **安全优先** | 50% / 30% / 10% / 10% | 精密/易损组件,首次运输 | | **效率优先** | 20% / 50% / 15% / 15% | 紧急任务,多次往返 | | **平衡模式** | 35% / 35% / 15% / 15% | 通用场景(默认) | ### 2.2 权重配置代码 ```csharp public static class AnalysisStrategies { public const string SafetyFirst = "安全优先"; public const string EfficiencyFirst = "效率优先"; public const string Balanced = "平衡模式"; // 权重顺序: 安全、效率、转弯、直达 public static readonly Dictionary Weights = new Dictionary { [SafetyFirst] = new[] { 0.50, 0.30, 0.10, 0.10 }, [EfficiencyFirst] = new[] { 0.20, 0.50, 0.15, 0.15 }, [Balanced] = new[] { 0.35, 0.35, 0.15, 0.15 } }; } ``` --- ## 三、指标体系(4维度) ### 3.1 安全性(碰撞风险指数)- 权重最高 ```csharp // 基础碰撞分(100分制) // 0次=100分, 1次=80分, 2次=60分, 3次=40分, 4次+=20分 BaseScore = Max(0, 100 - CollisionCount * 20); // 碰撞热点扣分(3米范围内≥2次碰撞视为热点) // 每个热点扣15分 HotspotPenalty = HotspotCount * 15; // 最终安全分 SafetyScore = Max(0, BaseScore - HotspotPenalty); ``` ### 3.2 效率(通行效率指数) ```csharp // 速度分(以1.0 m/s为理想速度) ActualSpeed = TotalLength / EstimatedTime; SpeedScore = Min(100, ActualSpeed / 1.0 * 100); // 时间效率(与组内最短时间的比值) TimeEfficiency = GroupMinTime / EstimatedTime * 100; // 综合效率分(速度70% + 时间效率30%) EfficiencyScore = SpeedScore * 0.7 + TimeEfficiency * 0.3; ``` ### 3.3 可行性(转弯难度系数) ```csharp // 从 PathRoute.Edges 统计 ArcEdgeCount = Edges.Count(e => e.SegmentType == PathSegmentType.Arc); TotalEdgeCount = Edges.Count; // 转弯次数扣分(每次扣8分) TurnPenalty = ArcEdgeCount * 8; // 小半径惩罚 MinRadius = Edges .Where(e => e.SegmentType == PathSegmentType.Arc) .Select(e => e.Trajectory?.ActualRadius ?? double.MaxValue) .DefaultIfEmpty(double.MaxValue) .Min(); RadiusPenalty = MinRadius < 2.0 ? 20 : 0; // 转弯难度分 TurnDifficultyScore = Max(0, 100 - TurnPenalty - RadiusPenalty); ``` ### 3.4 直达性(路径曲折度) ```csharp // 计算起点到终点的直线距离 StartPoint = Points.First().Position; EndPoint = Points.Last().Position; StraightDistance = Distance(StartPoint, EndPoint); // 曲折度(≥1.0) Tortuosity = TotalLength / StraightDistance; // 曲折度分 TortuosityScore = Max(0, 100 - (Tortuosity - 1.0) * 50); ``` --- ## 四、同一起终点分析(核心功能) ### 4.1 路径分组算法 ```csharp // 以终点为主的分组(2米阈值) public List GroupPathsByEndpoint(List routes) { const double ENDPOINT_THRESHOLD = 2.0; // 2米 var groups = new List(); foreach (var route in routes) { var endPoint = route.GetEndPoint()?.Position; if (endPoint == null) continue; // 查找是否已有匹配的组 var matchingGroup = groups.FirstOrDefault(g => Distance(g.EndPoint, endPoint) < ENDPOINT_THRESHOLD); if (matchingGroup != null) { matchingGroup.Routes.Add(route); // 更新组中心点 matchingGroup.EndPoint = AveragePoint(matchingGroup.Routes); } else { groups.Add(new EndpointGroup { GroupId = Guid.NewGuid().ToString("N")[..8], EndPoint = endPoint, Routes = new List { route } }); } } return groups; } ``` ### 4.2 组内对比指标 | 对比项 | 计算公式 | |-------|---------| | 长度差异率 | (路径长度 - 组内最短) / 最短 × 100% | | 效率差异率 | (路径时间 - 组内最短) / 最短 × 100% | | 安全差异 | 碰撞数对比(0次为优) | | 最佳路径 | 按策略加权评分最高者 | ### 4.3 最佳路径判定逻辑 ```csharp public PathRoute FindBestPathInGroup(EndpointGroup group, string strategy) { // 第一步:计算所有路径的加权评分 foreach (var route in group.Routes) { route.WeightedScore = CalculateWeightedScore(route.Analysis, strategy); } // 第二步:按评分排序 var sortedRoutes = group.Routes.OrderByDescending(r => r.WeightedScore).ToList(); // 第三步:如果前两名评分接近(差距<5分),优先选碰撞少的 if (sortedRoutes.Count >= 2) { var first = sortedRoutes[0]; var second = sortedRoutes[1]; if (Math.Abs(first.WeightedScore - second.WeightedScore) < 5) { if (second.CollisionCount < first.CollisionCount) return second; } } return sortedRoutes.First(); } ``` --- ## 五、碰撞热点计算 ### 5.1 热点定义 - **范围**: 3米半径球体 - **阈值**: 范围内 ≥2 次碰撞 - **数据来源**: `ClashDetectiveCollisionObjects` 表的 `Item1PosX/Y/Z` ### 5.2 热点检测算法 ```csharp public List DetectHotspots(List collisions, double radius = 3.0) { var hotspots = new List(); var processed = new HashSet(); for (int i = 0; i < collisions.Count; i++) { if (processed.Contains(i)) continue; var center = collisions[i].Center; var nearbyCollisions = new List { collisions[i] }; // 查找范围内的其他碰撞 for (int j = i + 1; j < collisions.Count; j++) { if (processed.Contains(j)) continue; if (Distance(center, collisions[j].Center) <= radius) { nearbyCollisions.Add(collisions[j]); processed.Add(j); } } // 如果达到阈值,创建热点 if (nearbyCollisions.Count >= 2) { hotspots.Add(new CollisionHotspot { Center = CalculateCenter(nearbyCollisions), CollisionCount = nearbyCollisions.Count, Radius = radius, CollidedObjectNames = nearbyCollisions.Select(c => c.Item2.DisplayName).Distinct().ToList() }); } processed.Add(i); } return hotspots; } ``` --- ## 六、优化建议生成 ### 6.1 建议分类 | 类别 | 触发条件 | 建议内容 | |-----|---------|---------| | **安全建议** | 碰撞数>0 | 发现X次碰撞,其中Y个热点,建议检查碰撞位置 | | **效率建议** | 长度差异率>30% | 该路径比组内最短路径长X%,建议优化路线 | | **转弯建议** | 转弯次数>3 | 路径包含X个转弯,建议减少急转弯 | | **直达建议** | 直达性<70% | 路径较为曲折,建议考虑更直接的路线 | | **组内对比** | 组内路径>1 | 本组共X条路径,推荐【路径名】为最佳选择 | ### 6.2 建议生成示例 ```csharp public List GenerateSuggestions(PathDetailedAnalysis analysis, EndpointGroup group) { var suggestions = new List(); // 安全建议 if (analysis.CollisionCount > 0) { if (analysis.HotspotCount > 0) suggestions.Add($"🔴 发现{analysis.CollisionCount}次碰撞,其中{analysis.HotspotCount}个热点区域,建议重点检查热点位置"); else suggestions.Add($"⚠️ 发现{analysis.CollisionCount}次碰撞,建议优化路径避让"); } else { suggestions.Add("✅ 无碰撞,安全性良好"); } // 组内对比建议 if (group?.Routes.Count > 1) { var lengthDiff = (analysis.TotalLength - group.MinLength) / group.MinLength * 100; if (lengthDiff > 30) suggestions.Add($"📊 该路径比组内最短路径长{lengthDiff:F1}%,建议考虑更短路线"); // 推荐最佳路径 if (analysis.RouteId == group.BestRouteId) suggestions.Add($"🏆 该路径是本组到『{group.EndPointName}』的最佳选择"); } return suggestions; } ``` --- ## 七、数据库扩展 ### 7.1 扩展示意图 ```sql -- AnalysisResults 表扩展字段 ALTER TABLE AnalysisResults ADD COLUMN TurnDifficultyScore REAL, -- 转弯难度分 TortuosityScore REAL, -- 直达性分 HotspotCount INTEGER, -- 热点数量 AnalysisStrategy TEXT, -- 分析策略 GroupId TEXT, -- 所属终点组ID GroupRanking INTEGER; -- 在组内排名 -- 新增热点表(可选) CREATE TABLE IF NOT EXISTS CollisionHotspots ( Id INTEGER PRIMARY KEY AUTOINCREMENT, RouteId TEXT NOT NULL, CenterX REAL, CenterY REAL, CenterZ REAL, Radius REAL, CollisionCount INTEGER, CreatedAt DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY(RouteId) REFERENCES PathRoutes(Id) ON DELETE CASCADE ); ``` --- ## 八、复用现有代码清单 | 功能 | 复用代码 | 文件路径 | |-----|---------|---------| | 通道属性获取 | `CategoryAttributeManager.GetLogisticsPropertyValue()` | `src/Core/Properties/CategoryAttributeManager.cs` | | 碰撞数据获取 | `PathDatabase.GetClashDetectiveResultsByPath()` | `src/Core/PathDatabase.cs` | | 碰撞对象位置 | `ClashDetectiveCollisionObjects` 表 | `src/Core/PathDatabase.cs` | | 路径点位置 | `PathRoute.GetSortedPoints()` | `src/Core/PathPlanningModels.cs` | | 路径边分析 | `PathRoute.Edges` | `src/Core/PathPlanningModels.cs` | | 单位转换 | `UnitsConverter.ConvertToMeters()` | `src/Utils/UnitsConverter.cs` | | 距离计算 | `GeometryHelper.Distance()` | `src/Utils/GeometryHelper.cs` | | 报告目录 | `PathHelper.GetReportDirectory()` | `src/Utils/PathHelper.cs` | | HTML报告模板 | `CollisionReportHtmlGenerator` | `src/Utils/CollisionReportHtmlGenerator.cs` | --- ## 九、分阶段实施计划 ### Phase 1: 核心算法与数据结构(基础) | 任务 | 文件 | 说明 | |-----|------|------| | 1.1 数据模型 | `src/Core/Models/PathAnalysisModels.cs` | 新建,定义分析相关模型 | | 1.2 分析引擎 | `src/Core/PathAnalysisEngine.cs` | 新建,核心计算逻辑 | | 1.3 数据库扩展 | `src/Core/PathDatabase.cs` | 修改,增加新字段和方法 | | 1.4 服务扩展 | `src/Core/PathAnalysisService.cs` | 修改,集成新算法 | ### Phase 2: UI可视化(第二步) | 任务 | 文件 | 说明 | |-----|------|------| | 2.1 ViewModel更新 | `src/UI/WPF/ViewModels/PathAnalysisViewModel.cs` | 修改,增加新属性和命令 | | 2.2 对话框更新 | `src/UI/WPF/Views/PathAnalysisDialog.xaml` | 修改,增加Canvas图表区域 | | 2.3 图表绘制 | `src/UI/WPF/Views/PathAnalysisDialog.xaml.cs` | 修改,Canvas自绘柱状图和雷达图 | ### Phase 3: HTML报告(第三步) | 任务 | 文件 | 说明 | |-----|------|------| | 3.1 报告生成器 | `src/Core/PathAnalysisReportGenerator.cs` | 新建,HTML生成逻辑 | | 3.2 报告样式 | 嵌入式CSS | 使用内联样式,无需外部依赖 | --- ## 十、关键算法伪代码 ### 10.1 综合评分计算 ```csharp public double CalculateWeightedScore(PathDetailedAnalysis analysis, string strategy) { var weights = AnalysisStrategies.Weights[strategy]; // 各维度分数 double safety = analysis.SafetyScore; // 安全 double efficiency = analysis.EfficiencyScore; // 效率 double turn = analysis.TurnDifficultyScore; // 转弯 double tortuosity = analysis.TortuosityScore; // 直达 // 加权计算 double weightedScore = safety * weights[0] + efficiency * weights[1] + turn * weights[2] + tortuosity * weights[3]; return Math.Round(weightedScore, 1); } ``` ### 10.2 完整分析流程 ```csharp public PathDetailedAnalysis AnalyzePath(PathRoute route, AnalysisContext context) { var analysis = new PathDetailedAnalysis { RouteId = route.Id, RouteName = route.Name }; // 1. 获取碰撞数据 var collisions = GetCollisionsForRoute(route.Id); analysis.CollisionCount = collisions.Count; // 2. 检测热点 analysis.Hotspots = DetectHotspots(collisions, radius: 3.0); analysis.HotspotCount = analysis.Hotspots.Count; // 3. 计算各维度分数 analysis.SafetyScore = CalculateSafetyScore(analysis.CollisionCount, analysis.HotspotCount); analysis.EfficiencyScore = CalculateEfficiencyScore(route, context.GroupMinTime); analysis.TurnDifficultyScore = CalculateTurnDifficultyScore(route.Edges); analysis.TortuosityScore = CalculateTortuosityScore(route); // 4. 计算综合评分 analysis.WeightedScore = CalculateWeightedScore(analysis, context.Strategy); return analysis; } ``` --- ## 十一、界面设计要点 ### 11.1 路径分析对话框布局 ``` +----------------------------------------------------------+ | 路径分析 - 多路径对比 [关闭] | +----------------------------------------------------------+ | +----------------+ +------------------+ +-----------+ | | | 路径选择 | | 🏆 推荐最佳路径 | | 💡 优化建议| | | | - 路径A | | 路径名称 | | 建议1... | | | | - 路径B [x] | | 长度: XXm | 评分 | | 建议2... | | | | - 路径C [x] | +------------------+ | ... | | | | | +------------------+ +-----------+ | | | [全选][清空] | | 📊 多路径对比图表 | | | | | | +--------------+ | | | | 策略: | | | 柱状图 | | | | | ○ 安全优先 | | | (4维度对比) | | | | | ○ 效率优先 | | +--------------+ | | | | ● 平衡模式 | | +--------------+ | | | | | | | 雷达图 | | | | | [开始分析] | | | (组内对比) | | | | +----------------+ +------------------+ | | +------------------+ | | | 🎯 同终点路径组 | | | | 组1: 终点 (2条) | | | | - 路径B (最佳) | | | | - 路径A | | | +------------------+ | +----------------------------------------------------------+ | [导出报告] [关闭] | +----------------------------------------------------------+ ``` ### 11.2 可视化元素(WPF Canvas自绘) 1. **柱状图**: 使用WPF Canvas绘制,展示各路径4维度分数对比(安全/效率/转弯/直达) - 每个柱子显示具体分数 - 路径名称水平显示在柱组下方 - 右上角显示图例 2. **雷达图**: 使用WPF Canvas绘制,展示选中组内所有路径的4维度表现 - 五边形网格背景 - 不同颜色区分各路径 - 最佳路径用粗线标识 3. **推荐卡片**: 显示最佳路径名称、长度和综合评分 4. **优化建议列表**: 分类显示安全、效率、转弯等建议 --- ## 十二、HTML报告结构 ```html 路径分析报告 ``` **说明**: HTML报告使用纯CSS样式,无需外部JavaScript库,可离线打开。 --- ## 十三、风险评估与应对 | 风险 | 影响 | 应对措施 | |-----|------|---------| | 碰撞位置数据缺失 | 热点计算失败 | 使用碰撞对象中心点作为近似 | | 通道属性未设置 | 冗余度无法计算 | 使用默认值,并在报告中提示 | | 路径无边数据 | 转弯分析失败 | 退化为直线分析 | | 单一路径无对比 | 组内分析无意义 | 隐藏组内对比部分 | --- ## 十四、验收标准 ### 14.1 Phase 1 验收 - [ ] 能正确计算5维度分数 - [ ] 能正确检测碰撞热点(3米范围) - [ ] 能按策略计算加权评分 - [ ] 数据能正确保存到数据库 ### 14.2 Phase 2 验收 - [ ] UI能显示4维度柱状图(WPF Canvas绘制) - [ ] UI能显示雷达图(WPF Canvas绘制) - [ ] 同终点组能正确分组(2米阈值) - [ ] 能正确标识组内最佳路径 - [ ] 优化建议具体且可执行 ### 14.3 Phase 3 验收 - [ ] HTML报告能离线打开(纯CSS样式,无外部依赖) - [ ] 报告包含所有必要信息 - [ ] 表格分数条能正确显示 - [ ] 样式符合专业报告标准 --- ## 十五、资源文件路径 所有资源文件统一存放在 `resources` 目录下: | 文件 | 路径 | 说明 | |-----|------|------| | 默认配置 | `resources/default_config.toml` | 系统默认配置模板 | | 插件名称 | `resources/TransportPlugin.name.txt` | 插件显示名称 | | 单位立方体 | `resources/unit_cube.nwc` | 虚拟物体碰撞检测用 | **部署说明**: 编译时资源文件会自动复制到输出目录,部署脚本会将整个 `resources` 文件夹复制到插件目录。 --- ## 附录:参考文件 - 现有碰撞报告生成器: `src/Utils/CollisionReportHtmlGenerator.cs` - 通道属性管理器: `src/Core/Properties/CategoryAttributeManager.cs` - 路径数据模型: `src/Core/PathPlanningModels.cs` - 数据库操作: `src/Core/PathDatabase.cs` - 单位转换: `src/Utils/UnitsConverter.cs`