1 changed files with 0 additions and 239 deletions
@ -1,239 +0,0 @@
|
||||
# Maneuver Planning System - Implementation Plan |
||||
|
||||
## Overview |
||||
Add a maneuver planning system to SimulationState that allows pre-defining burns in config files, which will execute automatically when trigger conditions are met. |
||||
|
||||
--- |
||||
|
||||
## Design Decisions |
||||
|
||||
1. **Trigger Types:** Start with TIME and TRUE_ANOMALY only |
||||
2. **SOI Triggers:** Not implementing SOI_ENTRY/EXIT to start |
||||
3. **Custom Burns:** Not implementing custom burns to start (delta_v only) |
||||
4. **Error Handling:** Fail config load if spacecraft_name doesn't exist or if maneuver name is not unique |
||||
5. **Manual Triggers:** Deferred until later |
||||
|
||||
--- |
||||
|
||||
## 1. Data Structures |
||||
|
||||
### A. Maneuver Struct (`src/maneuver.h`) |
||||
|
||||
```cpp |
||||
enum TriggerType { |
||||
TRIGGER_TIME, // Execute at specific simulation time (seconds) |
||||
TRIGGER_TRUE_ANOMALY // Execute at specific orbital true anomaly (radians) |
||||
}; |
||||
|
||||
struct Maneuver { |
||||
char name[64]; // Maneuver identifier (must be unique) |
||||
int craft_index; // Index of spacecraft in sim->spacecraft |
||||
|
||||
// Burn parameters |
||||
BurnDirection direction; // Prograde, retrograde, normal, etc. |
||||
double delta_v; // Magnitude (for standard directions) |
||||
|
||||
// Trigger condition |
||||
TriggerType trigger_type; |
||||
double trigger_value; // Time (seconds) or true anomaly (radians) |
||||
|
||||
// Execution state |
||||
bool executed; // Has the burn been applied? |
||||
double executed_time; // Simulation time when executed |
||||
}; |
||||
``` |
||||
|
||||
### B. SimulationState Extension (`src/simulation.h`) |
||||
|
||||
```cpp |
||||
struct SimulationState { |
||||
CelestialBody* bodies; |
||||
int body_count; |
||||
int max_bodies; |
||||
|
||||
Spacecraft* spacecraft; |
||||
int craft_count; |
||||
int max_craft; |
||||
|
||||
Maneuver* maneuvers; // NEW: Planned maneuvers array |
||||
int maneuver_count; // NEW: Current number of maneuvers |
||||
int max_maneuvers; // NEW: Maximum capacity |
||||
|
||||
double time; |
||||
double dt; |
||||
char config_name[256]; |
||||
}; |
||||
``` |
||||
|
||||
--- |
||||
|
||||
## 2. Config File Format |
||||
|
||||
```toml |
||||
[[maneuvers]] |
||||
name = "orbit_raise_1" |
||||
spacecraft_name = "LEO_Satellite" |
||||
trigger_type = "time" |
||||
trigger_value = 3600.0 # 1 hour into simulation |
||||
direction = "prograde" |
||||
delta_v = 500.0 |
||||
|
||||
[[maneuvers]] |
||||
name = "plane_change" |
||||
spacecraft_name = "LEO_Satellite" |
||||
trigger_type = "true_anomaly" |
||||
trigger_value = 1.5708 # 90 degrees in radians |
||||
direction = "normal" |
||||
delta_v = 300.0 |
||||
``` |
||||
|
||||
**Config Fields:** |
||||
- `name` - Maneuver identifier (must be unique) |
||||
- `spacecraft_name` - Which spacecraft (string, resolved to index after loading) |
||||
- `trigger_type` - One of: "time", "true_anomaly" |
||||
- `trigger_value` - Numeric threshold (time in seconds, angle in radians) |
||||
- `direction` - One of: "prograde", "retrograde", "normal", "antinormal", "radial_in", "radial_out" |
||||
- `delta_v` - Magnitude for standard directions |
||||
|
||||
--- |
||||
|
||||
## 3. Implementation Plan |
||||
|
||||
### Phase 1: Data Structures |
||||
|
||||
1. **Update `src/maneuver.h`:** |
||||
- Add `TriggerType` enum (TIME, TRUE_ANOMALY) |
||||
- Add `Maneuver` struct with all required fields |
||||
|
||||
2. **Update `src/simulation.h`:** |
||||
- Add maneuver array fields to SimulationState |
||||
- Add `max_maneuvers` parameter to `create_simulation()` signature |
||||
|
||||
3. **Update `src/simulation.cpp`:** |
||||
- Allocate maneuver array in `create_simulation()` |
||||
- Free maneuver array in `destroy_simulation()` |
||||
- Initialize maneuver_count to 0 |
||||
|
||||
### Phase 2: Config Loading |
||||
|
||||
4. **Update `src/config_loader.h`:** |
||||
- No API changes - internal helper only |
||||
|
||||
5. **Update `src/config_loader.cpp`:** |
||||
- Add static helper `parse_toml_maneuver()` to parse individual maneuver entries |
||||
- Add `load_maneuvers_from_toml(SimulationState* sim, toml_result_t result)` helper |
||||
- Call from `load_system_config()` after loading spacecraft |
||||
- Resolve spacecraft_name → craft_index (requires spacecraft loaded first) |
||||
- Validate spacecraft_name exists (fail config if not found) |
||||
- Validate maneuver name uniqueness (fail config if duplicate) |
||||
|
||||
6. **String parsing in config_loader.cpp:** |
||||
- Parse trigger_type string → enum ("time" → TRIGGER_TIME, "true_anomaly" → TRIGGER_TRUE_ANOMALY) |
||||
- Parse direction string → BurnDirection enum |
||||
|
||||
### Phase 3: Execution Logic |
||||
|
||||
7. **Update `src/maneuver.h`:** |
||||
- Add function declarations for trigger checking and execution |
||||
|
||||
8. **Update `src/maneuver.cpp`:** |
||||
- Add `check_maneuver_trigger(Maneuver* maneuver, Spacecraft* craft, SimulationState* sim, bool* triggered)` |
||||
- Add `execute_maneuver(Maneuver* maneuver, Spacecraft* craft, double current_time)` |
||||
- Update executed flag and executed_time |
||||
|
||||
9. **Update `src/simulation.cpp`:** |
||||
- In `update_simulation()`, after spacecraft updates: |
||||
- Call `execute_pending_maneuvers(sim)` |
||||
- Add `execute_pending_maneuvers(SimulationState* sim)` function that: |
||||
- Loops through maneuvers |
||||
- Skips executed ones |
||||
- Checks trigger condition |
||||
- Executes if triggered |
||||
- Updates spacecraft velocity |
||||
- Marks as executed |
||||
|
||||
### Phase 4: Trigger Condition Logic |
||||
|
||||
10. **Implement trigger checks:** |
||||
- **TIME:** Check `sim->time >= trigger_value` |
||||
- **TRUE_ANOMALY:** Calculate current true anomaly from position/velocity, compare to threshold |
||||
- True anomaly ν = atan2(√(1-e²) * sin(E), cos(E)) where E is eccentric anomaly |
||||
- Or use direct position/velocity: ν = atan2(r·v, r·v⊥) (simpler) |
||||
- Use normalized position/velocity for stability |
||||
|
||||
11. **True anomaly calculation:** |
||||
- Position vector r = local_position |
||||
- Velocity vector v = local_velocity |
||||
- Angular momentum h = r × v |
||||
- Eccentricity vector e = (v × h) / μ - r/|r| |
||||
- True anomaly ν = acos( (e·r) / (|e|·|r|) ) |
||||
- Check sign using (r·h) to determine quadrant (prograde vs retrograde) |
||||
|
||||
### Phase 5: Testing |
||||
|
||||
12. **Create test config** (`tests/configs/maneuver_sequence.toml`): |
||||
- Time-based prograde burn to raise orbit |
||||
- True anomaly-based normal burn for plane change |
||||
- Verify spacecraft with specified name exists |
||||
|
||||
13. **Create test file** (`tests/test_maneuver_planning.cpp`): |
||||
- Test config loading with valid maneuvers |
||||
- Test config failure with duplicate maneuver names |
||||
- Test config failure with non-existent spacecraft |
||||
- Test time-based trigger execution |
||||
- Test true anomaly trigger execution |
||||
- Test maneuver executed state tracking |
||||
- Test maneuvers only fire once |
||||
|
||||
14. **Update all test files:** |
||||
- Update `create_simulation()` calls to include max_maneuvers parameter |
||||
|
||||
15. **Update main.cpp:** |
||||
- Update `create_simulation()` call with max_maneuvers parameter |
||||
|
||||
--- |
||||
|
||||
## 4. Key Design Decisions |
||||
|
||||
### A. Spacecraft Resolution |
||||
- Config uses `spacecraft_name` (string) |
||||
- After loading spacecraft array, resolve names to indices |
||||
- Validate that spacecraft exists before loading maneuvers |
||||
- Fail config load if spacecraft not found |
||||
|
||||
### B. Maneuver Name Uniqueness |
||||
- Maneuver names must be unique identifiers |
||||
- Check for duplicates while loading |
||||
- Fail config load if duplicate found |
||||
|
||||
### C. Trigger Types (Initial Implementation) |
||||
- **TIME:** Simple time-based trigger |
||||
- **TRUE_ANOMALY:** Orbital position-based trigger |
||||
- Deferred: SOI_ENTRY, SOI_EXIT, DISTANCE, MANUAL |
||||
|
||||
### D. Burn Directions (Initial Implementation) |
||||
- Standard directions: prograde, retrograde, normal, antinormal, radial_in, radial_out |
||||
- Deferred: custom burns with arbitrary delta_v vector |
||||
|
||||
### E. Execution Timing |
||||
- Check triggers **after** physics update in `update_simulation()` |
||||
- Apply burns to spacecraft `local_velocity` and `velocity` |
||||
- Mark as executed to prevent re-firing |
||||
- Record executed_time for debugging |
||||
|
||||
### F. True Anomaly Calculation |
||||
- Use eccentric anomaly approach for numerical stability |
||||
- Alternative: use position/velocity dot products directly |
||||
- Need to calculate orbital elements from current state |
||||
|
||||
--- |
||||
|
||||
## 5. Future Enhancements |
||||
|
||||
- Additional trigger types (distance, SOI entry/exit) |
||||
- Custom burns with arbitrary delta-v vectors |
||||
- Manual trigger API for interactive control |
||||
- Maneuver groups/chaining |
||||
- Delta-v budget tracking |
||||
- Burn timeline visualization |
||||
- Undo/revert maneuver capability |
||||
Loading…
Reference in new issue