> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Build a validated coarse-path smoothing module that compares cubic B-spline, local cubic Bézier, and piecewise quintic paths, then exports reproducible IEEE-style Chinese reports for existing and fast fixture scenarios.
**Architecture:** Add `PathSmoothing` beside `CoarsePath`; keep contracts, shared geometry processing, algorithms, validation, comparison, and rendering isolated. Every algorithm consumes the same preprocessed direction segments, every candidate passes the same analyzer and full-footprint validator, and only accepted results reach the formal facade. Reporting consumes immutable comparison data and cannot affect planning status.
**Tech Stack:** C# 10, .NET Standard 2.0, existing `PlanningGridMap`/`FootprintCollisionChecker`, PowerShell reflection tests, Newtonsoft.Json 13.0.4, StbImageWriteSharp 1.16.7, System.Drawing.Common 10.0.10 on Windows.
## Global Constraints
- Core units are m, rad, and 1/m; no mm or degree conversion inside smoothing algorithms.
- Never differentiate, resample, or fit across a gear-switch duplicate pair.
- Default output spacing is `0.05 m`; default swept-collision step is `0.025 m`.
- A formal result publishes a path only for `Success` or explicitly verified `FallbackToCoarsePath`.
- Rejected candidates may appear only in comparison diagnostics, never in `PathSmoothingResult.Path`.
- No speed, acceleration, time, SQP, Frenet, chassis, sensor, localization, or UI dependencies.
- Figure size is `7.16 × 5.2 in`; PNG size is `2148 × 1560 px` with 300 dpi metadata.
- Chinese text uses `SimSun`; English, numbers, Greek, and mathematics use `Times New Roman`.
- Fixed method colors are raw `#4D4D4D`, B-spline `#0072B2`, Bézier `#D55E00`, quintic `#009E73`, and curvature limits `#CC79A7`.
-`System.Drawing.Common` is a Windows-only report-rendering dependency; smoothing, validation, comparison, SVG, and CSV remain independent of its runtime availability.
- Follow TDD for every task: failing verification first, minimal implementation second, full relevant verification before commit.
- Produces: `PathSmoothingRequest`; `PathSmoothingResult.Success(...)`; `PathSmoothingResult.Fallback(...)`; `PathSmoothingResult.Failure(...)`; all public enums and value objects used below.
- [ ]**Step 1: Write the failing contract verification**
Create a reflection script that loads `ClumsyPilot.dll`, resolves every type listed above, and verifies these exact defaults and invariants:
Assert-Near0.05$configuration.OutputSpacingMeters'Default output spacing must be 0.05 m.'
Assert-Near0.025$configuration.MaximumCollisionCheckStepMeters'Default collision step must be 0.025 m.'
Assert-Equal4$configuration.RetryStrengthScales.Count'Retry schedule must contain four entries.'
Assert-Near1.0$configuration.RetryStrengthScales[0]'First retry scale must be 1.0.'
Assert-Near0.25$configuration.RetryStrengthScales[3]'Last retry scale must be 0.25.'
$failed=$resultType.GetMethod('Failure').Invoke(
$null,
@([Enum]::Parse($statusType,'InvalidInput'),
[Activator]::CreateInstance($diagnosticsType)))
Assert-Equal0$failed.Path.Count'Failure must publish no path.'
Assert-Equal0$failed.Segments.Count'Failure must publish no segments.'
```
Also construct a `SmoothedPathPoint` and assert all units/properties, construct two `SmoothedPathSegment` instances, and prove returned collections cannot be mutated.
- [ ]**Step 2: Run the verification and confirm RED**
Define parameterless immutable-empty defaults for `PathQualityMetrics` and `PathSmoothingDiagnostics`, plus overloads that accept all measured values. The three result factories are:
`PathSmoothingResult` must copy all input lists into `ReadOnlyCollection<T>`. Reject `Success`/`Fallback` factories with empty paths or segments; reject `Failure` with a success-like status.
- [ ]**Step 4: Run contract verification and existing integration verification**
- Produces: `PathSmoothingPreprocessor.TryPrepare(request, out PreparedPath, out string)` and `PathGeometryAnalyzer.TryAnalyze(candidateSegments, spacing, out PathGeometryAnalysis analysis, out string reason)`.
For each direction segment, recompute arc length from Euclidean position increments, unwrap heading from travel tangents, and use stable one-sided/central differences:
- Produces: `TryValidate(..., out IReadOnlyList<SmoothedPathPoint> pathWithClearance, out double minimumClearance, out string reason)`.
- [ ]**Step 1: Write failing safety cases**
Create an empty map, an occupied rectangle map, and paths that are: valid; point-colliding; swept-motion-colliding; outside bounds; over maximum curvature; changed at a gear switch; and overclaiming clearance.
```powershell
Assert-False$collisionAccepted'A smoothing candidate that cuts through an obstacle must be rejected.'
Assert-False$curvatureAccepted'A smoothing candidate above vehicle maximum curvature must be rejected.'
Assert-False$switchAccepted'A moved gear-switch pose must be rejected.'
Assert-True$validAccepted'A valid straight candidate must pass.'
- [ ]**Step 3: Implement validator using existing collision semantics**
For every point call `FootprintCollisionChecker.IsPoseCollisionFree`; for every non-duplicate adjacent pair call `IsSweptMotionCollisionFree`. Enforce:
Verify a straight segment remains collinear, a five-point corner becomes tangent-continuous, endpoints and travel tangents are exact, and every displacement stays within its supplied movement radius.
- [ ]**Step 3: Implement clamped basis evaluation and constrained control points**
Use degree 3, endpoint knot multiplicity 4, and Cox–de Boor basis evaluation. Fix the first/last control points to endpoints; place adjacent control points on endpoint travel tangents. Blend remaining control points toward local three-point averages:
Assert no window is created for a straight line; one corner creates one replacement; overlapping windows merge; outside-window samples remain bitwise equal; endpoints and switch points remain fixed.
For each evaluated point, compare its displacement from the parameter-matched interpolated original reference with `max(0, reference.BodyClearance - MinimumClearanceReserveMeters)`. If any point exceeds that radius, return a failed candidate with no geometry; do not pointwise clamp or project curve samples. Retain original samples outside merged windows.
- Produces: C2-connected local polynomial segments without crossing direction boundaries.
- [ ]**Step 1: Write failing continuity and degeneracy tests**
At every shared knot evaluate left/right position, first derivative, and second derivative; assert equality within `1e-6`. Verify exact endpoint pose, bounded movement, and stable failure for a segment shorter than the configured minimum knot spacing.
For each knot interval use normalized `t ∈ [0,1]` and solve the six coefficients independently for X and Y from:
```text
p(0)=p0, p(1)=p1
p'(0)=v0, p'(1)=v1
p''(0)=a0, p''(1)=a1
```
Derive endpoint velocities from travel tangents times interval length. Blend shared accelerations once per knot and reuse the same value on both adjacent intervals. Reject singular or non-finite coefficients before sampling.
- [ ]**Step 4: Run quintic, geometry, and validator checks**
Cover valid straight success, invalid input, cancellation, infeasible-without-fallback, and infeasible-with-verified-fallback. Assert fallback points use `CoarsePathFallback` and status never equals `Success`.
Validate the coarse path before smoothing. On allowed fallback, convert the revalidated coarse points to `SmoothedPathPoint` with `CoarsePathFallback`, re-run shared geometry analysis, and return `Fallback`, preserving the failed method diagnostics.
- [ ]**Step 4: Run all core smoothing verifications**
- Ranking order: feasible count; median variation energy; worst peak utilization; worst clearance loss; median length increase; median elapsed.
- [ ]**Step 1: Write failing comparison and ranking tests**
Create synthetic entries whose order changes at each tie-break level. Verify one method failure does not stop the remaining methods, cancellation does, and no feasible method produces a null recommendation.
Also assert the result always contains one separately analyzed raw-path baseline plus exactly one entry for each requested method; the raw baseline is never treated as a candidate method in ranking.
Use absolute deltas when a raw denominator has magnitude below `1e-12`. The comparison service must force `AllowFallbackToCoarsePath = false` so fallback cannot masquerade as method success.
Verify unique IDs, version > 0, matching fingerprint, valid segment coverage, and that fixture-only loading has no reference to `HybridAStarPlanner`.
- [ ]**Step 2: Write failing end-to-end tests**
For `ExplicitEmpty`, `RectangleDetour`, `ManualAndTwoLeg`, and `ReverseGearSwitch`, call the existing planner then comparison service. Assert the raw path is unchanged and every successful smoothing entry preserves segment count and gear-switch count.
`SmoothingFixtureGenerator.Generate(string outputPath, bool overwrite)` must refuse an existing target when `overwrite` is false. The script maps `-Overwrite` to that argument; normal tests call only `LoadAndVerify` and never regenerate data. Each obstacle is serialized as a typed circle or axis-aligned rectangle DTO so the loader can rebuild the exact `PlanningGridMap` without Hybrid A*.
- [ ]**Step 5: Run fixture and integration checks**
- Produces: one immutable figure model, UTF-8 SVG, and UTF-8-BOM CSV.
- [ ]**Step 1: Write failing style and serialization tests**
Assert exact colors, line styles, panel labels, view box, equal XY scale, legend order, XML escaping, UTF-8 Chinese, BOM bytes `EF BB BF`, and invariant decimal points.
Include one rejected candidate in the model and assert its normal method-colored curve plus violation cross markers are present while its metrics row says `Infeasible`. Include one numerical failure and assert its legend/row remains but no fake path element is emitted.
- [ ]**Step 3: Implement one physical layout model**
Define all coordinates in typographic points (`72 pt/in`):
```csharp
publicconstdoubleFigureWidthPoints=7.16d*72d;
publicconstdoubleFigureHeightPoints=5.20d*72d;
publicconststringRawColor="#4D4D4D";
publicconststringBSplineColor="#0072B2";
publicconststringBezierColor="#D55E00";
publicconststringQuinticColor="#009E73";
publicconststringLimitColor="#CC79A7";
```
Allocate 60% width to panel `(a)`, split the right side between `(b)` curvature and `(c)` metrics, and compute one world-to-panel transform with equal X/Y scale.
- [ ]**Step 4: Implement SVG and CSV**
SVG text must use explicit runs:
```xml
<text><tspanfont-family="SimSun">车辆曲率 </tspan><tspanfont-family="Times New Roman">κ (m⁻¹)</tspan></text>
Expected: restore exits 0. Do not add cross-platform fallback switches; Microsoft documents `System.Drawing.Common` as Windows-only.
- [ ]**Step 4: Implement exact font resolution and mixed-run baseline layout**
Use `InstalledFontCollection` to require `SimSun` and `Times New Roman`. Split text by Unicode category/CJK ranges, measure each run with typographic `StringFormat`, and align runs by font-family ascent:
Return `FontUnavailable` before creating output files if either exact family is absent.
- [ ]**Step 5: Render the shared model and write validated PNG**
Render at `2148 × 1560`, opaque white background, anti-aliased geometry, and no gradients/shadows. Convert bitmap pixels to RGBA and use the existing validated PNG path, extending it to insert a `pHYs` chunk with `11811` pixels/meter and correct CRC before `IDAT`.
Export all three files to temporary siblings, validate each, then rename into place. On failure, remove only those exact temporary siblings.
- [ ]**Step 6: Run PNG, map-image, and build checks**
- Produces: documented formal call example and a developer-only batch command that writes reports under `ClumsyPilot/obj/path_smoothing_reports`.
- [ ]**Step 1: Write failing documentation and batch-entry verification**
Assert README contains exact sections for units, facade usage, status handling, fallback, fixture freshness, IEEE colors/fonts, Windows PNG limitation, SQP boundary, and output files. Assert the batch runner offers `-FixtureOnly` and never writes under source directories.
The batch script builds once, runs eight fixtures by default, optionally runs the four end-to-end cases, prints one-line metrics per method, and writes only beneath `ClumsyPilot/obj/path_smoothing_reports`.
- [ ]**Step 4: Run the complete verification suite**
Inspect `straight`, `rectangle-detour`, and `forward-reverse-switch` PNG/SVG files. Confirm four-method legend order, equal path axes, readable 8–10 pt text, no Chinese mojibake, no clipping/overlap, curvature limits, and infeasible markers where applicable.