Turn each locked moon at its orbit's rate and Iapetus's pole round its orbit, so they face their planets at every date the clock reaches

The IAU gives a locked moon's W the mean motion of whichever orbit its authors had, and JPL's table
has another. Near the present the difference is nothing; over the clock's AD 1 to 3000 it turned
Proteus's far side to Neptune at AD 1 (146 degrees), Mimas 52 degrees from Saturn and Miranda 23.
Iapetus was worse for another reason: its IAU pole is a straight line, 3.9 degrees a century in
right ascension, through its orbit normal's 3 439-year circle round the Laplace pole, which by AD 1
has run past the celestial pole (Dec 97.9), 11 degrees off the orbit, with the face 87 degrees
from Saturn. Mimas and Iapetus carry mission maps, so a wrong hemisphere was drawn facing Saturn.
The ETL's lock check sampled only 1950-2100, so none of it failed.

tools/etl/lib/locked-spin.ts, lockedToOrbit, called for every locked moon:
- W's rate becomes the orbit's own mean motion, its constant moved so W is unchanged on
  2025-01-01; the pole and every periodic term stay the IAU's. A W with a quadratic is left
  (Phobos's orbit already takes it; the Moon's is its tidal slowing, 0.75 degrees at AD 1). The
  kernel's rate must be within 1e-5 of the orbit's first (at most 3.4e-6, Iapetus).
- Iapetus (poleFollowsOrbit): the pole follows its orbit normal, as a moon in a Cassini state does,
  in the IAU's own form: sines of the node's angle and four harmonics on right ascension, cosines
  on declination, fitted to the normal's circle and pinned to the IAU pole at the present; W takes
  sines of the same angles, fitted to hold the face where it is today.

build.ts samples the lock over AD 1 to 3000 (8 114 dates, every 135 days) instead of 1950-2100, and
subPlanetLongitudeDeg moved to the lib, shared by both. Measured on the real catalogue: at most
5.36 degrees (Titan) but the Moon 7.62 (its eccentricity, and W's quadratic at AD 1: a new named
ceiling of 8), Mimas 8.94 (ceiling 11 -> 9.5) and Iapetus 15.95 (19 -> 16.5, 9.4 of it its row's
lag); Proteus's own ceiling of 9 is gone, at 2.66. Iapetus's axis stays within 0.74 degrees of its
orbit normal (11.06 before) and its pole is the IAU's at the present to 1e-4 degrees.

Live on :4301, the longitude facing the planet at AD 1 / 1000 / 2025 / 2999: Proteus 2.6 / 2.6 /
2.6 / 2.6 (was -146.5 / -72.9 / 2.6 / 74.5), Iapetus -15.9 / -15.4 / -15.3 / -9.3 (-87.0 / -50.9 /
-15.3 / 22.8), Mimas 4.1 / 6.8 / 5.7 / 8.4 (48.6 / 29.3 / 5.7 / -13.0), Miranda -0.1 / 2.2 / 0.0 /
1.4 (-23.4 / -9.6 / 0.0 / 12.6); the present is unchanged.

