Skip to content

Collapse two-axis IDR into a single dual-axis instance#429

Open
brickbots wants to merge 2 commits into
mainfrom
refactor/pointing-estimate-dataclasses
Open

Collapse two-axis IDR into a single dual-axis instance#429
brickbots wants to merge 2 commits into
mainfrom
refactor/pointing-estimate-dataclasses

Conversation

@brickbots
Copy link
Copy Markdown
Owner

Summary

  • ImuDeadReckoning now handles both camera and aligned axes in one instance. solve() takes (camera, aligned, q_x2imu) and captures q_cam2aligned alongside q_eq2x; predict() composes the camera prediction with q_cam2aligned and returns both as a (camera, aligned) tuple. reset() clears both quaternions.
  • integrator.py drops the idr_camera / idr_aligned pair for a single idr. Both call sites (_apply_successful_solve, _advance_with_imu) collapse to one IDR call.
  • The IDR remains a pure math primitive: RaDecRoll in, RaDecRoll out. No import from PiFinder.types.positioning.
  • Equivalence tests parametrize over (screen_direction, alignment_offset ∈ {identity, real_offset}) and assert both predicted.camera == legacy.get_cam_radec() and predicted.aligned == legacy.get_scope_radec(). imu_dead_reckoning_legacy.py stays in the tree until the user is comfortable removing it in a follow-up.

Builds on #428 (the prior solved dict → PointingEstimate migration on the same branch).

Test plan

  • nox -s lint type_hints smoke_tests unit_tests — all green (213 unit tests pass).
  • Run on hardware: confirm dead-reckoning continues across failed solves and the aligned-axis offset is preserved under IMU motion.
  • Run alignment flow: confirm the new IDR picks up the alignment offset on the next solve and pointing.aligned.estimate reflects it.

🤖 Generated with Claude Code

brickbots and others added 2 commits May 22, 2026 21:15
End-to-end adoption of the dataclasses in PiFinder/types/positioning.py:

- Solver builds a fresh PointingEstimate per attempt and pushes to
  solver_queue. Alignment queue carries AlignOnRaDec / AlignCancel /
  ReloadSqmCalibration commands and AlignedResult responses, dispatched
  via isinstance().
- Integrator owns the long-lived PointingEstimate. solve cells survive
  failed plate-solves so IMU dead-reckoning keeps producing aligned
  estimates.
- shared_state.solution() / set_solution() carry PointingEstimate;
  default to an empty PointingEstimate() so consumers can always call
  .has_pointing() without a None check.
- All ~15 consumers (UI, server, pos_server, nearby, etc.) read via the
  PointingEstimate access shape (pointing.aligned.estimate.RA, etc.).
- solve_pixel -> target_pixel rename: code, default_config.json,
  shared_state.target_pixel() / set_target_pixel(), Config key. No
  user-config migration logic; users re-align to write the new key.
- Delete solver_main.py (dead code), get_initialized_solved_dict(),
  to_legacy_dict() / from_legacy_dict() bridge methods, and the
  "PROPOSAL ONLY" framing in types/positioning.py.
- Add matched_centroids / matched_stars fields to PointingEstimate so
  the SQM calibration UI can replay SQM calculations from cached
  published solutions.
- Pull the simplified ImuDeadReckoning (and legacy companion + tests)
  from idr_tests so the integrator's IDR call surface matches.
- 21 new unit tests in test_pointing_estimate.py covering dataclass
  basics, solver builders, integrator merge semantics, failed-solve
  anchor preservation, alignment dispatch, picklability, deep-copy
  isolation.
- CONTEXT.md cleaned of stale migration notes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ImuDeadReckoning now handles both camera and aligned axes in one
instance. solve() takes (camera, aligned, q_x2imu) and captures
q_cam2aligned alongside q_eq2x; predict() composes the camera
prediction with q_cam2aligned and returns both as a tuple.

The integrator drops the idr_camera/idr_aligned pair for a single
idr. The IDR remains a math primitive (RaDecRoll in, tuple of
RaDecRoll out) and does not import from PiFinder.types.positioning.

Equivalence tests now parametrize over (screen_direction,
alignment_offset) and check both predicted.camera == legacy.cam and
predicted.aligned == legacy.scope for identity and real-offset cases.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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