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.
128 lines
4.4 KiB
128 lines
4.4 KiB
#!/usr/bin/env python3 |
|
""" |
|
Precalculate expected values for test_maneuver_planning.cpp refactoring. |
|
Computes velocities and energy after time-based and true anomaly-based |
|
maneuver triggers. |
|
""" |
|
|
|
import math |
|
import sys |
|
sys.path.insert(0, "/home/agent/dev/claudes_game") |
|
from scripts.sim_engine import * |
|
|
|
|
|
def main(): |
|
G_const = G |
|
earth_mass = 5.972e24 |
|
mu = G_const * earth_mass |
|
|
|
# Initial circular orbit at r = 6.771e6 m |
|
r0 = 6.771e6 |
|
v_circular = math.sqrt(mu / r0) |
|
|
|
print("// Initial circular orbit") |
|
print(f"// r = {r0} m") |
|
print(f"// v_circular = {v_circular:.15e} m/s") |
|
print() |
|
|
|
# Run the full simulation with the TOML config |
|
sim = Simulator("tests/test_maneuver_planning.toml", dt=60.0) |
|
|
|
# Get initial craft velocity |
|
craft = sim.get_craft("LEO_Satellite") |
|
v_initial = vmag(craft.local_vel) |
|
print(f"// Initial craft velocity from config: {v_initial:.15e} m/s") |
|
print() |
|
|
|
# Run to just before first burn (t=3600) |
|
steps_to_first_burn = int(3600.0 / 60.0) # 60 steps |
|
sim.run(steps_to_first_burn) |
|
|
|
craft = sim.get_craft("LEO_Satellite") |
|
v_before_burn1 = vmag(craft.local_vel) |
|
t_before = sim.time |
|
|
|
# Check if maneuver[0] executed |
|
man = sim.maneuvers[0] |
|
print("// First burn (time trigger at 3600.0 s)") |
|
print(f"// Time at step end: {t_before:.1f} s") |
|
print(f"// Executed: {man.executed}") |
|
print(f"// Executed time: {man.executed_time:.15e} s") |
|
print(f"// Velocity before burn: {v_before_burn1:.15e} m/s") |
|
print() |
|
|
|
# Continue a bit more to ensure burn fires |
|
sim.run(1) |
|
man = sim.maneuvers[0] |
|
craft = sim.get_craft("LEO_Satellite") |
|
v_after_burn1 = vmag(craft.local_vel) |
|
a_after_burn1 = craft.orbit.a |
|
e_after_burn1 = craft.orbit.e |
|
r_after_burn1 = vmag(craft.local_pos) |
|
|
|
print(f"// After stepping past burn:") |
|
print(f"// Executed: {man.executed}") |
|
print(f"// Executed time: {man.executed_time:.15e} s") |
|
print(f"// Velocity after burn: {v_after_burn1:.15e} m/s") |
|
print(f"// Semi-major axis: {a_after_burn1:.15e} m") |
|
print(f"// Eccentricity: {e_after_burn1:.15e}") |
|
print(f"// Radius: {r_after_burn1:.15e} m") |
|
print(f"// KE after first burn: {0.5 * 1000.0 * v_after_burn1 * v_after_burn1:.15e} J") |
|
print() |
|
|
|
# Continue until second burn fires (true anomaly 0.0) |
|
max_additional_steps = 2000 # should be enough |
|
second_burn_fired = False |
|
for step in range(max_additional_steps): |
|
sim.run(1) |
|
if sim.maneuvers[1].executed: |
|
second_burn_fired = True |
|
break |
|
|
|
craft = sim.get_craft("LEO_Satellite") |
|
v_after_burn2 = vmag(craft.local_vel) |
|
a_after_burn2 = craft.orbit.a |
|
e_after_burn2 = craft.orbit.e |
|
|
|
man2 = sim.maneuvers[1] |
|
print("// Second burn (true anomaly trigger at 0.0)") |
|
print(f"// Fired: {second_burn_fired}") |
|
print(f"// Executed time: {man2.executed_time:.15e} s") |
|
print(f"// Sim time: {sim.time:.1f} s") |
|
print(f"// Velocity after second burn: {v_after_burn2:.15e} m/s") |
|
print(f"// Semi-major axis: {a_after_burn2:.15e} m") |
|
print(f"// Eccentricity: {e_after_burn2:.15e}") |
|
print(f"// KE after second burn: {0.5 * 1000.0 * v_after_burn2 * v_after_burn2:.15e} J") |
|
print() |
|
|
|
# Also get the exact burn result for second burn |
|
br = man2.burn_result |
|
print(f"// Pre-burn state at second burn:") |
|
print(f"// pos = {br.position}") |
|
print(f"// vel = {br.velocity}") |
|
print(f"// true_anomaly = {br.true_anomaly:.15e} rad") |
|
print() |
|
|
|
# Run beyond well past to verify no extra executions |
|
sim.run(500) |
|
exec_count = sum(1 for m in sim.maneuvers if m.executed) |
|
print("// After extra simulation") |
|
print(f"// Total executed: {exec_count}") |
|
for i, m in enumerate(sim.maneuvers): |
|
print(f"// Maneuver[{i}] '{m.name}': executed={m.executed}, time={m.executed_time:.1f} s") |
|
print() |
|
|
|
print("// For WithinAbs assertions:") |
|
print(f"// v_initial := {v_circular:.15e}") |
|
print(f"// v_after_burn1 := {v_after_burn1:.15e}") |
|
print(f"// a_after_burn1 := {a_after_burn1:.15e}") |
|
print(f"// e_after_burn1 := {e_after_burn1:.15e}") |
|
print(f"// v_after_burn2 := {v_after_burn2:.15e}") |
|
print(f"// a_after_burn2 := {a_after_burn2:.15e}") |
|
print(f"// e_after_burn2 := {e_after_burn2:.15e}") |
|
print(f"// executed_time_1 := {man.executed_time:.15e}") |
|
print(f"// executed_time_2 := {man2.executed_time:.15e}") |
|
|
|
|
|
if __name__ == "__main__": |
|
main()
|
|
|