FA-69691 / Orbital propagation / Open access
Cylindrical Earth shadow test: Sun direction is not normalized · case 01
Shadow geometry scales with the length of the sun vector.
ROOT CAUSE
The sun vector is used directly as the shadow axis.
VERIFIED REPAIR
Normalize the sun vector.
Unsuccessful approach: Dividing by the component sum is not a normalization.
Case contract
Input [r, s, R]: satellite position, sun direction (any length) and body radius. With u=s/|s| and d=r.u, the satellite is sunlit when d>=0; otherwise it is in umbra when the distance of r from the shadow axis |r-d u| is <= R. Return "umbra" or "sunlit".
Why this case matters
Orbit determination and mission planning chain many small conversions; one wrong branch or unit silently moves a spacecraft by kilometres.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
r,s,R=x
sn=math.sqrt(sum(c*c for c in s))
u=list(s)
d=sum(a*b for a,b in zip(r,u))
if d>=0: return 'sunlit'
perp=[a-d*b for a,b in zip(r,u)]
return 'umbra' if math.sqrt(sum(c*c for c in perp))<=R else 'sunlit'
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'sunlit')], [('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0]', [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit')], [('cylindrical earth shadow test [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0]', [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-42164.0, 0.0, 6000.0], [0.0, 0.0, 0.0001], 6378.0]', [[-42164.0, 0.0, 6000.0], [0.0, 0.0, 0.0001], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[3000.0, -7000.0, 0.0], [0.0, 0.5, 0.5], 6378.0]', [[3000.0, -7000.0, 0.0], [0.0, 0.5, 0.5], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra')], [('cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-42164.0, 0.0, 6000.0], [0.0, 0.0, 0.0001], 6378.0]', [[-42164.0, 0.0, 6000.0], [0.0, 0.0, 0.0001], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[3000.0, -7000.0, 0.0], [0.0, 0.5, 0.5], 6378.0]', [[3000.0, -7000.0, 0.0], [0.0, 0.5, 0.5], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit')], [('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'sunlit')]]
for label, args, expected in fixtures[N-1]:
check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0] | sunlit | umbra | Failed |
| cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0] | sunlit | umbra | Failed |
| cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0] | umbra | umbra | Passed |
| cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0] | sunlit | sunlit | Passed |
| cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0] | umbra | umbra | Passed |
| cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0] | sunlit | sunlit | Passed |
| cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0] | sunlit | sunlit | Passed |
SHA-256 / 8f83d52a6896909244621be59234dd30ed8fcd1f84d59300ba910f3481fb2654
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
r,s,R=x
sn=math.sqrt(sum(c*c for c in s))
u=[c/sum(s) for c in s] if sum(s) else list(s)
d=sum(a*b for a,b in zip(r,u))
if d>=0: return 'sunlit'
perp=[a-d*b for a,b in zip(r,u)]
return 'umbra' if math.sqrt(sum(c*c for c in perp))<=R else 'sunlit'
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'sunlit')], [('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0]', [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit')], [('cylindrical earth shadow test [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0]', [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-42164.0, 0.0, 6000.0], [0.0, 0.0, 0.0001], 6378.0]', [[-42164.0, 0.0, 6000.0], [0.0, 0.0, 0.0001], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[3000.0, -7000.0, 0.0], [0.0, 0.5, 0.5], 6378.0]', [[3000.0, -7000.0, 0.0], [0.0, 0.5, 0.5], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra')], [('cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-42164.0, 0.0, 6000.0], [0.0, 0.0, 0.0001], 6378.0]', [[-42164.0, 0.0, 6000.0], [0.0, 0.0, 0.0001], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[3000.0, -7000.0, 0.0], [0.0, 0.5, 0.5], 6378.0]', [[3000.0, -7000.0, 0.0], [0.0, 0.5, 0.5], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit')], [('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'sunlit')]]
for label, args, expected in fixtures[N-1]:
check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0] | umbra | umbra | Passed |
| cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0] | sunlit | umbra | Failed |
| cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0] | umbra | umbra | Passed |
| cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0] | sunlit | sunlit | Passed |
| cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0] | umbra | umbra | Passed |
| cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0] | sunlit | sunlit | Passed |
| cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0] | sunlit | sunlit | Passed |
SHA-256 / 9ad5609ff95d8b435493ec29ba08c3830b004c9d7d77a3db3643008dad2b295a
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
r,s,R=x
sn=math.sqrt(sum(c*c for c in s))
u=[c/sn for c in s]
d=sum(a*b for a,b in zip(r,u))
if d>=0: return 'sunlit'
perp=[a-d*b for a,b in zip(r,u)]
return 'umbra' if math.sqrt(sum(c*c for c in perp))<=R else 'sunlit'
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'sunlit')], [('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0]', [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit')], [('cylindrical earth shadow test [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0]', [[-5000.0, -5000.0, 1000.0], [3.0, 4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-42164.0, 0.0, 6000.0], [0.0, 0.0, 0.0001], 6378.0]', [[-42164.0, 0.0, 6000.0], [0.0, 0.0, 0.0001], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[3000.0, -7000.0, 0.0], [0.0, 0.5, 0.5], 6378.0]', [[3000.0, -7000.0, 0.0], [0.0, 0.5, 0.5], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra')], [('cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-100.0, 7000.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-42164.0, 0.0, 6000.0], [0.0, 0.0, 0.0001], 6378.0]', [[-42164.0, 0.0, 6000.0], [0.0, 0.0, 0.0001], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[3000.0, -7000.0, 0.0], [0.0, 0.5, 0.5], 6378.0]', [[3000.0, -7000.0, 0.0], [0.0, 0.5, 0.5], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit')], [('cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]', [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0]', [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0], 'sunlit'), ('cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'umbra'), ('cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]', [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0], 'sunlit')]]
for label, args, expected in fixtures[N-1]:
check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0] | umbra | umbra | Passed |
| cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0] | umbra | umbra | Passed |
| cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0] | umbra | umbra | Passed |
| cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0] | sunlit | sunlit | Passed |
| cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0] | umbra | umbra | Passed |
| cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0] | sunlit | sunlit | Passed |
| cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0] | sunlit | sunlit | Passed |
SHA-256 / 14ab844d2f98a82614abf669ca88c417eb37fab0224f92199a8bf447349e4af3
Verification & scope
A deterministic toy two-body model with stipulated constants and conventions; not flight dynamics software or a validated SGP4 implementation. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:48:13.831237+00:00.
Case digest / f4ca937019763daec207a6625e6adf1e1fbd23971897c258d4ef3417bbd99ec9