FAILURE MAP
← Case archive

FA-69686 / Orbital propagation / Open access

Cylindrical Earth shadow test: Sunward test assumes the sun is along +x · case 01

Satellites are shadowed on the day side when the sun is not on the x axis.

Verified by executionVariant 1 · 7 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The day-side test uses the sign of r_x instead of r.u.

VERIFIED REPAIR

Use the projection on the sun direction.

Unsuccessful approach: Using the unnormalized sun vector without the projection sign still misplaces the day side.

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=[c/sn for c in s]
    d=sum(a*b for a,b in zip(r,u))
    if r[0]>=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 [[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 [[-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 [[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 [[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 [[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 [[-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 [[-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 [[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 [[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 [[-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 [[-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 [[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 [[-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 [[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 [[-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')]]
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 fixtureActualExpectedOutcome
cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]sunlitumbraFailed
cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]sunlitsunlitPassed
cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]umbraumbraPassed
cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]sunlitsunlitPassed
cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]umbraumbraPassed
cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0]sunlitsunlitPassed
cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]sunlitumbraFailed

SHA-256 / f9cc5236a221eac5e691577ffeb93623d3113f2c43d415df25fd8edd87bd78ca

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/sn for c in s]
    d=sum(a*b for a,b in zip(r,u))
    if sum(a*b for a,b in zip(r,s))>0 and s[0]!=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 [[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 [[-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 [[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 [[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 [[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 [[-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 [[-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 [[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 [[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 [[-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 [[-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 [[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 [[-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 [[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 [[-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')]]
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 fixtureActualExpectedOutcome
cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]umbraumbraPassed
cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]umbrasunlitFailed
cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]umbraumbraPassed
cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]sunlitsunlitPassed
cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]umbraumbraPassed
cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0]sunlitsunlitPassed
cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]umbraumbraPassed

SHA-256 / be0a751e8891679b00c9ed03c514407418258f303a7d594ef6caf2d6279591d5

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 [[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 [[-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 [[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 [[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 [[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 [[-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 [[-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 [[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 [[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 [[-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 [[-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 [[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 [[-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 [[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 [[-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')]]
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 fixtureActualExpectedOutcome
cylindrical earth shadow test [[0.0, -8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]umbraumbraPassed
cylindrical earth shadow test [[0.0, 8000.0, 500.0], [0.0, 2.0, 0.0], 6378.0]sunlitsunlitPassed
cylindrical earth shadow test [[-7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]umbraumbraPassed
cylindrical earth shadow test [[7000.0, 100.0, 0.0], [1.0, 0.0, 0.0], 6378.0]sunlitsunlitPassed
cylindrical earth shadow test [[-7000.0, 6378.0, 0.0], [1.0, 0.0, 0.0], 6378.0]umbraumbraPassed
cylindrical earth shadow test [[-7000.0, 6400.0, 0.0], [1.0, 0.0, 0.0], 6378.0]sunlitsunlitPassed
cylindrical earth shadow test [[5000.0, 5000.0, 0.0], [-3.0, -4.0, 0.0], 6378.0]umbraumbraPassed

SHA-256 / a6de83efd55279c15f6284e764b37f8390d373ebff1ec904a42fc242f8927844

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.775750+00:00.

Case digest / 627145fcca04099533fb7571fc62e2a3e2d87b215b0db9071408144272546eab