docs: design Local G2 soft anchor recovery
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
# 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:
|
||||
|
||||
```text
|
||||
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.
|
||||
Reference in New Issue
Block a user