Draw four moons' nodes at JPL's current rates, which Horizons and the IAU's poles agree with

The archived satellite table the moons are read from gives older node
periods than JPL's current one for Miranda (17.727 years against URA182's
17.787), Ganymede (132.654 against 137.812), Callisto (338.82 against
577.264) and Titan (704.60 against 687.370), and 74ea1d6 turned the IAU's
poles after those older rates, taking them for the right ones. They were
not: fitted to Horizons' osculating elements on Uranus's equator over
1601-2399, Miranda's node turns 2023.97 degrees a century (rms 0.04),
against the current table's 2023.95, the IAU's U11 2024.22 and the row's
2030.80. That commit moved Miranda's axis from 0.38 to 2.36 degrees of
Horizons' orbit normal. Mimas's node, 0.986 years in both tables, now takes
the IAU's S3, 36505.5 degrees a century, 1.2 from a Horizons fit where
the row's is 4.5.

The ETL spec carries the node period (nodePeriodYears), and the periapsis
keeps the row's longitude rate: the row gives the longitude's rate (Callisto
68.7 degrees a century, the current table 67.2), so the argument takes up
the change. On the row's argument Callisto's periapsis moved 44 degrees by
2100 and it strayed 0.71 degrees from Horizons over 1950-2100.

Worst angle from Horizons' osculating orbit normal (ICRF), HEAD then now:
- Miranda, 1601-2399: drawn orbit 2.11 -> 0.12, axis 2.36 -> 0.34.
- Mimas, 1750-2249: orbit 0.33 -> 0.11, axis 0.65 -> 0.40.
- Ganymede, 1600-2199: orbit 0.17 -> 0.11, axis 0.13 -> 0.01.
- Callisto, 1600-2199: orbit 0.53 -> 0.20, axis 0.02 -> 0.03.
- Titan, 1750-2249: orbit 0.048 -> 0.052.
Against the 1950-2100 Horizons tracks the ETL checks: Callisto 0.19 -> 0.08,
Miranda 1.73 -> 1.62, Ganymede 0.30 -> 0.29, Mimas 7.43 -> 7.42, Titan 0.06.

lockedToOrbit now barely moves the IAU's node terms: Miranda's U11 to
-2023.95, Ganymede's J5 to 261.23 (262.1), Mimas's S3 not at all, and
Callisto's J6, 3.1 per cent from its new node rate, to 62.36 (64.3), which
takes Callisto's axis from 0.56 to 0.22 degrees of its drawn orbit.

With the drawn rates right, leaving every node term at the IAU's rate no
longer failed the ETL (Mimas used to), nor did a 1 per cent tolerance, the
node's angle without its harmonics, or the older node periods. The axis
ceiling is now 0.25 degrees for Europa (0.13 measured), Ganymede (0.16),
Callisto (0.22), Rhea (0.17), Miranda (0.23) and Triton (0.15), and
Callisto's track ceiling 0.15 (0.08). Guarded mutants, each through the
solar ETL on the real catalogue and then the suite on the bodies.json it
wrote:
- node terms left at the IAU's rates: ETL "europa's spin axis leans up to
  0.33"; suite fails only 'turns the poles of Europa, Ganymede, Callisto,
  Rhea, Miranda and Triton round with their drawn nodes'.
