Browse Source

src: add Hohmann transfer helper functions

Add validate_hohmann_transfer_parameters(), calculate_relative_orbit_period(),
and calculate_next_hohmann_wait_time() for robust Hohmann transfer setup.
Update required_separation() and calculate_wait_time_for_hohmann() to use
[-pi, pi] normalization instead of [0, 2pi).
main
cinnaboot 3 months ago
parent
commit
4d6af716ce
  1. 96
      src/rendezvous_hohmann.cpp
  2. 39
      src/rendezvous_hohmann.h

96
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;
}

39
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

Loading…
Cancel
Save