#!/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()