Skip to content

fix(meade): restore hemisphere conversion for DEC coordinates - #300

Open
ClutchplateDude wants to merge 1 commit into
developfrom
fix/meade-dec-hemisphere-conversion
Open

fix(meade): restore hemisphere conversion for DEC coordinates#300
ClutchplateDude wants to merge 1 commit into
developfrom
fix/meade-dec-hemisphere-conversion

Conversation

@ClutchplateDude

Copy link
Copy Markdown
Member

Summary

The Meade parser refactor (#291) dropped the hemisphere conversion between the mount's internal DEC axis coordinate and celestial declination at the Meade protocol boundary. This restores it for all DEC paths crossing that boundary.

Background: the firmware stores DEC as a mount-axis coordinate — 0 at the pole above the mount, ±180 at the opposite pole — not as celestial declination. Every conversion to/from the wire format must apply:

  • Northern hemisphere: celestial = 90° − |axis|
  • Southern hemisphere: celestial = |axis| − 90°

The old code did this inside Declination::formatString() (output) and Declination::ParseFromMeade() (input). The refactor replaced those call sites with raw component extraction, dropping the transform. ParseFromMeade was left with zero call sites.

Symptoms

Command Before this fix
:GD# / :Gd# (get DEC) Reported the raw axis coordinate. Northern mount at celestial +80° answered +10*00'00#; southern mounts flipped the sign; values outside ±90° were possible
:Sd# (set target DEC) Stored celestial DEC as an axis coordinate
:CM sync (DEC+RA) Same as :Sd#

Slews commanded from Meade clients landed at the complement of the intended DEC. LCD menu, OLED, and :GX# status were unaffected (they use Mount::DECString()), which made this easy to miss.

Changes

  • src/core/types/Declination.{hpp,cpp} — the transform now lives in pure, unit-testable statics: axisToCelestialSeconds(), celestialToAxisSeconds(), fromTotalSeconds(). Formulas are byte-for-byte the historical ones
  • src/core/types/DayTime.{hpp,cpp}splitSeconds(): signed seconds → (signed deg, unsigned min/sec)
  • src/Declination.{hpp,cpp} — app overlay gains getCelestialDegrees() / fromCelestialDegrees(); formatString() now delegates to the shared core conversion instead of its own inline copy
  • src/MeadeCommandProcessor.cppdecFrom() (:GD/:Gd) applies the hemisphere correction; new decFromWire() used by onSetTargetDec() (:Sd) and onSyncCoordinates() (:CM)

Verification

  • All 269 native unit tests pass, including 13 new ones pinning the full hemisphere relationship (poles, both equator crossings, sign-flip region, home-branch round-trips, clamping) — unit_tests/test_core/types/test_declination.cpp
  • pio run -e ramps builds clean with -Werror
  • clang-format 18 (CI version): no changes
  • pio run -e esp32 fails in this workspace, but identically on the clean tree (missing RA_RX_PIN/DEC_RX_PIN in local config) — pre-existing, unrelated

🤖 Generated with Claude Code

The Meade parser refactor (#291) dropped the conversion between the
mount's internal DEC axis coordinate (0 = pole above the mount) and
celestial declination. As a result :GD#/:Gd# reported the raw axis
coordinate and :Sd#/:CM stored wire DEC as an axis coordinate, so
clients saw wrong values (e.g. +10*00'00 for celestial +80) and slews
landed at the complement of the intended DEC.

Move the transform into pure, unit-testable core helpers
(Declination::axisToCelestialSeconds / celestialToAxisSeconds,
fromTotalSeconds, DayTime::splitSeconds), expose wire-format accessors
on the app-level Declination overlay (getCelestialDegrees /
fromCelestialDegrees), and route all three Meade boundary handlers
through them: decFrom() for :GD/:Gd, decFromWire() for :Sd and :CM.

Behavior matches the pre-refactor code exactly; LCD/OLED/status paths
were unaffected and are unchanged.

Co-Authored-By: Claude <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