Summary
Replace the current out-of-focus annotated_frames fixtures with sharper captures, and re-expand the fixture set now that the #170 determinism blocker is resolved.
Background
crates/core/tests/fixtures/annotated_frames/ feeds the absolute corner-error gate (tests/absolute_corner_error.rs, #166 Track A): each fixture is a JPEG of the printed pinball marker plus a .corners.json with the four corners in TL/TR/BR/BL order. The test reprojects each backend's homography corners and asserts max_err <= baseline + 0.5 px.
Two problems today:
- The images are poor. The fixtures' own README says it plainly: "The current
pinball-seq{1..4}.jpg fixtures show what not to do (out of focus → matcher returns matched_id = -1)." An out-of-focus gate image is a weak signal — it exercises the matcher's failure mode more than its accuracy.
- The set is down to 2 frames (
pinball-seq1, pinball-seq4). seq2/seq3 were dropped for run-to-run Rust non-determinism, and pinball-demo for cross-platform C++ divergence.
Why now: the blocker is lifted
The README says the dropped fixtures "will be re-added once #170 lands cross-platform determinism in both backends." That condition now appears met:
So we should be able to hold more frames stable across platforms than we could in May.
Scope
Notes
- No code change needed to add fixtures — the test globs
*.corners.json.
- Commit
.jpg + .corners.json + baseline.json together so the baseline stays in sync.
- Report matched_id + per-backend max-err in the PR body so reviewers can see what's being gated.
Related
Summary
Replace the current out-of-focus
annotated_framesfixtures with sharper captures, and re-expand the fixture set now that the #170 determinism blocker is resolved.Background
crates/core/tests/fixtures/annotated_frames/feeds the absolute corner-error gate (tests/absolute_corner_error.rs, #166 Track A): each fixture is a JPEG of the printedpinballmarker plus a.corners.jsonwith the four corners inTL/TR/BR/BLorder. The test reprojects each backend's homography corners and assertsmax_err <= baseline + 0.5 px.Two problems today:
pinball-seq{1..4}.jpgfixtures show what not to do (out of focus → matcher returnsmatched_id = -1)." An out-of-focus gate image is a weak signal — it exercises the matcher's failure mode more than its accuracy.pinball-seq1,pinball-seq4).seq2/seq3were dropped for run-to-run Rust non-determinism, andpinball-demofor cross-platform C++ divergence.Why now: the blocker is lifted
The README says the dropped fixtures "will be re-added once #170 lands cross-platform determinism in both backends." That condition now appears met:
HashMap→BTreeMapfor Hough vote tally + VisualDatabase keyframes (investigate: Rust backend matched_id is non-deterministic across runs (HashMap random hasher likely affecting BHC tree topology) #170/fix(kpm): use BTreeMap for Hough vote tally and VisualDatabase keyframes to remove Rust-side matcher nondeterminism (refs #170) #171), removing the BHC-topology non-determinism.unordered_map→std::mapviawebarkit/WebARKitLib#39, pulled in by the submodule bump in PR chore(submodule): bump WebARKitLib for std::map matcher-determinism fix (refs #170) #172. (Re-confirmed while closing test(kpm): test_full_pipeline_pose fails on Windows with pose component out of tolerance #118, where this same mechanism was the root cause.)So we should be able to hold more frames stable across platforms than we could in May.
Scope
pinballmarker per the README recipe: tap-to-focus, marker filling 40–80% of frame, no motion blur, good contrast.simple_nft_dual(renders both backends' outlines) before annotating.tools/annotate_corners/index.html(TL → TR → BR → BL).pinball-seq1/seq4and re-add the dropped frames (or fresh equivalents) — target ~4–5 stable fixtures.WEBARKIT_REGEN_CORNER_BASELINE=1 cargo test --test absolute_corner_error --features dual-mode -- --nocaptureREGRESSION_EPSILON_PX(currently widened to ~2.0 px to absorb the old drift) — with determinism fixed and sharper images, a tighter epsilon means a stronger gate.seq1"rock-solid (sub-pixel)" while the capture section lumpsseq1..4as out-of-focus), and refresh the "why only two frames" section.Notes
*.corners.json..jpg+.corners.json+baseline.jsontogether so the baseline stays in sync.Related
unordered_maproot cause was re-confirmed