NavisworksTransport/doc/working/最少转弯路径算法Plan20250909.md

5.9 KiB
Raw Permalink Blame History

⎿ 最少转弯路径实现计划基于Roy-T.AStar官方API

实施策略:严格保护现有算法

阶段一:数据结构扩展

1. 添加路径策略枚举

位置src/PathPlanning/PathPlanningModels.cs
public enum PathStrategy
{
    Shortest = 0,    // 默认:标准最短路径(现有行为)
    Straightest = 1  // 新增:直线优先路径
}

2. 扩展AutoPathFinder方法签名

位置src/PathPlanning/AutoPathFinder.cs
- 新增重载FindPath(..., PathStrategy strategy = PathStrategy.Shortest)
- 保留所有现有方法不变

阶段二:核心算法实现

3. 实现方向感知的网格转换

新增方法ConvertToAStarGridWithStrategy()
private Grid ConvertToAStarGridWithStrategy(GridMap gridMap, Point3D startPos, Point3D endPos, PathStrategy strategy,
double objectHeight)
{
    if (strategy == PathStrategy.Shortest) {
        // 调用现有方法保证100%兼容
        return ConvertToAStarGridWith2_5D(gridMap, channelCoverage, objectHeight);
    }

    // 直线优先实现
    return ConvertToAStarGridStraightest(gridMap, startPos, endPos, objectHeight);
}

4. 直线优先算法核心

基于文档第127行的AddEdge模式
private Grid ConvertToAStarGridStraightest(GridMap gridMap, Point3D start, Point3D end, double objectHeight)
{
    // 1. 计算主方向
    double dx = Math.Abs(end.X - start.X);
    double dy = Math.Abs(end.Y - start.Y);
    bool preferHorizontal = dx > dy;

    // 2. 差异化速度设置基于文档的Velocity.FromKilometersPerHour
    var mainDirectionVelocity = Velocity.FromKilometersPerHour(10);  // 主方向:低成本
    var crossDirectionVelocity = Velocity.FromKilometersPerHour(2);  // 次方向:高成本
    var diagonalVelocity = Velocity.FromKilometersPerHour(5);        // 对角线:中等成本

    // 3. 按现有模式创建和断开网格文档第104-108行
    var grid = Grid.CreateGridWithLateralConnections(gridSize, cellSize, mainDirectionVelocity);

    // 先断开所有连接
    for (int x = 0; x < gridMap.Width; x++) {
        for (int y = 0; y < gridMap.Height; y++) {
            grid.DisconnectNode(new GridPosition(x, y));
        }
    }

    // 4. 智能连接根据方向设置不同速度文档第115-126行模式
    for (int x = 0; x < gridMap.Width; x++) {
        for (int y = 0; y < gridMap.Height; y++) {
            if (IsPassableWithHeight(gridMap.Cells[x, y], objectHeight)) {
                var pos = new GridPosition(x, y);

                // 水平连接
                if (x + 1 < gridMap.Width && IsPassableWithHeight(gridMap.Cells[x + 1, y], objectHeight)) {
                    var rightPos = new GridPosition(x + 1, y);
                    var velocity = preferHorizontal ? mainDirectionVelocity : crossDirectionVelocity;
                    grid.AddEdge(pos, rightPos, velocity);
                    grid.AddEdge(rightPos, pos, velocity);
                }

                // 垂直连接
                if (y + 1 < gridMap.Height && IsPassableWithHeight(gridMap.Cells[x, y + 1], objectHeight)) {
                    var bottomPos = new GridPosition(x, y + 1);
                    var velocity = preferHorizontal ? crossDirectionVelocity : mainDirectionVelocity;
                    grid.AddEdge(pos, bottomPos, velocity);
                    grid.AddEdge(bottomPos, pos, velocity);
                }

                // 对角线连接(可选)
                if (x + 1 < gridMap.Width && y + 1 < gridMap.Height &&
                    IsPassableWithHeight(gridMap.Cells[x + 1, y + 1], objectHeight)) {
                    var diagonalPos = new GridPosition(x + 1, y + 1);
                    grid.AddEdge(pos, diagonalPos, diagonalVelocity);
                    grid.AddEdge(diagonalPos, pos, diagonalVelocity);
                }
            }
        }
    }

    return grid;
}

阶段三:集成到现有流程

5. 扩展PathPlanningManager调用

位置src/Core/PathPlanningManager.cs
- 在AutoPlanPath方法中添加可选策略参数
- 默认值确保现有调用完全不变

6. 策略路由逻辑

public Task<PathRoute> AutoPlanPath(..., PathStrategy strategy = PathStrategy.Shortest)
{
    // 现有逻辑保持不变...

    // 策略感知的路径查找
    pathResult = pathFinder.FindPath(startPoint.Position, endPoint.Position, gridMap, channelCoverage, objectHeight,
strategy);
}

阶段四:质量保证

7. 兼容性验证

- ✅ 所有现有单元测试必须通过
- ✅ 默认调用行为与当前完全一致
- ✅ 现有UI调用无需任何修改

8. 功能验证

- ✅ 对比两种策略的路径差异
- ✅ 验证直线优先路径确实减少转弯
- ✅ 性能测试确保无显著性能影响

9. 调试支持

基于文档第237行的日志模式
LogManager.Info($"[直线优先] 主方向: {(preferHorizontal ? "水平" : "垂直")}, 起点({start.X:F2},{start.Y:F2}),
终点({end.X:F2},{end.Y:F2})");
LogManager.Info($"[速度设置] 主方向: {mainDirectionVelocity.InKilometersPerHour}km/h, 次方向:
{crossDirectionVelocity.InKilometersPerHour}km/h");

交付成果

1. 零破坏性扩展现有功能100%保持原样
2. 基于官方API使用Roy-T.AStar文档化的最佳实践
3. 易于使用:通过可选参数启用新功能
4. 充分测试:确保稳定性和兼容性
5. 详细日志:便于调试和性能分析

测试用例设计

- 现有路径 vs 直线优先路径的转弯次数对比
- 长距离直线路径的优化效果验证
- 复杂地形下的算法鲁棒性测试