diff --git a/src/rendezvous_hohmann.cpp b/src/rendezvous_hohmann.cpp index f8a6fea..e837032 100644 --- a/src/rendezvous_hohmann.cpp +++ b/src/rendezvous_hohmann.cpp @@ -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; +} diff --git a/src/rendezvous_hohmann.h b/src/rendezvous_hohmann.h index a48f594..55e70ed 100644 --- a/src/rendezvous_hohmann.h +++ b/src/rendezvous_hohmann.h @@ -61,16 +61,35 @@ bool verify_hohmann_transfer_orbit( double tolerance // Acceptable deviation in semi-major axis (meters) ); -// Check if Hohmann transfer is complete -// Determines if transfer time has elapsed and spacecraft is at target radius. -// Returns: true if transfer is complete, false otherwise -bool hohmann_transfer_complete( - double transfer_start_time, // When first burn was executed - double current_time, // Current simulation time - double transfer_time, // Expected transfer duration (from calculate_hohmann_transfer) - double target_radius, // Target orbit radius (meters) - double current_radius, // Current orbital radius (meters) - double tolerance // Radius tolerance for completion check (meters) +// 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, // Current circular orbit radius (meters) + double target_orbit_radius, // Target circular orbit radius (meters) + double central_mass // Mass of central body (kg) +); + +// 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, // Current circular orbit radius (meters) + double target_orbit_radius, // Target circular orbit radius (meters) + double central_mass // Mass of central body (kg) +); + +// 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, // Current circular orbit radius (meters) + double target_orbit_radius, // Target circular orbit radius (meters) + double angular_separation, // Current angle from chaser to target (radians) + double central_mass, // Mass of central body (kg) + double min_wait_time // Minimum acceptable wait time (seconds) ); #endif // RENDEZVOUS_HOHMANN_H