vibe coding an orbital mechanics simulation to try out claude code
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.
 
 
 
 
 

189 lines
6.8 KiB

#!/usr/bin/env python3
"""
Precalculate expected values for test_maneuvers.cpp refactoring.
Uses sim_engine.py for physics propagation.
"""
import math
import sys
sys.path.insert(0, "/home/agent/dev/claudes_game")
from scripts.sim_engine import *
def main():
dt = 60.0
sim = Simulator("tests/test_maneuvers.toml", dt=dt)
craft = sim.spacecraft[0]
earth = sim.bodies[1]
# =========================================================================
# Test 1: Basic loading
# =========================================================================
print("// === Test 1: Spacecraft loading from config ===")
print(f"// craft_count = {len(sim.spacecraft)}")
print(f"// craft[0].name = \"{craft.name}\"")
print(f"// craft[0].parent_index = {craft.parent_index}")
print()
# =========================================================================
# Test 2: Prograde burn
# =========================================================================
sim2 = Simulator("tests/test_maneuvers.toml", dt=dt)
craft2 = sim2.spacecraft[0]
v0 = vmag(craft2.local_vel)
r0 = vmag(craft2.local_pos)
apply_impulsive_burn(craft2, BurnDirection.PROGRADE, 100.0, earth.mass)
v_after = vmag(craft2.local_vel)
# Simulate 3600s
steps = int(3600.0 / dt)
for _ in range(steps):
sim2._step()
sim2.time += sim2.dt
r_final = vmag(craft2.local_pos)
print("// === Test 2: Prograde burn ===")
print(f"// initial_velocity = {v0:.4f}")
print(f"// velocity_after_burn = {v_after:.4f}")
print(f"// delta_v = {v_after - v0:.4f}")
print(f"// initial_local_r = {r0:.4f}")
print(f"// final_local_r (t=3600s) = {r_final:.4f}")
print(f"// delta_r = {r_final - r0:.4f}")
print()
# =========================================================================
# Test 3: Retrograde burn
# =========================================================================
sim3 = Simulator("tests/test_maneuvers.toml", dt=dt)
craft3 = sim3.spacecraft[0]
v0r = vmag(craft3.local_vel)
r0r = vmag(craft3.local_pos)
apply_impulsive_burn(craft3, BurnDirection.RETROGRADE, 100.0, earth.mass)
v_after_r = vmag(craft3.local_vel)
for _ in range(steps):
sim3._step()
sim3.time += sim3.dt
r_final_r = vmag(craft3.local_pos)
print("// === Test 3: Retrograde burn ===")
print(f"// initial_velocity = {v0r:.4f}")
print(f"// velocity_after_burn = {v_after_r:.4f}")
print(f"// delta_v = {v_after_r - v0r:.4f}")
print(f"// initial_local_r = {r0r:.4f}")
print(f"// final_local_r (t=3600s) = {r_final_r:.4f}")
print(f"// delta_r = {r_final_r - r0r:.4f}")
print()
# =========================================================================
# Test 4: Normal burn
# =========================================================================
sim4 = Simulator("tests/test_maneuvers.toml", dt=dt)
craft4 = sim4.spacecraft[0]
z0 = craft4.local_pos[2]
apply_impulsive_burn(craft4, BurnDirection.NORMAL, 500.0, earth.mass)
for _ in range(steps):
sim4._step()
sim4.time += sim4.dt
z_final = craft4.local_pos[2]
z_change = abs(z_final - z0)
print("// === Test 4: Normal burn ===")
print(f"// initial_z = {z0:.4f}")
print(f"// final_z (t=3600s) = {z_final:.4f}")
print(f"// |z_change| = {z_change:.4f}")
print()
# =========================================================================
# Test 5: Custom burn
# =========================================================================
sim5 = Simulator("tests/test_maneuvers.toml", dt=dt)
craft5 = sim5.spacecraft[0]
iv5 = craft5.local_vel
apply_custom_burn(craft5, (10.0, 20.0, 30.0))
print("// === Test 5: Custom burn ===")
print(f"// initial_vel = ({iv5[0]:.4f}, {iv5[1]:.4f}, {iv5[2]:.4f})")
print(f"// final_vel = ({craft5.local_vel[0]:.4f}, {craft5.local_vel[1]:.4f}, {craft5.local_vel[2]:.4f})")
print(f"// dx = {craft5.local_vel[0] - iv5[0]:.4f}")
print(f"// dy = {craft5.local_vel[1] - iv5[1]:.4f}")
print(f"// dz = {craft5.local_vel[2] - iv5[2]:.4f}")
print()
# =========================================================================
# Test 6: Propagation stability (1 day)
# =========================================================================
sim6 = Simulator("tests/test_maneuvers.toml", dt=dt)
craft6 = sim6.spacecraft[0]
r0_6 = vmag(craft6.local_pos)
a0_6 = craft6.orbit.a
e0_6 = craft6.orbit.e
total_time = 86400.0
steps6 = int(total_time / dt)
for _ in range(steps6):
sim6._step()
sim6.time += sim6.dt
r_final_6 = vmag(craft6.local_pos)
a_final_6 = craft6.orbit.a
e_final_6 = craft6.orbit.e
drift_pct = abs(r_final_6 - r0_6) / r0_6 * 100.0
a_drift_pct = abs(a_final_6 - a0_6) / a0_6 * 100.0
print("// === Test 6: Propagation stability (1 day) ===")
print(f"// initial_local_r = {r0_6:.4f}")
print(f"// final_local_r (t=86400s) = {r_final_6:.4f}")
print(f"// distance_drift_pct = {drift_pct:.10f}%")
print(f"// initial_a = {a0_6:.4f}")
print(f"// final_a = {a_final_6:.4f}")
print(f"// a_drift_pct = {a_drift_pct:.10f}%")
print(f"// initial_e = {e0_6:.10f}")
print(f"// final_e = {e_final_6:.10f}")
print()
# =========================================================================
# Test 7: State vectors at orbital quarters
# =========================================================================
sim7 = Simulator("tests/test_maneuvers.toml", dt=dt)
craft7 = sim7.spacecraft[0]
orbit_radius = vmag(craft7.local_pos)
period = 2 * math.pi * math.sqrt(orbit_radius**3 / (G * earth.mass))
quarter_time = period / 4
steps_per_quarter = int(quarter_time / dt)
print("// === Test 7: State vectors at orbital quarters ===")
print(f"// orbit_radius = {orbit_radius:.4f}")
print(f"// orbital_period = {period:.4f} s ({period/3600:.4f} hours)")
print(f"// steps_per_quarter = {steps_per_quarter}")
for q in range(5):
angle = math.atan2(craft7.local_pos[1], craft7.local_pos[0])
if angle < 0:
angle += 2 * math.pi
r_q = vmag(craft7.local_pos)
v_q = vmag(craft7.local_vel)
print(f"// Q{q}: angle={math.degrees(angle):.4f}°, r={r_q:.4f}, v={v_q:.4f}")
if q < 4:
for _ in range(steps_per_quarter):
sim7._step()
sim7.time += sim7.dt
# Full rotation check
final_angle = math.atan2(craft7.local_pos[1], craft7.local_pos[0])
if final_angle < 0:
final_angle += 2 * math.pi
total_deg = math.degrees(final_angle)
print(f"// total_rotation = {total_deg:.4f}° = {final_angle:.6f} rad")
print(f"// angle_change_per_quarter = {(total_deg / 4):.4f}°")
print()
if __name__ == "__main__":
main()