Files
gps-denied-onboard/_docs/02_tasks/todo/AZ-702_khp20s30_calibration.md
T
Oleksandr Bezdieniezhnykh a12638dd92 [AZ-696] chore: cycle-2 bootstrap — gitignore tlog inputs, Step 9 PBIs
Pre-implement chore commit to land orchestration artifacts produced by
autodev cycle-2 Step 9 (New Task), so that Step 10 (Implement) starts
against a clean working tree.

What's included:

- .gitignore: exclude _docs/00_problem/input_data/**/*.{tlog,mp4,h264}
  (derkachi.tlog is a 5.8 MB binary input and stays out-of-band).
- _docs/02_tasks/todo/AZ-697..AZ-702: 6 new PBI specs under epic AZ-696
  (tlog ground-truth extractor, mid-flight trim+align, real-flight
  validation runner, replay map viz, HTTP replay API, KHP20S30 calib).
- _docs/02_tasks/_dependencies_table.md: dep edges for the 6 PBIs.
- _docs/_autodev_state.md: status -> in_progress, step 10 cycle 2.
- _docs/_process_leftovers/...opencv_pin_deferred.md: replay-attempt
  timestamp refreshed (gtsam-numpy-2 wheels still not published;
  leftover remains open).

No source code is modified by this commit.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-20 15:50:50 +03:00

4.9 KiB
Raw Blame History

Topotek KHP20S30 camera calibration (factory-sheet approximation)

Task: AZ-702_khp20s30_calibration Name: Provide a calibration JSON for the Topotek KHP20S30 nadir camera (factory-sheet approximation) Description: Compute and commit a CameraCalibrationArtifact JSON for the Derkachi camera (Topotek KHP20S30) from manufacturer factory data. Replaces the adti26.json placeholder that AC-3 currently uses. Documents the residual error vs a per-unit checkerboard refinement. Complexity: 1 point Dependencies: None Component: input_data / shared_helpers Tracker: AZ-702 Epic: AZ-696

Problem

_docs/00_problem/input_data/flight_derkachi/camera_info.md states the Topotek KHP20S30 intrinsics are unknown. tests/e2e/replay/conftest.py (line 5056) substitutes tests/fixtures/calibration/adti26.json as a placeholder. AC-3 (≤ 100 m horizontal error for 80 % of ticks) is @xfail until a real calibration ships.

The cheapest reasonable starting point is a factory-sheet approximation — compute K from the manufacturer's published focal length + sensor geometry, accept the 13 % focal-length residual as a documented budget, and let AC-3 either PASS or honestly FAIL with the residual attributed.

Outcome

  • A calibration JSON khp20s30_factory.json exists in the Derkachi input directory, parses against the project's CameraCalibrationArtifact schema, and documents the acquisition method as factory_sheet.
  • camera_info.md is updated to reference the new calibration + the residual budget + the deferral handle (AZ-XXX_checkerboard_refinement).
  • AZ-699 (T3) uses this calibration as its --camera-calibration input.

Scope

Included

  • Source manufacturer factory data for the Topotek KHP20S30 (sensor: 1/2.8" CMOS, 2.13 MP, 1920×1080; lens focal length, FOV, pixel pitch).
  • Compute K = [[fx, 0, cx], [0, fy, cy], [0, 0, 1]] from fx = fy = focal_length_mm × (image_width_px / sensor_width_mm).
  • Set distortion to [0, 0, 0, 0, 0] (factory-sheet approximation).
  • Set body_to_camera_se3 to identity-down (nadir; camera-z = aircraft-down).
  • Set acquisition_method = "factory_sheet".
  • Write _docs/00_problem/input_data/flight_derkachi/khp20s30_factory.json.
  • Update _docs/00_problem/input_data/flight_derkachi/camera_info.md.
  • New unit test under tests/unit/calibration/ asserting the JSON parses and matches the documented inputs.

Excluded

  • Physical checkerboard calibration (needs hardware).
  • PnP-from-tlog back-computation (deferred follow-up).
  • Updating adti26.json or other test fixtures.

Acceptance Criteria

AC-1: Calibration JSON parses Given the new khp20s30_factory.json When loaded by the project's calibration parser (same schema as adti26.json) Then it parses without error and all fields are populated

AC-2: Doc updated Given camera_info.md before When the calibration is committed Then camera_info.md says "factory-sheet approximation; per-unit checkerboard refinement deferred — see " and lists the residual budget

AC-3: Unit test snapshot Given the new JSON When the unit test runs Then it asserts fx == fy (square pixels), cx ≈ width/2, cy ≈ height/2, distortion all zero

AC-4: T3 consumes this calibration Given AZ-699's test_derkachi_real_tlog.py When it runs Then it loads khp20s30_factory.json as --camera-calibration (no longer the adti26.json placeholder)

Non-Functional Requirements

Compatibility

  • JSON schema MUST be identical to existing calibration fixtures (adti26.json) — no schema changes in this task.

Unit Tests

AC Ref What to Test Required Outcome
AC-1 JSON loads via existing parser Object populated
AC-3 Field values match factory inputs fx == fy, cx/cy at centre, zero distortion

Blackbox Tests

AC Ref Initial Data/Conditions What to Test Expected Behavior NFR References
AC-4 T3 test pointed at new JSON T3 launches without calibration parse error Test starts cleanly Compat

Constraints

  • MUST follow the calibration contract in _docs/02_document/contracts/shared_helpers/descriptor_normaliser.md (or wherever the camera-calibration schema lives).
  • MUST be a single committed JSON — no generator script with side effects.

Risks & Mitigation

Risk 1: Factory data unavailable at required precision

  • Risk: Topotek does not publish the exact focal length / sensor width to the precision needed.
  • Mitigation: Document the gap; ship with the best-available estimate; flag in camera_info.md so T3 surfaces the uncertainty in its failure message.

Risk 2: Residual error exceeds AC-3 budget

  • Risk: 13 % focal-length error may push horizontal error past 100 m at 1 km AGL.
  • Mitigation: That's the honest finding. T3 reports it. A follow-up task can pursue checkerboard refinement if needed.