PathSmoothing 路径平滑(Local G2)
模块说明(Module Overview)
PathSmoothing 是 Hybrid A* 成功输出后的空间参考路径后处理模块。它只保留 Local G2 五次过渡算法:在同一行驶方向的粗路径段内检测车辆曲率跳变,尝试以局部五次曲线替换,并对整条结果进行车辆曲率、全车体碰撞、净空和曲率变化代价复核。
该模块不参与粗路径搜索接受条件,也不做时间参数化、速度、加速度、转向速率或动态障碍物处理。下游只能消费本模块已经发布的空间路径。
文件结构(File Structure)
PathSmoothing/
├── Contracts/ # 请求、结果、配置、状态、质量指标与区域报告
├── Facade/ # 正式平滑入口和离线比较入口
├── LocalG2/ # 跳变检测、窗口规划、候选生成、评估、拼接
├── Processing/ # 粗路径预处理、原始基线和几何分析
├── Validation/ # 全车体碰撞与车辆曲率复核
├── Output/
│ ├── Comparison/ # 原始路径与 Local G2 的稳定比较模型和摘要
│ └── Visualization/ # SVG、PNG、CSV 报告模型和导出器
├── Test/ # 固定夹具、演示入口和 Local G2 诊断证据
│ └── Fixtures/ # 版本化的成功粗路径快照
└── README.md
Algorithms/、旧的 Comparison/、旧的 Visualization/ 以及 B-spline、局部 Bezier、分段五次选项均已移除。输出相关代码统一归入 Output/,与 CoarsePath/Output/ 的组织方式保持一致。
平滑数据流(Smoothing Data Flow)
成功的 CoarsePath
-> PathSmoothingRequest 快照
-> 输入校验与 PathSmoothingPreprocessor
-> RawPathBaselineBuilder 原始路径全局复核
-> CurvatureTransitionDetector(仅同向 PathSegment 内)
-> LocalG2WindowPlanner
-> LocalG2CandidateBuilder / LocalG2CandidateEvaluator
-> LocalG2PathSplicer
-> 全路径曲率、碰撞、净空、代价复核
-> PathSmoothingResult.PublishLocalG2
Local G2 不跨换向段建立窗口。它处理的是同一前进或倒退段内、由运动原语摆角变化等原因形成的车辆曲率跳变,而不是把换向点作为平滑对象。
结果状态与发布规则(Result Status and Publication Rules)
下列四个状态都会发布已复核的 Path 和 Segments,可由下游消费:
| 状态 | 含义 |
|---|---|
Complete |
检测到的所有 Local G2 区域都被接受并替换。 |
PartialImprovement |
至少一个区域被替换,其余区域保留原始几何。 |
NotNeeded |
没有检测到同向段内的曲率跳变;发布已复核的原始路径。 |
Unchanged |
检测到区域,但所有候选都被拒绝;发布已复核的原始路径,并保留 RegionReports。 |
InvalidInput、Cancelled、Failed 和 Infeasible 不发布可消费路径。Unchanged 不是失败,它表示“安全门或质量门没有接受新候选”,不是“原始粗路径未经验证地回退”。
区域报告与拒绝原因
PathSmoothingRegionReport 按检测顺序记录每个 Local G2 区域。区域状态为 Improved 或 RetainedOriginal;后者可进一步给出 WindowUnavailable、CandidateGenerationFailed、Collision、InsufficientClearance、CurvatureExceeded、CurvatureOvershoot、DeviationExceeded、InsufficientImprovement、VariationCostRegression 或 GlobalValidationRollback。
候选先进行全车体碰撞复核,再检查净空余量。MinimumClearanceReserveMeters = 0d 只取消额外净空储备,不会取消车辆曲率、碰撞、数值有效性、偏差或曲率变化代价门。
坐标与单位(Coordinates and Units)
- 路径位置、弧长、窗口长度、偏差、净空和碰撞检查步长:m
- 航向:rad
- 车辆曲率:
1/m - 车辆曲率导数:
1/m^2 - 地图构建输入仍沿用 mm;
PlanningGridMap的路径复核查询使用 m
发布路径保留成功粗路径的首尾位姿,因此末端误差继承粗规划器已接受的目标容差。
最小调用示例(Minimal Call Example)
if (coarseResult.PlanningResult.Status != PlanningStatus.Success)
return;
var request = new PathSmoothingRequest(
coarseResult.PlanningResult.Path,
coarseResult.PlanningResult.Segments,
coarseResult.MapResult.Map,
job.Vehicle,
new PathSmoothingConfiguration());
PathSmoothingResult result = new PathSmoothingService().Smooth(request, cancellationToken);
bool published = result.Status == PathSmoothingStatus.Complete ||
result.Status == PathSmoothingStatus.PartialImprovement ||
result.Status == PathSmoothingStatus.NotNeeded ||
result.Status == PathSmoothingStatus.Unchanged;
if (published)
ConsumeSpatialReference(result.Path, result.Segments);
PathSmoothingConfiguration 没有算法选择开关;正式入口始终执行 Local G2。
详细使用指南(Detailed Usage Guide)
- 长期持有
PathSmoothingService,只向它传入成功的粗路径、方向分段、规划地图和车辆参数。 - 使用
PathSmoothingConfiguration调整输出采样、碰撞检查步长和 Local G2 窗口/质量门参数。 MinimumClearanceReserveMeters当前默认0d。需要额外净空时显式设置正值;碰撞约束始终存在。- 按上表判断结果是否已发布,随后消费
Path和Segments;不要以Failed或Cancelled的空路径继续规划。 - 对
PartialImprovement或Unchanged,读取RegionReports判断被保留的区域以及拒绝原因。
Local G2 关键选项位于 LocalG2Quintic:最小、首选和最大窗口长度,最大偏差,曲率跳变阈值,峰值曲率导数改善比,曲率变化代价回退比,以及每区候选数。
固定夹具报告与可视化(Fixture Reports and Visualization)
SmoothingScenarioFixtureLoader.LoadAndVerify 会校验 JSON 夹具的版本和指纹;夹具报告不重新运行 Hybrid A*。离线比较始终输出“原始粗路径 + Local G2”两组数据。
SmoothingReportExporter.Export(SmoothingReportExportRequest) 为每个场景写入 CSV、SVG 和 PNG。常规图固定为四张:
01-coarse-path-overview02-all-paths-comparison03-local-g2-overview04-curvature-comparison
当模型显式附带诊断候选时,额外写入 05-local-g2-diagnostic-candidate。诊断候选仅用于解释拒绝,不是发布路径。
报告默认写入 ClumsyPilot/obj/path_smoothing_reports 的调用方指定子目录。PNG 需要 Windows 的 SimSun 与 Times New Roman;若字体不可用,导出返回 FontUnavailable,SVG 和 CSV 仍可单独使用。
常见错误(Common Errors)
- 将未成功的 CoarsePath 直接传入平滑:应先检查
PlanningStatus.Success。 - 把
Unchanged当作失败:它仍然包含已复核的原始路径和区域报告。 - 认为净空余量为 0 会关闭碰撞检查:它只取消额外储备,不能绕过全车体碰撞和车辆曲率门。
- 在换向点两侧强行连续平滑:当前窗口检测明确不跨方向段。
- 使用过期夹具:修改粗路径场景或规划配置后,应按夹具生成/验证脚本更新快照。
第一版限制(First-Version Limits)
- 仅平滑同向段内的车辆曲率跳变;不跨换向点。
- 仅包含 Local G2 五次局部过渡,不提供多算法比较或算法回退。
- 只输出几何空间路径;没有时间、速度、加速度、转向速率和动态障碍物约束。
- Local G2 候选必须通过严格的全路径复核;在当前夹具上,
Unchanged和Failed仍是有价值的诊断结果,而不是自动放宽安全约束的信号。