You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
188 lines
5.9 KiB
188 lines
5.9 KiB
#!/usr/bin/env python3 |
|
""" |
|
Precalculate expected values for test_extreme_timescales. |
|
All values in SI units (meters, m/s, seconds). |
|
Output local-frame values relative to parent body. |
|
""" |
|
import math |
|
|
|
G = 6.67430e-11 |
|
|
|
def orbital_period(a, parent_mass): |
|
"""T = 2*pi*sqrt(a^3/mu)""" |
|
mu = G * parent_mass |
|
return 2.0 * math.pi * math.sqrt(a**3 / mu) |
|
|
|
def orbital_energy(r, v, craft_mass, parent_mass): |
|
"""E = 0.5*m*v^2 - G*m1*m2/r""" |
|
mu = G * parent_mass |
|
ke = 0.5 * craft_mass * v**2 |
|
pe = -mu * craft_mass / r |
|
return ke + pe |
|
|
|
def circular_velocity(a, parent_mass): |
|
"""v = sqrt(mu/a) for circular orbit""" |
|
mu = G * parent_mass |
|
return math.sqrt(mu / a) |
|
|
|
# Body definitions (from TOML) |
|
earth_mass = 5.972e24 |
|
earth_radius = 6.371e6 |
|
sun_mass = 1.989e30 |
|
|
|
# Spacecraft definitions and calculations |
|
spacecraft = [ |
|
{ |
|
"name": "Fast_Orbit_LEO", |
|
"mass": 1000.0, |
|
"parent_index": 0, # Earth |
|
"parent_mass": earth_mass, |
|
"a": 6.771e6, |
|
"e": 0.0, |
|
"nu": 0.0, |
|
}, |
|
{ |
|
"name": "Mercury_Like_Orbit", |
|
"mass": 1000.0, |
|
"parent_index": 1, # Sun |
|
"parent_mass": sun_mass, |
|
"a": 5.79e10, |
|
"e": 0.2056, |
|
"nu": 0.0, |
|
}, |
|
{ |
|
"name": "Long_Period_Orbit", |
|
"mass": 1000.0, |
|
"parent_index": 1, # Sun |
|
"parent_mass": sun_mass, |
|
"a": 5.2e11, |
|
"e": 0.0489, |
|
"nu": 0.0, |
|
}, |
|
{ |
|
"name": "Low_Altitude_Orbit", |
|
"mass": 1000.0, |
|
"parent_index": 0, # Earth |
|
"parent_mass": earth_mass, |
|
"a": 6.471e6, |
|
"e": 0.0, |
|
"nu": 0.0, |
|
}, |
|
{ |
|
"name": "Super_Synchronous_Orbit", |
|
"mass": 1000.0, |
|
"parent_index": 0, # Earth |
|
"parent_mass": earth_mass, |
|
"a": 4.5e7, |
|
"e": 0.0, |
|
"nu": 0.0, |
|
}, |
|
{ |
|
"name": "Geosynchronous_Orbit", |
|
"mass": 1000.0, |
|
"parent_index": 0, # Earth |
|
"parent_mass": earth_mass, |
|
"a": 4.2164e7, |
|
"e": 0.0, |
|
"nu": 0.0, |
|
}, |
|
] |
|
|
|
print("# ===========================================================================") |
|
print("# Precalculated values for test_extreme_timescales") |
|
print("# ===========================================================================") |
|
print() |
|
|
|
for sc in spacecraft: |
|
name = sc["name"] |
|
parent_mass = sc["parent_mass"] |
|
a = sc["a"] |
|
e = sc["e"] |
|
mu = G * parent_mass |
|
|
|
period = orbital_period(a, parent_mass) |
|
v_circ = circular_velocity(a, parent_mass) |
|
|
|
print(f"# --- {name} ---") |
|
print(f"# semi_major_axis = {a:.10e} m") |
|
print(f"# eccentricity = {e}") |
|
print(f"# parent_mass = {parent_mass:.10e} kg") |
|
print(f"# orbital_period = {period:.6f} s") |
|
print(f"# orbital_period = {period / 60.0:.4f} minutes") |
|
print(f"# orbital_period = {period / 86400.0:.4f} days") |
|
print(f"# circular_velocity = {v_circ:.6f} m/s") |
|
|
|
if e == 0.0: |
|
r = a |
|
v = v_circ |
|
energy = orbital_energy(r, v, sc["mass"], parent_mass) |
|
print(f"# circular orbit: r = {r:.10e} m, v = {v:.6f} m/s") |
|
print(f"# total_energy = {energy:.6f} J") |
|
else: |
|
# For eccentric orbits, at nu=0 (periapsis): |
|
r_peri = a * (1 - e) |
|
v_peri = math.sqrt(mu * (2/r_peri - 1/a)) |
|
energy_peri = orbital_energy(r_peri, v_peri, sc["mass"], parent_mass) |
|
print(f"# eccentric orbit (nu=0=periapsis):") |
|
print(f"# r_peri = {r_peri:.10e} m") |
|
print(f"# v_peri = {v_peri:.6f} m/s") |
|
print(f"# total_energy = {energy_peri:.6f} J") |
|
|
|
print() |
|
|
|
# Geosynchronous period check |
|
geo_a = 4.2164e7 |
|
geo_period = orbital_period(geo_a, earth_mass) |
|
sidereal_day_hours = 23.93447 |
|
sidereal_day_seconds = sidereal_day_hours * 3600.0 |
|
geo_period_hours = geo_period / 3600.0 |
|
print("# --- Geosynchronous period check ---") |
|
print(f"# Geosynchronous period: {geo_period_hours:.6f} hours") |
|
print(f"# Sidereal day: {sidereal_day_hours} hours") |
|
print(f"# Period error: {abs(geo_period_hours - sidereal_day_hours):.6f} hours") |
|
print(f"# Period error: {abs(geo_period - sidereal_day_seconds):.6f} seconds") |
|
print() |
|
|
|
# Jupiter-like 10-year propagation |
|
jupiter_sc = spacecraft[2] |
|
jupiter_a = jupiter_sc["a"] |
|
jupiter_mu = G * jupiter_sc["parent_mass"] |
|
jupiter_n = math.sqrt(jupiter_mu / jupiter_a**3) # mean motion |
|
prop_time_10yr = 10.0 * 365.0 * 86400.0 |
|
expected_mean_anomaly = jupiter_n * prop_time_10yr |
|
expected_orbits = expected_mean_anomaly / (2.0 * math.pi) |
|
print("# --- Jupiter-like 10-year mean anomaly ---") |
|
print(f"# Mean motion n = {jupiter_n:.15e} rad/s") |
|
print(f"# Propagation time = {prop_time_10yr:.1f} s ({prop_time_10yr / (365.0*86400.0):.1f} years)") |
|
print(f"# Expected mean anomaly = {expected_mean_anomaly:.6f} rad") |
|
print(f"# Expected orbits = {expected_orbits:.6f}") |
|
print(f"# Expected true anomaly change = {expected_mean_anomaly % (2*math.pi):.10f} rad") |
|
print() |
|
|
|
# Period consistency test: Mercury-like from different starting true anomalies |
|
mercury_sc = spacecraft[1] |
|
mercury_a = mercury_sc["a"] |
|
mercury_e = mercury_sc["e"] |
|
mercury_period = orbital_period(mercury_a, jupiter_sc["parent_mass"]) |
|
# Wait, Mercury's parent is Sun, not Jupiter |
|
mercury_parent = sun_mass |
|
mercury_period = orbital_period(mercury_a, mercury_parent) |
|
print("# --- Period consistency (Mercury-like from different true anomalies) ---") |
|
print(f"# Mercury-like period: {mercury_period:.6f} s") |
|
for nu0_deg in [0, 90, 180, 270]: |
|
nu0 = math.radians(nu0_deg) |
|
print(f"# Starting nu = {nu0_deg} deg ({nu0:.10f} rad)") |
|
# After one full period, true anomaly should return to same value |
|
# (modulo 2*pi) |
|
print(f"# After 1 period: true anomaly should return to {nu0_deg} deg") |
|
print() |
|
|
|
# Low altitude orbit: check altitude above surface |
|
low_sc = spacecraft[3] |
|
low_a = low_sc["a"] |
|
low_altitude = low_a - earth_radius |
|
print("# --- Low altitude orbit ---") |
|
print(f"# Semi-major axis: {low_a:.10e} m") |
|
print(f"# Earth radius: {earth_radius:.10e} m") |
|
print(f"# Altitude above surface: {low_altitude:.10e} m ({low_altitude/1000.0:.1f} km)") |
|
print()
|
|
|