@ -18,12 +18,17 @@ static double hohmann_transfer_time(double r1, double r2, double mass) {
// Calculate required angular separation at first burn
// For Hohmann transfer: target should be at specific angle when chaser burns
// Returns: required angular separation in radians [0, 2π)
// Returns: required angular separation (chaser - target) in radians
// Negative value means chaser should be behind target, positive means ahead
static double required_separation ( double r1 , double r2 , double mass ) {
double transfer_time = hohmann_transfer_time ( r1 , r2 , mass ) ;
double n2 = calc_mean_motion ( r2 , mass ) ;
double target_angle = n2 * transfer_time ;
return M_PI - target_angle ;
// Chaser travels π radians in transfer orbit, target travels target_angle
// For rendezvous: chaser_pos + π = target_pos + target_angle
// Therefore: chaser_pos - target_pos = target_angle - π
// Negative value means chaser should be behind target
return target_angle - M_PI ;
}
@ -66,17 +71,17 @@ double calculate_wait_time_for_hohmann(
double n2 = calc_mean_motion ( target_orbit_radius , central_mass ) ;
double rel_angular_vel = n1 - n2 ;
// Normalize required separation to [0, 2*pi)
required_sep = normalize_angle_2pi ( required_sep ) ;
// Normalize current separation to [-pi, pi]
// Positive = chaser ahead of target, negative = chaser behind target
double current_sep = normalize_angle_pi ( angular_separation ) ;
// Normalize current separation to [0, 2*pi)
double sep = normalize_angle_2pi ( angular_separation ) ;
// Normalize required separation to [-pi, pi]
required_sep = normalize_angle_pi ( required_sep ) ;
// How much more angle needs to close
double angle_to_close = required_sep - sep ;
// Normalize to [-pi, pi] for shortest path
angle_to_close = normalize_angle_pi ( angle_to_close ) ;
// Angle to close: difference between required and current separation
// If current_sep > required_sep, chaser is too far ahead (negative wait time)
// If current_sep < required_sep, chaser is too far behind (positive wait time)
double angle_to_close = required_sep - current_sep ;
// Wait time = angle_to_close / relative_angular_velocity
return angle_to_close / rel_angular_vel ;
@ -130,3 +135,72 @@ bool hohmann_transfer_complete(
double radius_diff = fabs ( current_radius - target_radius ) ;
return radius_diff < tolerance ;
}
// Validate parameters for Hohmann transfer
// Checks if the transfer parameters are valid before calculation.
// Returns: true if parameters are valid, false otherwise
bool validate_hohmann_transfer_parameters (
double initial_orbit_radius ,
double target_orbit_radius ,
double central_mass
) {
// Check for positive radii
if ( initial_orbit_radius < = 0.0 | | target_orbit_radius < = 0.0 ) {
return false ;
}
// Check for positive mass
if ( central_mass < = 0.0 ) {
return false ;
}
// Check for different orbits (no relative motion if equal)
if ( initial_orbit_radius = = target_orbit_radius ) {
return false ;
}
return true ;
}
// Calculate relative orbit period
// Computes the time for the chaser to complete one full relative orbit
// with respect to the target (time between consecutive phasing opportunities).
// Returns: relative orbit period in seconds
double calculate_relative_orbit_period (
double initial_orbit_radius ,
double target_orbit_radius ,
double central_mass
) {
double n1 = calc_mean_motion ( initial_orbit_radius , central_mass ) ;
double n2 = calc_mean_motion ( target_orbit_radius , central_mass ) ;
double rel_angular_vel = fabs ( n1 - n2 ) ;
return 2.0 * M_PI / rel_angular_vel ;
}
// Calculate next valid wait time for Hohmann transfer
// Like calculate_wait_time_for_hohmann(), but always returns a non-negative
// value by advancing to the next phasing opportunity if needed.
// Returns: non-negative wait time in seconds (time to wait before executing transfer)
double calculate_next_hohmann_wait_time (
double initial_orbit_radius ,
double target_orbit_radius ,
double angular_separation ,
double central_mass ,
double min_wait_time
) {
double wait_time = calculate_wait_time_for_hohmann (
initial_orbit_radius , target_orbit_radius , angular_separation , central_mass
) ;
double rel_period = calculate_relative_orbit_period (
initial_orbit_radius , target_orbit_radius , central_mass
) ;
// Add relative orbit periods until wait_time >= min_wait_time
while ( wait_time < min_wait_time ) {
wait_time + = rel_period ;
}
return wait_time ;
}