docs: gate Local G2 pipeline on stable region order
This commit is contained in:
@@ -1189,6 +1189,7 @@ git commit -m "feat: validate local G2 candidate quality"
|
||||
**Files:**
|
||||
|
||||
- Create: `ClumsyPilot/ParkrobTrajplanner/PathSmoothing/LocalG2/LocalG2PreSmoothingPipeline.cs`
|
||||
- Consume unchanged: `ClumsyPilot/ParkrobTrajplanner/PathSmoothing/LocalG2/LocalG2RegionWorkOrder.cs`
|
||||
- Modify: `ClumsyPilot/ParkrobTrajplanner/PathSmoothing/Facade/PathSmoothingService.cs`
|
||||
- Create: `ClumsyPilot/tests/verify_path_smoothing_local_g2_integration.ps1`
|
||||
- Modify: `ClumsyPilot/tests/verify_path_smoothing_service.ps1`
|
||||
@@ -1196,6 +1197,8 @@ git commit -m "feat: validate local G2 candidate quality"
|
||||
**Interfaces:**
|
||||
|
||||
- Consumes: validated request, prepared path and fair raw baseline.
|
||||
- Consumes `LocalG2RegionWorkOrder.TryCreate(...)`; pipeline iteration must not use report-order regions directly.
|
||||
- Publishes region reports in the detector's original ascending order, independently of processing order.
|
||||
- Produces:
|
||||
|
||||
```csharp
|
||||
@@ -1242,6 +1245,21 @@ Assert-True ($result.Diagnostics.Metrics.MinimumBodyClearanceMeters -ge 0.02) `
|
||||
|
||||
For `Complete` and `PartialImprovement`, require at least one region report with `Improved`. For `PartialImprovement`, require at least one `RetainedOriginal`. Run every fixture twice and compare status, point count, coordinates and region reports.
|
||||
|
||||
Create one deterministic same-direction fixture with two disjoint detected
|
||||
regions. Both accepted candidates must change their local replacement length.
|
||||
Assert:
|
||||
|
||||
1. the larger-original-arc region is evaluated first;
|
||||
2. the second processed region still matches the intended original front
|
||||
window endpoints;
|
||||
3. both reports are `Improved`;
|
||||
4. reports are published in ascending original arc order;
|
||||
5. both Local G2 replacements are present in the final full path;
|
||||
6. two identical requests produce equal status, candidate indices, report
|
||||
order, point count and point coordinates.
|
||||
|
||||
The test must fail if the pipeline replaces `workRegions` with `regions`.
|
||||
|
||||
Also create two explicit service cases:
|
||||
|
||||
```powershell
|
||||
@@ -1273,31 +1291,68 @@ Expected: fail because the service cannot resolve `LocalG2Quintic`.
|
||||
Pipeline pseudocode must be implemented directly:
|
||||
|
||||
```csharp
|
||||
if (!_workOrder.TryCreate(
|
||||
regions,
|
||||
out IReadOnlyList<LocalG2SmoothingRegion> workRegions,
|
||||
out string orderReason))
|
||||
{
|
||||
return PathSmoothingResult.Failure(
|
||||
PathSmoothingStatus.Failed,
|
||||
new PathSmoothingDiagnostics(
|
||||
new PathQualityMetrics(),
|
||||
TimeSpan.Zero,
|
||||
0,
|
||||
0d,
|
||||
orderReason));
|
||||
}
|
||||
|
||||
PreparedPath current = preparedPath;
|
||||
var reports = new List<PathSmoothingRegionReport>();
|
||||
var reportsByRegion = new Dictionary<LocalG2SmoothingRegion, PathSmoothingRegionReport>();
|
||||
int improvedCount = 0;
|
||||
|
||||
foreach (LocalG2SmoothingRegion region in regions)
|
||||
foreach (LocalG2SmoothingRegion region in workRegions)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
IReadOnlyList<LocalG2CandidateGeometry> candidates =
|
||||
_builder.Build(preparedPath.Segments[region.SegmentIndex], region, outputSpacing, options, cancellationToken);
|
||||
_builder.Build(
|
||||
preparedPath.Segments[region.SegmentIndex],
|
||||
region,
|
||||
outputSpacing,
|
||||
options,
|
||||
cancellationToken);
|
||||
var evaluations = new List<LocalG2CandidateEvaluation>();
|
||||
foreach (LocalG2CandidateGeometry candidate in candidates)
|
||||
evaluations.Add(_evaluator.Evaluate(preparedPath, current, region, candidate, request, options, cancellationToken));
|
||||
{
|
||||
evaluations.Add(
|
||||
_evaluator.Evaluate(
|
||||
preparedPath,
|
||||
current,
|
||||
region,
|
||||
candidate,
|
||||
request,
|
||||
options,
|
||||
cancellationToken));
|
||||
}
|
||||
|
||||
LocalG2CandidateEvaluation best = LocalG2CandidateEvaluator.SelectBest(evaluations);
|
||||
LocalG2CandidateEvaluation best =
|
||||
LocalG2CandidateEvaluator.SelectBest(evaluations);
|
||||
if (best != null && best.Accepted)
|
||||
{
|
||||
current = best.SplicedPreparedPath;
|
||||
improvedCount++;
|
||||
reports.Add(CreateImprovedReport(region, best));
|
||||
reportsByRegion.Add(region, CreateImprovedReport(region, best));
|
||||
}
|
||||
else
|
||||
{
|
||||
reports.Add(CreateRetainedReport(region, evaluations));
|
||||
reportsByRegion.Add(
|
||||
region,
|
||||
CreateRetainedReport(region, evaluations));
|
||||
}
|
||||
}
|
||||
|
||||
var reports = new List<PathSmoothingRegionReport>(regions.Count);
|
||||
for (int reportIndex = 0; reportIndex < regions.Count; reportIndex++)
|
||||
reports.Add(reportsByRegion[regions[reportIndex]]);
|
||||
```
|
||||
|
||||
Regions are disjoint after merging, so successful earlier replacements remain when a later region fails.
|
||||
|
||||
Reference in New Issue
Block a user