The renderer spec now takes the rotational elements from bodies.json too, so no hand copy is left,
and a new test turns Proteus, Miranda, Mimas and Iapetus to their planets at AD 1 and AD 3000.
Guarded mutants, each run through the solar ETL and then the full suite on what it wrote:
lockedToOrbit bypassed (validator: Mimas 52.30, ceiling 9.5; the new test fails), Iapetus on the
IAU's straight pole (98.48), and its pole round the orbit without W's terms (73.13); each fails the
new test and only it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-30 15:58:04 +02:00
co-authored by Claude Opus 5.5
parent 09eaf9532f
commit 3b4fd1af6c
6 changed files with 312 additions and 107 deletions
+91 -44
View File
@@ -809,8 +809,8 @@
0
],
"primeMeridianDeg": [
79.39932954,
285.16188899,
79.49055322521608,
285.161879,
0
],
"terms": [
@@ -906,8 +906,8 @@
0
],
"primeMeridianDeg": [
200.39,
203.4889538,
200.34890824984421,
203.4889583,
0
],
"terms": [
@@ -971,8 +971,8 @@
0
],
"primeMeridianDeg": [
36.022,
101.3747235,
36.015607949990184,
101.3747242,
0
],
"terms": [
@@ -1045,8 +1045,8 @@
0
],
"primeMeridianDeg": [
44.064,
50.3176081,
44.07221835003116,
50.3176072,
0
],
"terms": [
@@ -1119,8 +1119,8 @@
0
],
"primeMeridianDeg": [
259.51,
21.5710715,
259.498129049991,
21.5710728,
0
],
"terms": [
@@ -1199,8 +1199,8 @@
0
],
"primeMeridianDeg": [
333.46,
381.994555,
334.00971630006546,
381.9944948,
0
],
"terms": [
@@ -1264,8 +1264,8 @@
0
],
"primeMeridianDeg": [
6.32,
262.7318996,
6.336436700062315,
262.7318978,
0
]
}
@@ -1315,8 +1315,8 @@
0
],
"primeMeridianDeg": [
8.95,
190.6979085,
8.928084400003424,
190.6979109,
0
],
"terms": [
@@ -1380,8 +1380,8 @@
0
],
"primeMeridianDeg": [
357.6,
131.5349316,
357.60821835003117,
131.5349307,
0
]
}
@@ -1425,8 +1425,8 @@
0
],
"primeMeridianDeg": [
235.16,
79.6900478,
235.1773498500081,
79.6900459,
0
],
"terms": [
@@ -1481,8 +1481,8 @@
0
],
"primeMeridianDeg": [
186.5855,
22.5769768,
186.5964577999983,
22.5769756,
0
]
}
@@ -1544,19 +1544,66 @@
"rotationPeriodHours": 1903.9469348834284,
"rotationalElements": {
"poleRaDeg": [
318.16,
-3.949,
283.4205056238858,
0,
0
],
"poleDecDeg": [
75.03,
-1.143,
77.15116551386498,
0,
0
],
"primeMeridianDeg": [
355.2,
4.5379572,
388.27970766227594,
4.5379416,
0
],
"terms": [
{
"angleDeg": [
261.10499999998126,
-10.46898128087986
],
"ra": -42.60490881707297,
"dec": 7.692796952777751,
"pm": 41.78612687698857
},
{
"angleDeg": [
522.2099999999625,
-20.93796256175972
],
"ra": -15.535995393995726,
"dec": 1.2845933786338362,
"pm": 15.53892376069157
},
{
"angleDeg": [
783.3149999999438,
-31.406943842639578
],
"ra": -7.628387941010053,
"dec": 0.45238994454766307,
"pm": 7.62837456853055
},
{
"angleDeg": [
1044.419999999925,
-41.87592512351944
],
"ra": -4.2134447101107595,
"dec": 0.20197385694504744,
"pm": 4.213441809239813
},
{
"angleDeg": [
1305.5249999999064,
-52.344906404399296
],
"ra": -2.482395388436937,
"dec": 0.10190190070186696,
"pm": 2.4609277085117798
}
]
}
},
@@ -1644,8 +1691,8 @@
0
],
"primeMeridianDeg": [
30.7,
-254.6906892,
30.41144460000184,
-254.6906576,
0
],
"terms": [
@@ -1727,8 +1774,8 @@
0
],
"primeMeridianDeg": [
156.22,
-142.8356681,
156.12685870007942,
-142.8356579,
0
],
"terms": [
@@ -1792,8 +1839,8 @@
0
],
"primeMeridianDeg": [
108.05,
-86.8688923,
108.00982140004953,
-86.8688879,
0
],
"terms": [
@@ -1857,8 +1904,8 @@
0
],
"primeMeridianDeg": [
77.74,
-41.3514316,
77.67607950003162,
-41.3514246,
0
],
"terms": [
@@ -1913,8 +1960,8 @@
0
],
"primeMeridianDeg": [
6.77,
-26.7394932,
6.729821400017093,
-26.7394888,
0
],
"terms": [
@@ -1969,8 +2016,8 @@
0
],
"primeMeridianDeg": [
296.53,
-61.2572637,
296.5309131499458,
-61.2572638,
0
],
"terms": [
@@ -2124,8 +2171,8 @@
0
],
"primeMeridianDeg": [
93.38,
320.7654228,
91.53817645008237,
320.7656245,
0
],
"terms": [
@@ -2190,8 +2237,8 @@
0
],
"primeMeridianDeg": [
122.695,
56.3625225,
122.70869724996541,
56.362521,
0
]
}