路径分析功能深化设计方案
版本: 1.0
日期: 2026-02-14
适用范围: 大型装置内精密组件物流仿真
一、项目背景与目标
1.1 背景
- 应用场景: 大型装置内进行精密组件物流仿真
- 核心目标: 确保组件能安全到达安装位置(终点)
- 最高优先级: 减少碰撞(安全性)
- 次要优先级: 路径复杂度/效率(时间成本)
- 不涉及: 经济成本
1.2 设计原则
- 实用优先: 指标不在于多,而在于有用
- 聚焦终点: 核心目标是"找出到同一安装位置的最佳路径"
- 可解释性: 每个指标和评分都要有明确的物理意义
- 可操作性: 建议要具体,告诉用户"怎么做"
二、策略模式
2.1 三种分析策略
| 策略 |
权重配置(安全/效率/转弯/曲折/冗余) |
适用场景 |
| 安全优先 |
50% / 20% / 10% / 10% / 10% |
精密/易损组件,首次运输 |
| 效率优先 |
20% / 40% / 15% / 15% / 10% |
紧急任务,多次往返 |
| 平衡模式 |
35% / 30% / 10% / 15% / 10% |
通用场景(默认) |
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.20, 0.10, 0.10, 0.10 },
[EfficiencyFirst] = new[] { 0.20, 0.40, 0.15, 0.15, 0.10 },
[Balanced] = new[] { 0.35, 0.30, 0.10, 0.15, 0.10 }
};
}
三、指标体系(5维度)
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);
3.5 冗余度(通道冗余度)
// 获取路径经过的通道
Channels = GetChannelsAlongPath(this);
// 通道最小限宽限高
MinChannelWidth = Channels.Min(c => c.WidthLimit);
MinChannelHeight = Channels.Min(c => c.HeightLimit);
// 车辆实际尺寸(含安全间隙)
EffectiveVehicleWidth = MaxVehicleWidth + SafetyMargin;
EffectiveVehicleHeight = MaxVehicleHeight + SafetyMargin;
// 冗余率
WidthRedundancy = (MinChannelWidth - EffectiveVehicleWidth) / EffectiveVehicleWidth;
HeightRedundancy = (MinChannelHeight - EffectiveVehicleHeight) / EffectiveVehicleHeight;
// 冗余度分(0-100)
RedundancyScore = Min(100, (WidthRedundancy + HeightRedundancy) / 2 * 100);
四、同一起终点分析(核心功能)
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个转弯,建议减少急转弯 |
| 冗余建议 |
冗余度<20% |
通道余量较小,建议确认车辆尺寸匹配 |
| 组内对比 |
组内路径>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, -- 曲折度分
RedundancyScore 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 |
修改,增加可视化元素 |
| 2.3 图表组件 |
src/UI/WPF/Views/PathAnalysisCharts.xaml |
新建,雷达图/柱状图 |
Phase 3: HTML报告(第三步)
| 任务 |
文件 |
说明 |
| 3.1 报告生成器 |
src/Core/PathAnalysisReportGenerator.cs |
新建,HTML生成逻辑 |
| 3.2 Chart.js部署 |
resources/js/chart.min.js |
下载本地Chart.js |
| 3.3 报告模板 |
resources/templates/ |
新建,HTML模板文件 |
十、关键算法伪代码
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 redundancy = analysis.RedundancyScore; // 冗余
// 加权计算
double weightedScore =
safety * weights[0] +
efficiency * weights[1] +
turn * weights[2] +
tortuosity * weights[3] +
redundancy * weights[4];
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);
analysis.RedundancyScore = CalculateRedundancyScore(route, context.Channels);
// 4. 计算综合评分
analysis.WeightedScore = CalculateWeightedScore(analysis, context.Strategy);
return analysis;
}
十一、界面设计要点
11.1 路径分析对话框布局
+----------------------------------------------------------+
| 路径分析 - 多路径对比 [关闭] |
+----------------------------------------------------------+
| +----------------+ +------------------+ +-----------+ |
| | 路径选择 | | 对比分析表格 | | 分析结果 | |
| | - 路径A | | 名称|安全|效率|... | | 最佳路径 | |
| | - 路径B [x] | | A | 90 | 85 |... | | 优化建议 | |
| | - 路径C [x] | | B |100 | 70 |... | | ... | |
| | | | C | 80 | 90 |... | | | |
| | [全选][清空] | +------------------+ +-----------+ |
| | | +------------------+ |
| | 策略: | | 雷达图可视化 | |
| | ○ 安全优先 | | | |
| | ○ 效率优先 | +------------------+ |
| | ● 平衡模式 | +------------------+ |
| | | | 同终点组分析 | |
| | [开始分析] | | 组1: 终点A (3条) | |
| +----------------+ | - 路径B [推荐] | |
| | - 路径A | |
| | - 路径C | |
| +------------------+ |
+----------------------------------------------------------+
| [导出报告] [关闭] |
+----------------------------------------------------------+
11.2 可视化元素
- 雷达图: 展示单条路径5维度分数
- 柱状图: 组内路径长度/时间对比
- 表格: 所有路径的详细指标
- 推荐卡片: 高亮显示最佳路径
- 热点标记: 在路径上标注碰撞热点位置
十二、HTML报告结构
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>路径分析报告</title>
<!-- 本地Chart.js -->
<script src="./js/chart.min.js"></script>
<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; }
.metric-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 15px; }
.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. 详细数据表格 -->
<!-- 6. 优化建议 -->
<!-- 7. 技术参数 -->
</body>
</html>
十三、风险评估与应对
| 风险 |
影响 |
应对措施 |
| 碰撞位置数据缺失 |
热点计算失败 |
使用碰撞对象中心点作为近似 |
| 通道属性未设置 |
冗余度无法计算 |
使用默认值,并在报告中提示 |
| 路径无边数据 |
转弯分析失败 |
退化为直线分析 |
| 单一路径无对比 |
组内分析无意义 |
隐藏组内对比部分 |
十四、验收标准
14.1 Phase 1 验收
14.2 Phase 2 验收
14.3 Phase 3 验收
附录:参考文件
- 现有碰撞报告生成器:
src/Utils/CollisionReportHtmlGenerator.cs
- 通道属性管理器:
src/Core/Properties/CategoryAttributeManager.cs
- 路径数据模型:
src/Core/PathPlanningModels.cs
- 数据库操作:
src/Core/PathDatabase.cs
- 单位转换:
src/Utils/UnitsConverter.cs