Skip to content

feat: field map calibration stage 1 - #241

Merged
tfield merged 2 commits into
mainfrom
feat/field-map-calibration
Apr 17, 2026
Merged

feat: field map calibration stage 1#241
tfield merged 2 commits into
mainfrom
feat/field-map-calibration

Conversation

@tfield

@tfield tfield commented Apr 17, 2026

Copy link
Copy Markdown
Contributor

Admin page at /admin/field-map-calibration walks through a 4-click corner calibration, derives a pure-TS homography, and renders a 1-metre grid, coordinate axes, and a fixed robot pose at (2, 2, 0°) as a visual sanity check.

What's included

  • Homography math (app/common/field/homography.ts): 4-point DLT solver with Gaussian elimination (no external deps). isCalibrationWellFormed rejects colinear/too-close/bowtie click orders before they reach the solver.
  • Types & API client (app/types/FieldCalibration.ts, app/common/field/fieldConstants.ts, app/common/storage/rb.ts): getFieldCalibration returns null on 404 (intentional divergence from the default idiom — first load legitimately has no record); saveFieldCalibration follows the standard throw-on-non-OK idiom.
  • Overlay component (FieldCalibrationOverlay.tsx): field image + normalized 0..1 SVG overlay, pinned to the same rect via aspect-ratio + absolute positioning. Clicks produce normalized image coords directly.
  • Calibration page (calibration-page.tsx): state machine (idle → picking-corner-0..3 → ready), Reset/Save/Verify buttons, admin-menu entry, route wiring. Verify button prints round-trip deltas in mm so numerical issues surface before Stage 2 telemetry playback hits them.
  • Colour-blind palette (global.css): Paul Tol "Bright" set, dual-encoded (shape + stroke width + letter labels), with dark-mode overrides.
  • Design doc (docs/field-map-calibration.md) covering conventions, flow, math, data model, API, palette rationale, and Stage 2 roadmap.
  • Plan (docs/plans/2026-04-17-001-feat-field-map-calibration-stage-1-plan.md) included for traceability.

Verification

  • npm run typecheck — clean
  • npm run build — clean
  • Dev server smoke-tested: /admin/field-map-calibration returns 200 and renders the page component with the expected CSS classes.

Manual testing still needed (requires running RavenBrain + login)

  • Click-through on the bundled 2026 field image and confirm the 1-metre grid lines up with visible field features
  • Verify button shows sub-millimetre round-trip deltas
  • Dark-mode + deuteranopia simulator pass
  • iPhone 5 viewport check (lower priority per project constraints)

Pairs with the RavenBrain PR on the same branch (REST API + V27 migration + 11 API tests, all green).

Admin page at /admin/field-map-calibration walks through a 4-click
corner calibration, derives a pure-TS homography, and renders a 1-metre
grid, coordinate axes, and a fixed robot pose at (2, 2, 0 deg) as a
visual sanity check.

- homography.ts: 4-point DLT solver with Gaussian elimination (no deps);
  includes isCalibrationWellFormed to reject colinear/too-close/bowtie
  quads before feeding the solver.
- fieldConstants.ts, FieldCalibration type, and rb.ts helpers
  (getFieldCalibration returns null on 404; saveFieldCalibration
  throws on non-OK).
- FieldCalibrationOverlay renders the field image + normalized 0..1
  SVG overlay; clicks land in normalized image coords directly.
- Calibration page with state machine, Reset/Save/Verify buttons.
  Verify button prints round-trip deltas in mm so numerical issues
  surface before Stage 2 telemetry playback hits them.
- Colour-blind-friendly palette (Paul Tol Bright), dual-encoded with
  shape and stroke width; dark-mode overrides.
- Admin-menu entry and docs/field-map-calibration.md design doc.
The corner-click workflow was unclear — the first-corner instruction
only appeared once the user pressed Start, and driver-station-relative
language was missing.

- Persistent 4-row corner table above the overlay shows all four
  corners with alliance badges, driver-station-relative headings, and
  plain-language hints ("bottom-left of the field image"), visible
  from the moment the page loads.
- Each row shows its status: a green check after it's been clicked,
  an accent-highlighted arrow for the row you're expected to click
  next, a dot otherwise.
- phaseHint now leads with the next corner's description in both
  idle and picking phases, so the admin always knows what corner A is
  before pressing Start.
@tfield
tfield merged commit e868b09 into main Apr 17, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant