@ -27,6 +27,18 @@ static int find_spacecraft_by_name(SimulationState* sim, const char* name) {
return - 1 ;
}
// ── Test-only output helper ──────────────────────────────────────────────────
struct TestOutput {
char buf [ 32768 ] ;
int offset = 0 ;
void dump_state ( SimulationState * sim , const char * label ) {
int n = dump_simulation_state ( sim , label , buf + offset , sizeof ( buf ) - offset ) ;
if ( n > 0 ) offset + = n ;
}
} ;
TEST_CASE ( " Config loading for Hohmann transfer " , " [rendezvous_hohmann][config] " ) {
const double TIME_STEP = 30.0 ;
@ -502,55 +514,38 @@ SCENARIO("Hohmann transfer rendezvous with validation", "[rendezvous_hohmann][in
int arr_idx = add_maneuver_to_simulation ( sim , & arrival ) ;
REQUIRE ( arr_idx > = 0 ) ;
// Dump initial state
dump_simulation_state ( sim , " INITIAL STATE " ) ;
// Compute expected step count from analytical times
const double expected_duration = wait_time + hohmann . transfer_time ;
const int expected_steps = static_cast < int > ( expected_duration / sim - > dt ) ;
// Safety limit: 1 year — prevents infinite loops if calculation is wrong
const double SAFETY_LIMIT_SECONDS = 3600.0 * 24.0 * 365.0 ;
// Run simulation
double sim_time = 0.0 ;
const double DT = 1.0 ;
const int MAX_STEPS = 700000 ;
TestOutput out ;
bool transfer_complete = false ;
for ( int i = 0 ; i < MAX_STEPS ; i + + ) {
for ( int i = 0 ; i < expected_steps + 1000 ; i + + ) {
update_simulation ( sim ) ;
sim_time + = DT ;
// Dump state at key milestones
if ( i = = 0 ) {
dump_simulation_state ( sim , " T=0 (initial) " ) ;
}
if ( i = = int ( wait_time / DT ) ) {
dump_simulation_state ( sim , " JUST BEFORE DEPARTURE " ) ;
}
if ( i = = int ( wait_time / DT ) + 1 ) {
dump_simulation_state ( sim , " AFTER DEPARTURE BURN " ) ;
}
if ( i = = int ( arrival_time / DT ) ) {
dump_simulation_state ( sim , " JUST BEFORE ARRIVAL " ) ;
if ( sim - > time > SAFETY_LIMIT_SECONDS ) {
INFO ( " \n === SAFETY LIMIT REACHED === " ) ;
INFO ( " sim->time: " < < sim - > time < < " s (limit: " < < SAFETY_LIMIT_SECONDS < < " s) " ) ;
break ;
}
if ( i = = 0 ) out . dump_state ( sim , " T=0 (initial) " ) ;
if ( i = = static_cast < int > ( wait_time / sim - > dt ) ) out . dump_state ( sim , " JUST BEFORE DEPARTURE " ) ;
if ( i = = static_cast < int > ( wait_time / sim - > dt ) + 1 ) out . dump_state ( sim , " AFTER DEPARTURE BURN " ) ;
if ( i = = static_cast < int > ( arrival_time / sim - > dt ) ) out . dump_state ( sim , " JUST BEFORE ARRIVAL " ) ;
if ( sim - > maneuvers [ arr_idx ] . executed & & ! transfer_complete ) {
dump_simulation_state ( sim , " AFTER ARRIVAL BURN " ) ;
out . dump_state ( sim , " AFTER ARRIVAL BURN " ) ;
transfer_complete = true ;
break ;
}
}
INFO ( " \n === FINAL STATE === " ) ;
INFO ( " Final time: " < < sim_time < < " s " ) ;
INFO ( " Departure executed: " < < sim - > maneuvers [ dep_idx ] . executed ) ;
INFO ( " Arrival executed: " < < sim - > maneuvers [ arr_idx ] . executed ) ;
dump_simulation_state ( sim , " FINAL STATE " ) ;
// Verify maneuvers executed
REQUIRE ( sim - > maneuvers [ dep_idx ] . executed ) ;
REQUIRE ( sim - > maneuvers [ arr_idx ] . executed ) ;
// Verify rendezvous quality
double final_radius = vec3_magnitude ( chaser - > local_position ) ;
double radius_error = fabs ( final_radius - r2 ) ;
INFO ( " \n Verification: " ) ;
INFO ( " Radius error: " < < radius_error < < " m " ) ;
INFO ( " Chaser eccentricity: " < < chaser - > orbit . eccentricity ) ;
Vec3 chaser_vel = chaser - > local_velocity ;
Vec3 target_vel = target - > local_velocity ;
@ -560,10 +555,22 @@ SCENARIO("Hohmann transfer rendezvous with validation", "[rendezvous_hohmann][in
double separation_distance = vec3_magnitude ( separation ) ;
double relative_velocity = vec3_magnitude ( vec3_sub ( chaser_vel , target_vel ) ) ;
INFO ( " \n === FINAL STATE === " ) ;
INFO ( " Final time: " < < sim - > time < < " s " ) ;
INFO ( " Departure executed: " < < sim - > maneuvers [ dep_idx ] . executed ) ;
INFO ( " Arrival executed: " < < sim - > maneuvers [ arr_idx ] . executed ) ;
INFO ( " \n Verification: " ) ;
INFO ( " Radius error: " < < radius_error < < " m " ) ;
INFO ( " Chaser eccentricity: " < < chaser - > orbit . eccentricity ) ;
INFO ( " Chaser speed: " < < chaser_speed < < " m/s " ) ;
INFO ( " Target speed: " < < target_speed < < " m/s " ) ;
INFO ( " Separation: " < < separation_distance < < " m " ) ;
INFO ( " Relative velocity: " < < relative_velocity < < " m/s " ) ;
INFO ( out . buf ) ;
// Verify maneuvers executed
REQUIRE ( sim - > maneuvers [ dep_idx ] . executed ) ;
REQUIRE ( sim - > maneuvers [ arr_idx ] . executed ) ;
REQUIRE_THAT ( radius_error , WithinAbs ( 10.0 , 10.0 ) ) ;
REQUIRE_THAT ( chaser - > orbit . eccentricity , WithinAbs ( 0.0 , 0.001 ) ) ;