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