19 KiB
19 KiB
路径分析功能深化设计方案
版本: 1.0
日期: 2026-02-14
适用范围: 大型装置内精密组件物流仿真
一、项目背景与目标
1.1 背景
- 应用场景: 大型装置内进行精密组件物流仿真
- 核心目标: 确保组件能安全到达安装位置(终点)
- 最高优先级: 减少碰撞(安全性)
- 次要优先级: 路径复杂度/效率(时间成本)
- 不涉及: 经济成本
1.2 设计原则
- 实用优先: 指标不在于多,而在于有用
- 聚焦终点: 核心目标是"找出到同一安装位置的最佳路径"
- 可解释性: 每个指标和评分都要有明确的物理意义
- 可操作性: 建议要具体,告诉用户"怎么做"
二、策略模式
2.1 三种分析策略
| 策略 | 权重配置(安全/效率/转弯/直达) | 适用场景 |
|---|---|---|
| 安全优先 | 50% / 30% / 10% / 10% | 精密/易损组件,首次运输 |
| 效率优先 | 20% / 50% / 15% / 15% | 紧急任务,多次往返 |
| 平衡模式 | 35% / 35% / 15% / 15% | 通用场景(默认) |
2.2 权重配置代码
public static class AnalysisStrategies
{
public const string SafetyFirst = "安全优先";
public const string EfficiencyFirst = "效率优先";
public const string Balanced = "平衡模式";
// 权重顺序: 安全、效率、转弯、直达
public static readonly Dictionary<string, double[]> Weights = new Dictionary<string, double[]>
{
[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 安全性(碰撞风险指数)- 权重最高
// 基础碰撞分(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 效率(通行效率指数)
// 速度分(以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 可行性(转弯难度系数)
// 从 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 直达性(路径曲折度)
// 计算起点到终点的直线距离
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 路径分组算法
// 以终点为主的分组(2米阈值)
public List<EndpointGroup> GroupPathsByEndpoint(List<PathRoute> routes)
{
const double ENDPOINT_THRESHOLD = 2.0; // 2米
var groups = new List<EndpointGroup>();
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<PathRoute> { route }
});
}
}
return groups;
}
4.2 组内对比指标
| 对比项 | 计算公式 |
|---|---|
| 长度差异率 | (路径长度 - 组内最短) / 最短 × 100% |
| 效率差异率 | (路径时间 - 组内最短) / 最短 × 100% |
| 安全差异 | 碰撞数对比(0次为优) |
| 最佳路径 | 按策略加权评分最高者 |
4.3 最佳路径判定逻辑
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 热点检测算法
public List<CollisionHotspot> DetectHotspots(List<CollisionResult> collisions, double radius = 3.0)
{
var hotspots = new List<CollisionHotspot>();
var processed = new HashSet<int>();
for (int i = 0; i < collisions.Count; i++)
{
if (processed.Contains(i)) continue;
var center = collisions[i].Center;
var nearbyCollisions = new List<CollisionResult> { 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 建议生成示例
public List<string> GenerateSuggestions(PathDetailedAnalysis analysis, EndpointGroup group)
{
var suggestions = new List<string>();
// 安全建议
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 扩展示意图
-- 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 综合评分计算
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 完整分析流程
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自绘)
-
柱状图: 使用WPF Canvas绘制,展示各路径4维度分数对比(安全/效率/转弯/直达)
- 每个柱子显示具体分数
- 路径名称水平显示在柱组下方
- 右上角显示图例
-
雷达图: 使用WPF Canvas绘制,展示选中组内所有路径的4维度表现
- 五边形网格背景
- 不同颜色区分各路径
- 最佳路径用粗线标识
-
推荐卡片: 显示最佳路径名称、长度和综合评分
-
优化建议列表: 分类显示安全、效率、转弯等建议
十二、HTML报告结构
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>路径分析报告</title>
<style>
/* 简洁专业风格(蓝白配色) */
:root { --primary: #2c5aa0; --success: #28a745; --warning: #ffc107; --danger: #dc3545; }
body { font-family: 'Microsoft YaHei', Arial; margin: 40px; }
.header { text-align: center; border-bottom: 3px solid var(--primary); padding-bottom: 20px; }
.best-path-card { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 30px; border-radius: 12px; }
.score-bar-container { background: #e9ecef; height: 24px; border-radius: 12px; position: relative; }
.score-bar { height: 100%; border-radius: 12px; }
.score-text { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); font-weight: bold; }
.comparison-table { width: 100%; border-collapse: collapse; }
.comparison-table th { background: var(--primary); color: white; padding: 12px; }
/* ... */
</style>
</head>
<body>
<!-- 1. 头部 -->
<!-- 2. 执行摘要+最佳路径 -->
<!-- 3. 同终点组分析 -->
<!-- 4. 详细数据表格(带分数条) -->
<!-- 5. 优化建议 -->
</body>
</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