- tolerance 1 per cent: ETL, Callisto 0.33; the same test, alone.
- harmonics dropped: ETL, Triton 0.29 (the suite's three dates miss it).
- the archived node periods: ETL, Callisto's track 0.19; the suite fails
  that test and 'draws Miranda's orbit, and turns its axis, where Horizons
  has its orbit in 1601 and 2390' (orbit 2.02, axis 2.36 at 1601).
- the row's argument kept: ETL, Callisto's track 0.71.

The docs that called the IAU's rates the wrong ones are corrected
(lockedToOrbit, the axis ceiling in build.ts, whose Titan node now turns
in 687 years), and the README and BodyRecord doc no longer say every
locked moon's node terms are re-rated: only those within 5 per cent of a
multiple of the node's rate, never the Moon's or Phobos's, and not the
circles Ariel's, Umbriel's, Titania's and Oberon's poles go round on
(0.36 to 0.50 degrees off their orbits). The README also names the five
bodies the IAU's elements do not turn. Unit suite 866 passed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-30 19:22:57 +02:00
co-authored by Claude Opus 5.5
parent ac23496b37
commit 24c7be1bae
7 changed files with 182 additions and 68 deletions
+29 -8
View File
@@ -180,12 +180,12 @@ const MOON_OFFSET_CEILINGS_DEG: Record<string, number> = { hyperion: 10, iapetus
* - Iapetus, 10.34: the row sits 9.4 degrees behind Horizons at its own epoch, 2000 Jan 1.5, and
* keeps that offset; its plane agrees with Horizons' to 0.07 degrees and its period to 0.001 per
* cent, so the fault is in the row's longitude, which this has no second source to correct.
* - Mimas, 7.43: its orbit carries the 44-degree libration of its resonance with Tethys (see
* - Mimas, 7.42: its orbit carries the 44-degree libration of its resonance with Tethys (see
* `orbitFromW` in `fetchSolarSystem.ts`), but not the rest of what Horizons integrates.
* - Ceres, 7.12 (1953): the SBDB's elements are osculating, exact at 2026 Jun 9 and drifting
* either side; 1.9 by 2050, 5.3 by 2100, and 39 at 1600 on Horizons' own figures.
*
* And three are held tighter than the rest, each where one reading of its row is all that keeps it
* And four are held tighter than the rest, each where one reading of its row is all that keeps it
* close, and without it the card would quietly restate itself under the general ceiling:
*
* - Tethys, 0.28, which takes the other half of that libration, 2.23 degrees, from its W. Without
@@ -193,9 +193,12 @@ const MOON_OFFSET_CEILINGS_DEG: Record<string, number> = { hyperion: 10, iapetus
* - Io, 0.07, and Europa, 0.23, whose periapses turn backwards, held by the Laplace resonance at
* 2n(Europa) - n(Io), -0.7395 degrees a day (`apsidesRegress`). Read as advancing, Io strays 0.96
* and Europa 2.24, and their cards said "within 1.0" and "within 2.3".
* - Callisto, 0.08, whose node turns at JPL's current rate and its periapsis's longitude at the
* row's (`nodePeriodYears`). On the row's argument its periapsis moves 44 degrees by 2100 and it
* strays 0.71; on the row's node, 0.19.
*/
const MAX_TRACK_OFFSET_DEG = 3;
const TRACK_OFFSET_CEILINGS_DEG: Record<string, number> = { hyperion: 23, nereid: 12, iapetus: 11, mimas: 8, ceres: 8, tethys: 0.5, io: 0.2, europa: 0.5 };
const TRACK_OFFSET_CEILINGS_DEG: Record<string, number> = { hyperion: 23, nereid: 12, iapetus: 11, mimas: 8, ceres: 8, tethys: 0.5, io: 0.2, europa: 0.5, callisto: 0.15 };
/**
* The bodies the IAU WGCCRE 2015 report gives no rotational elements for: Hyperion tumbles, and
@@ -273,18 +276,36 @@ const SUB_PLANET_CEILINGS_DEG: Record<string, number> = { moon: 8, mimas: 9.5, i
* How far a locked moon's spin axis may lean from the normal of the orbit it is drawn going round,
* over the same dates. A locked moon sits in a Cassini state, its axis on its orbit normal as the
* node carries both round the Laplace pole, and the IAU's pole goes round on a term of the node's
* angle; at the rate the IAU's source had for it and not the drawn orbit's, Miranda's axis was 7.89
* degrees off at AD 9 and Mimas's 2.63, and an Iapetus pole left on the Laplace pole is 8.30 off at
* every date (see `lockedToOrbit`).
* angle; at the rate the IAU's source had for it and not the drawn orbit's, Rhea's axis is 0.77
* degrees off by AD 1 and Triton's 0.51, and an Iapetus pole left on the Laplace pole is 8.30 off
* at every date (see `lockedToOrbit`).
*
* Measured on this catalogue: at most 0.97 degrees (Tethys, whose IAU pole sits 0.69 from its orbit
* normal today; Titan 0.94, whose pole the IAU holds still while its node turns in 705 years) but
* normal today; Titan 0.94, whose pole the IAU holds still while its node turns in 687 years) but
* for four. The Moon 6.98, its real 6.7-degree tilt to its orbit. Phobos 1.81 and Deimos 1.74, and
* Proteus 1.09: their IAU poles nod with Mars's and Neptune's precessing poles, the Laplace poles
* their orbits are drawn round are fixed.
*
* And six are held tighter, each where its node terms turned at the node's rate, or its node at
* JPL's current rate, are what keep it close: Europa 0.13, Ganymede 0.16, Callisto 0.22, Rhea 0.17,
* Miranda 0.23 and Triton 0.15. On the IAU's rates they are 0.33, 0.21, 0.33, 0.77, 0.59 and 0.51,
* on a tolerance of 1 per cent Callisto and Rhea are left there, on the node's angle alone and not
* its harmonics Triton is 0.29, and on the archived table's node periods Callisto is 0.56 and
* Miranda 0.42: all under the general ceiling.
*/
const MAX_AXIS_FROM_ORBIT_DEG = 1;
const AXIS_FROM_ORBIT_CEILINGS_DEG: Record<string, number> = { moon: 7.1, phobos: 2, deimos: 2, proteus: 1.2 };
const AXIS_FROM_ORBIT_CEILINGS_DEG: Record<string, number> = {
moon: 7.1,
phobos: 2,
deimos: 2,
proteus: 1.2,
europa: 0.25,
ganymede: 0.25,
callisto: 0.25,
rhea: 0.25,
miranda: 0.25,
triton: 0.25
};
/** The clock's window, AD 1 to 3000 (`CLOCK_WINDOW` in `time.store.ts`), as Julian dates. */
const CLOCK_START_JD = Date.parse('0001-01-01T00:00Z') / 86400000 + 2440587.5;
const CLOCK_END_JD = Date.parse('3000-01-01T00:00Z') / 86400000 + 2440587.5;