diff --git a/src/maneuver.cpp b/src/maneuver.cpp index a0679b4..f2aafa1 100644 --- a/src/maneuver.cpp +++ b/src/maneuver.cpp @@ -5,6 +5,7 @@ #include "orbital_mechanics.h" #include #include +#include Vec3 calculate_prograde_dir(Vec3 local_velocity) { return vec3_normalize(local_velocity); @@ -54,6 +55,27 @@ Vec3 get_burn_direction_vector(BurnDirection direction, Vec3 local_pos, Vec3 loc } } +const char* get_burn_direction_name(BurnDirection direction) { + switch (direction) { + case BURN_PROGRADE: + return "Prograde"; + case BURN_RETROGRADE: + return "Retrograde"; + case BURN_NORMAL: + return "Normal"; + case BURN_ANTINORMAL: + return "Antinormal"; + case BURN_RADIAL_IN: + return "Radial In"; + case BURN_RADIAL_OUT: + return "Radial Out"; + case BURN_CUSTOM: + return "Custom"; + default: + return "Unknown"; + } +} + void apply_impulsive_burn(Spacecraft* craft, BurnDirection direction, double delta_v) { Vec3 dir = get_burn_direction_vector(direction, craft->local_position, craft->local_velocity); @@ -67,6 +89,27 @@ void apply_custom_burn(Spacecraft* craft, Vec3 delta_v_local) { craft->global_velocity = vec3_add(craft->global_velocity, delta_v_local); } +OrbitalElements preview_burn_result(const Spacecraft* craft, BurnDirection direction, double delta_v, const SimulationState* sim) { + OrbitalElements current_elements = craft->orbit; + + if (craft->parent_index < 0 || craft->parent_index >= sim->body_count) { + return current_elements; + } + + CelestialBody* parent = &sim->bodies[craft->parent_index]; + double parent_mass = parent->mass; + + Vec3 pos; + Vec3 vel; + orbital_elements_to_cartesian(current_elements, parent_mass, &pos, &vel); + + Vec3 burn_dir = get_burn_direction_vector(direction, pos, vel); + Vec3 delta_v_vec = vec3_scale(burn_dir, delta_v); + Vec3 new_vel = vec3_add(vel, delta_v_vec); + + return cartesian_to_orbital_elements(pos, new_vel, parent_mass); +} + bool check_maneuver_trigger(Maneuver* maneuver, Spacecraft* craft, SimulationState* sim) { switch (maneuver->trigger_type) { case TRIGGER_TIME: @@ -163,6 +206,20 @@ bool check_maneuver_trigger(Maneuver* maneuver, Spacecraft* craft, SimulationSta } } +Maneuver create_maneuver(const char* name, int craft_index, BurnDirection direction, double delta_v, TriggerType trigger_type, double trigger_value) { + Maneuver m; + strncpy(m.name, name, 63); + m.name[63] = '\0'; + m.craft_index = craft_index; + m.direction = direction; + m.delta_v = delta_v; + m.trigger_type = trigger_type; + m.trigger_value = trigger_value; + m.executed = false; + m.executed_time = 0.0; + return m; +} + void execute_maneuver(Maneuver* maneuver, Spacecraft* craft, SimulationState* sim, double current_time) { apply_impulsive_burn(craft, maneuver->direction, maneuver->delta_v); @@ -174,3 +231,73 @@ void execute_maneuver(Maneuver* maneuver, Spacecraft* craft, SimulationState* si maneuver->executed = true; maneuver->executed_time = current_time; } + +int add_maneuver_to_simulation(SimulationState* sim, Maneuver* maneuver) { + if (sim->maneuver_count >= sim->max_maneuvers) { + return -1; + } + + for (int i = 0; i < sim->maneuver_count; i++) { + if (strcmp(sim->maneuvers[i].name, maneuver->name) == 0) { + return -1; + } + } + + if (maneuver->craft_index < 0 || maneuver->craft_index >= sim->craft_count) { + return -1; + } + + int new_idx = sim->maneuver_count; + sim->maneuvers[new_idx] = *maneuver; + sim->maneuvers[new_idx].executed = false; + sim->maneuvers[new_idx].executed_time = 0.0; + sim->maneuver_count++; + + return new_idx; +} + +bool remove_maneuver_by_index(SimulationState* sim, int index) { + if (index < 0 || index >= sim->maneuver_count) { + return false; + } + + int elements_to_move = sim->maneuver_count - index - 1; + if (elements_to_move > 0) { + memmove(&sim->maneuvers[index], &sim->maneuvers[index + 1], + elements_to_move * sizeof(Maneuver)); + } + + sim->maneuver_count--; + return true; +} + +HohmannTransfer calculate_hohmann_transfer(double r1, double r2, double central_mass) { + HohmannTransfer result; + double a_transfer = (r1 + r2) / 2.0; + double mu = G * central_mass; + + double v1 = sqrt(mu / r1); + double v_transfer1 = sqrt(mu * (2.0 / r1 - 1.0 / a_transfer)); + result.dv1 = v_transfer1 - v1; + + double v2 = sqrt(mu / r2); + double v_transfer2 = sqrt(mu * (2.0 / r2 - 1.0 / a_transfer)); + result.dv2 = v2 - v_transfer2; + + result.transfer_time = M_PI * sqrt(pow(a_transfer, 3.0) / mu); + result.true_anomaly_2 = M_PI; + + return result; +} + +bool validate_burn_parameters(const Spacecraft* craft, BurnDirection direction, double delta_v, double parent_mass) { + if (delta_v < 0) { + return false; + } + + if (delta_v > 50000.0) { + return false; + } + + return true; +} diff --git a/src/maneuver.h b/src/maneuver.h index 768a789..98938cf 100644 --- a/src/maneuver.h +++ b/src/maneuver.h @@ -32,6 +32,13 @@ struct Maneuver { double executed_time; }; +struct HohmannTransfer { + double dv1; + double dv2; + double transfer_time; + double true_anomaly_2; +}; + // Direction calculation functions (local frame) Vec3 calculate_prograde_dir(Vec3 local_velocity); Vec3 calculate_retrograde_dir(Vec3 local_velocity); @@ -45,8 +52,25 @@ Vec3 get_burn_direction_vector(BurnDirection direction, Vec3 local_pos, Vec3 loc void apply_impulsive_burn(Spacecraft* craft, BurnDirection direction, double delta_v); void apply_custom_burn(Spacecraft* craft, Vec3 delta_v_local); +// Burn preview functions +OrbitalElements preview_burn_result(const Spacecraft* craft, BurnDirection direction, double delta_v, const SimulationState* sim); + +// Burn optimization functions +HohmannTransfer calculate_hohmann_transfer(double r1, double r2, double central_mass); + +// Maneuver information functions +const char* get_burn_direction_name(BurnDirection direction); + +// Maneuver validation functions +bool validate_burn_parameters(const Spacecraft* craft, BurnDirection direction, double delta_v, double parent_mass); + // Maneuver execution functions bool check_maneuver_trigger(Maneuver* maneuver, Spacecraft* craft, SimulationState* sim); void execute_maneuver(Maneuver* maneuver, Spacecraft* craft, SimulationState* sim, double current_time); +// Maneuver management functions +Maneuver create_maneuver(const char* name, int craft_index, BurnDirection direction, double delta_v, TriggerType trigger_type, double trigger_value); +int add_maneuver_to_simulation(SimulationState* sim, Maneuver* maneuver); +bool remove_maneuver_by_index(SimulationState* sim, int index); + #endif