Files
ParkingRobot/docs/superpowers/specs/2026-07-31-local-g2-soft-anchor-candidate-recovery-design.md
T

5.1 KiB
Raw Blame History

Local G2 Soft-Anchor Candidate Recovery Design

Goal

Repair the Local G2 candidate family so that a real, same-direction curvature transition can produce a candidate accepted by the existing evaluator, without weakening vehicle-curvature, raw-range, peak-gradient, collision, clearance, deviation, or global-validation gates.

Evidence and decision

The current two-piece quintic Hermite family holds every internal primitive boundary at its original position and heading. For the real SingleTurn fixture, a bounded sweep of internal derivative scales (0.50 through 1.60) and shared curvatures within the original [left, right] curvature interval produced no candidate that both remained in the original curvature range and reduced peak |dκ/ds| by the required 20 percent. This is a geometric-family limitation, not a service-dispatch or evaluator-threshold failure.

Three alternatives were considered:

  1. Relax curvature/range/quality gates. Rejected: it would weaken the safety and quality contract.
  2. Mark SingleTurn as Unchanged. Rejected: it contradicts the already approved main-route acceptance target and hides the incomplete candidate family.
  3. Keep all outer window boundary states exact while treating each internal primitive boundary as a bounded, deterministic soft anchor. Chosen: it expands geometry freedom only inside the existing 0.10 m deviation budget; every candidate still passes the unchanged evaluator before publication.

Candidate construction

For each LocalG2SmoothingRegion, the outer window endpoints remain exact position/tangent/curvature boundary conditions. At each internal curvature transition, candidate generation keeps the original vehicle heading and distance-weighted shared curvature, but may offset the internal anchor position along its original geometric normal:

P_soft = P_original + offset × N_travel
N_travel = (-sin(travelHeading), cos(travelHeading))

travelHeading continues to use vehicle heading for forward travel and vehicle heading minus π for reverse travel. The same offset profile is applied to all internal anchors in a combined region, so adjacent quintic pieces still share one position, heading, derivative scale, and curvature at each anchor and therefore remain G2.

The finite profile order for every legal window is:

  1. offset = 0.00 m, derivative multiplier 1.00 (exact-anchor baseline);
  2. offset = +0.05 m, derivative multiplier 0.85;
  3. offset = -0.05 m, derivative multiplier 1.15.

The signed offsets are intentionally both present; vehicle turn sign and map orientation must not choose a preferred side. A two-node, one-piece region has no internal anchor and therefore emits only the exact-anchor baseline. The existing global MaximumCandidatesPerRegion cap remains authoritative; profile enumeration is deterministic and stops at that cap. No configuration value is added in this recovery step.

The 0.05 m profile displacement is only a candidate-construction bound, not an acceptance relaxation. The unchanged evaluator must still prove the complete candidate's maximum deviation is at most the configured 0.10 m, as well as all curvature, collision, clearance, finite-value, direction, and quality gates.

Publication and failure behavior

The Task 8 pipeline continues to build candidates from the immutable original segment, evaluate them against the current path, process regions in work order, and publish reports in detector order. Soft-anchor candidates are ordinary candidates: they are never specially accepted. If none passes, the region is retained and the final result remains Unchanged or PartialImprovement as defined by the existing result contract.

Test-first acceptance

Before changing the builder, extend the real SingleTurn builder/evaluator regression to assert all of the following against actual preprocessor, detector, window planner, builder, and evaluator instances:

  • the exact-anchor baseline remains present and deterministic;
  • at least one emitted candidate is accepted by the unchanged evaluator;
  • the accepted candidate stays within the configured 0.10 m deviation limit, original curvature range, vehicle curvature limit, collision/clearance gates, and 20 percent peak-gradient-improvement gate;
  • the same request produces the same candidate sequence and selected result on two runs;
  • forward and reverse source/heading conventions remain unchanged.

The test must be observed failing before production changes, then pass after the smallest builder-only implementation. Task 8 service integration must then restore SingleTurn -> Complete and continue to prove cancellation, rollback, two-region work order, report order, and legacy-method isolation.

Scope

Production change is limited to LocalG2CandidateBuilder.cs; the focused candidate verifier and existing Task 8 integration/service files may change for TDD and end-to-end coverage. The previously authorized evaluator boundary de-duplication remains part of this Task 8 recovery. No safety threshold, validator tolerance, window length, vehicle model, comparison-default method, or collision/clearance behavior changes.