Graduate-level aerospace systems engineering | AeroHack submission
A single, unified, constraint-based mission planning engine that plans and simulates:
- ✈ Aircraft missions — UAV/fixed-wing waypoint flight under wind, energy, maneuver, and geofence constraints
- 🛰 Spacecraft missions — 7-day CubeSat LEO observation and downlink scheduling under visibility, power, and pointing constraints
One Planner.solve() loop. Zero constraint violations. Fully reproducible.
# 1. Install dependencies
pip install numpy scipy matplotlib
# 2. Run everything with one command (from project root)
cd c:\xampp\htdocs\AeroPlanX
python run.py
# 3. Open the dashboard
# Start XAMPP, then visit: http://localhost/AeroPlanX/frontend/index.html| Requirement | Version | Purpose |
|---|---|---|
| Python | 3.8+ | Core planning engine |
| numpy | any | Numerical computation |
| scipy | any | (optional, reserved) |
| matplotlib | any | Plot generation |
| XAMPP / Apache + PHP | 7.4+ | Frontend dashboard server |
| MySQL | 5.7+ | Mission result storage (optional) |
AeroPlanX/
├── run.py ← Single command entry point
├── planner/
│ ├── core/
│ │ ├── state.py ← Unified MissionState abstraction
│ │ ├── action.py ← Action types (maneuver, observe, downlink, idle)
│ │ ├── constraints.py ← All hard constraints (explicit, audited)
│ │ ├── objective.py ← Scoring functions
│ │ └── planner.py ← UnifiedPlanner.solve() — shared solver loop
│ ├── aircraft/
│ │ ├── wind.py ← Dryden turbulence + spatial wind model
│ │ ├── model.py ← Fixed-wing UAV dynamics & energy model
│ │ └── mission.py ← Aircraft mission orchestrator
│ ├── spacecraft/
│ │ ├── orbit.py ← Two-body + J2 LEO propagator
│ │ ├── visibility.py ← Ground target & station visibility windows
│ │ └── mission.py ← 7-day spacecraft scheduler
│ └── validation/
│ ├── monte_carlo.py ← Monte-Carlo wind robustness (N=50 runs)
│ └── metrics.py ← Metrics export + constraint audit
├── backend/
│ ├── api.php ← REST API for mission data
│ └── db.php ← MySQL schema
├── frontend/
│ ├── index.html ← Dashboard (Overview/Aircraft/Spacecraft/Validation)
│ ├── style.css ← Aerospace dark theme
│ └── app.js ← Dashboard data loading
├── outputs/ ← Generated plots + metrics (gitignored)
└── docs/
└── report.md ← Technical report
- Aircraft Mission — Plans a 10-waypoint UAV survey mission with real wind physics, saves trajectory + energy plots to
/outputs/ - Spacecraft Mission — Plans a 7-day CubeSat scheduling mission, saves timeline, energy, ground track plots + schedule CSV
- Monte-Carlo Validation — Runs 50 independent aircraft missions with different wind seeds, compares planner vs greedy baseline, saves statistical plots
- Summary Export — Writes
/outputs/summary.json(consumed by the dashboard)
- True Unified Architecture: Not two scripts glued together, but a single mathematical core (
UnifiedPlanner) solving both aircraft and spacecraft missions. - Explicit, Auditable Constraints: Every safety rule is a distinct, testable Python class. Zero "black box" logic.
- Robust Under Uncertainty: Validated against 50 randomized wind fields with 100% success rate, outperforming standard baselines.
- Reproducible Engineering: Deterministic seeding, config-as-code, and one-command execution.
- Aerospace Systems Thinking: Derived from real physics (Dryden turbulence, J2 perturbations) rather than game-like approximations.
plan = UnifiedPlanner().solve(
initial_state=state,
candidate_generator=mission.generate_candidates, # domain-specific
constraints=ConstraintChecker([...]), # explicit, audited
objective=MinTimeEnergyObjective(), # domain-specific scoring
terminal_condition=lambda s: s.payload["wp_idx"] >= len(waypoints),
)The same UnifiedPlanner.solve() runs both aircraft and spacecraft missions.
Domain specifics are injected — the core algorithm never changes.
All constraints are in planner/core/constraints.py. Every check returns (bool, str) — no silent passes, no implicit logic. The planner maintains a full audit trail.
The current implementation is fully deterministic. AI integration can be added by injecting AI-suggested candidate actions through the candidate_generator — the constraint system will filter them deterministically.
After running python run.py, the /outputs/ directory contains:
| File | Content |
|---|---|
aircraft_trajectory_seed42.png |
UAV flight path with waypoints and geofence |
aircraft_energy_seed42.png |
Battery level over mission time |
spacecraft_timeline.png |
7-day Gantt chart of actions |
spacecraft_energy_science.png |
Battery + cumulative science value |
spacecraft_ground_track.png |
Orbit ground track (Day 1) |
monte_carlo_comparison.png |
Boxplot comparison: planner vs greedy |
monte_carlo_success_rate.png |
Success rate bar chart |
monte_carlo_results.json |
Full Monte-Carlo statistics |
summary.json |
Master summary (read by dashboard) |
aircraft_metrics.csv |
Aircraft performance metrics |
spacecraft_metrics.csv |
Spacecraft performance metrics |
With XAMPP running, visit: http://localhost/AeroPlanX/frontend/index.html
The dashboard automatically loads from /outputs/summary.json via the PHP API and auto-refreshes every 30 seconds.
# Check constraint violations (must be 0)
python -c "import json; d=json.load(open('outputs/summary.json')); print('Violations:', d['total_constraint_violations'])"
# Check Monte-Carlo success rate (must be 1.0)
python -c "import json; d=json.load(open('outputs/monte_carlo_results.json')); print('MC Rate:', d['success_rate'])"- Wind: Dryden turbulence (MIL-HDBK-1797) + sinusoidal spatial field
- Dynamics:
V_ground = V_airspeed + V_wind, coordinated turnω = g·tan(φ)/V - Energy:
E_rate = (P_avionics + P_cruise·pf²) / E_capacity
- Orbit: Two-body + J2 secular perturbation, Kepler equation (Newton-Raphson)
- Visibility: Elevation angle geometry in ECI frame → time windows
- Power: Normalised duty-cycle budget (≤40% per orbit)