Browse Source

Merge maneuver execution into single spacecraft propagation pass

Consolidate execute_pending_maneuvers() into update_spacecraft_physics()
so every spacecraft goes through exactly one propagation path.

Changes:
- Remove spacecraft_handled_this_frame[256] static array
- Remove reset_spacecraft_tracking() function
- Remove execute_pending_maneuvers() function
- Check maneuver triggers before propagation in update_spacecraft_physics
- Propagate to burn time, execute burn, propagate remainder (same order
  as old code)
- Remove execute_pending_maneuvers declaration from simulation.h

Benefits:
- Single propagation call per spacecraft per frame (was 2 paths)
- No static array with magic number
- Simpler call chain: no separate maneuver pass
- Enables sub-step interpolation for true-anomaly triggers
- Sets up foundation for interpolated time triggers

Adds TODO in update_spacecraft_physics about testing interpolated burns.

All 154 tests pass (240,445 assertions).
main
cinnaboot 3 months ago
parent
commit
22727bbe22
  1. 83
      src/simulation.cpp
  2. 1
      src/simulation.h

83
src/simulation.cpp

@ -8,15 +8,6 @@
#include <cstdio> #include <cstdio>
#include <cmath> #include <cmath>
// FIXME: I'm not a fan of this
static bool spacecraft_handled_this_frame[256];
static void reset_spacecraft_tracking(int max_craft) {
for (int i = 0; i < max_craft && i < 256; i++) {
spacecraft_handled_this_frame[i] = false;
}
}
// Create a new simulation // Create a new simulation
SimulationState* create_simulation(int max_bodies, int max_craft, int max_maneuvers, double time_step) { SimulationState* create_simulation(int max_bodies, int max_craft, int max_maneuvers, double time_step) {
SimulationState* sim = (SimulationState*)malloc(sizeof(SimulationState)); SimulationState* sim = (SimulationState*)malloc(sizeof(SimulationState));
@ -172,10 +163,8 @@ void update_soi(CelestialBody* body, CelestialBody* parent, double semi_major_ax
} }
void update_simulation(SimulationState* sim) { void update_simulation(SimulationState* sim) {
reset_spacecraft_tracking(sim->max_craft);
update_bodies_physics(sim); update_bodies_physics(sim);
compute_global_coordinates(sim); compute_global_coordinates(sim);
execute_pending_maneuvers(sim);
update_spacecraft_physics(sim); update_spacecraft_physics(sim);
compute_spacecraft_globals(sim); compute_spacecraft_globals(sim);
sim->time += sim->dt; sim->time += sim->dt;
@ -298,10 +287,6 @@ void update_spacecraft_physics(SimulationState* sim) {
continue; continue;
} }
if (spacecraft_handled_this_frame[i]) {
continue;
}
CelestialBody* parent = &sim->bodies[craft->parent_index]; CelestialBody* parent = &sim->bodies[craft->parent_index];
Vec3 expected_pos, expected_vel; Vec3 expected_pos, expected_vel;
@ -312,46 +297,46 @@ void update_spacecraft_physics(SimulationState* sim) {
craft->orbit = cartesian_to_orbital_elements(craft->local_position, craft->local_velocity, parent->mass); craft->orbit = cartesian_to_orbital_elements(craft->local_position, craft->local_velocity, parent->mass);
} }
craft->orbit = propagate_orbital_elements(craft->orbit, sim->dt, parent->mass); // Check if any pending maneuver fires this frame. If so, propagate
orbital_elements_to_cartesian(craft->orbit, parent->mass, &craft->local_position, &craft->local_velocity); // to the burn time, execute the burn, then propagate the remaining
} // timestep. This enables sub-step interpolation for true-anomaly
} // triggers and sets up future interpolated time triggers.
// TODO: Test interpolated burns for TRIGGER_TIME — currently only
void execute_pending_maneuvers(SimulationState* sim) { // TRIGGER_TRUE_ANOMALY provides sub-step timing via scheduled_dt.
for (int i = 0; i < sim->maneuver_count; i++) { // For time triggers, scheduled_dt is always 0, so the burn applies
Maneuver* maneuver = &sim->maneuvers[i]; // at sim->time (step boundary). Could compute dt_to_burn =
// trigger_value - (sim->time - sim->dt) for exact placement.
if (maneuver->executed) { bool maneuver_fired = false;
continue; double burn_dt = 0.0;
} Maneuver* fired_maneuver = NULL;
for (int j = 0; j < sim->maneuver_count; j++) {
if (maneuver->craft_index < 0 || maneuver->craft_index >= sim->craft_count) { Maneuver* maneuver = &sim->maneuvers[j];
continue; if (maneuver->executed) {
} continue;
}
Spacecraft* craft = &sim->spacecraft[maneuver->craft_index]; if (maneuver->craft_index != i) {
continue;
if (craft->parent_index < 0 || craft->parent_index >= sim->body_count) { }
continue; if (check_maneuver_trigger(maneuver, craft, sim)) {
burn_dt = maneuver->scheduled_dt;
fired_maneuver = maneuver;
maneuver_fired = true;
break;
}
} }
if (check_maneuver_trigger(maneuver, craft, sim)) { if (maneuver_fired) {
CelestialBody* parent = &sim->bodies[craft->parent_index]; craft->orbit = propagate_orbital_elements(craft->orbit, burn_dt, parent->mass);
double dt_to_burn = maneuver->scheduled_dt; orbital_elements_to_cartesian(craft->orbit, parent->mass, &craft->local_position, &craft->local_velocity);
if (dt_to_burn > 0.0) {
craft->orbit = propagate_orbital_elements(craft->orbit, dt_to_burn, parent->mass);
orbital_elements_to_cartesian(craft->orbit, parent->mass, &craft->local_position, &craft->local_velocity);
}
execute_maneuver(maneuver, craft, sim, sim->time + dt_to_burn); execute_maneuver(fired_maneuver, craft, sim, sim->time + burn_dt);
double remaining_dt = sim->dt - dt_to_burn; double remaining_dt = sim->dt - burn_dt;
craft->orbit = propagate_orbital_elements(craft->orbit, remaining_dt, parent->mass); craft->orbit = propagate_orbital_elements(craft->orbit, remaining_dt, parent->mass);
orbital_elements_to_cartesian(craft->orbit, parent->mass, &craft->local_position, &craft->local_velocity); orbital_elements_to_cartesian(craft->orbit, parent->mass, &craft->local_position, &craft->local_velocity);
} else {
spacecraft_handled_this_frame[maneuver->craft_index] = true; craft->orbit = propagate_orbital_elements(craft->orbit, sim->dt, parent->mass);
maneuver->scheduled_dt = 0.0; orbital_elements_to_cartesian(craft->orbit, parent->mass, &craft->local_position, &craft->local_velocity);
} }
} }
} }

1
src/simulation.h

@ -47,7 +47,6 @@ void compute_global_coordinates(SimulationState* sim);
// Simulation update helper functions // Simulation update helper functions
void update_bodies_physics(SimulationState* sim); void update_bodies_physics(SimulationState* sim);
void update_spacecraft_physics(SimulationState* sim); void update_spacecraft_physics(SimulationState* sim);
void execute_pending_maneuvers(SimulationState* sim);
void compute_spacecraft_globals(SimulationState* sim); void compute_spacecraft_globals(SimulationState* sim);
// Initialize orbital objects from orbital elements // Initialize orbital objects from orbital elements

Loading…
Cancel
Save