c172-flight-dynamics
A small world model of a Cessna 172 in flight. Given the last 4 aircraft states and stick commands, it predicts the state 0.1 s later; fed its own predictions, it flies the aircraft forward open-loop. Trained from scratch on flights simulated with JSBSim (c172x). flight.py in this repo generates the data, trains the model and doubles as the loader.
Research aid only. Not for flight operations. It learns one simulated aircraft, not a real one, and is not certified or validated for anything.
🚀 Usage
Fly a held-out simulated flight and compare 10 s of model rollout with JSBSim, with flight.py on the path:
import torch
from flight import load, rollout, simulate
model = load("jgalego/c172-flight-dynamics", device="cpu")
states, controls = (torch.from_numpy(a)[None] for a in simulate(seed=1_000_000))
h = model.config.history
predicted = rollout(model, states[:, :h], controls[:, : h - 1 + 100])
print(predicted[0, -1, 0].item(), states[0, h + 99, 0].item()) # altitude in ft: model, simulator
State: altitude (ft), roll and pitch (rad), sine and cosine of heading, body velocities u, v, w (ft/s) and body rates p, q, r (rad/s). Commands: aileron, elevator and rudder in [-1, 1], throttle in [0, 1], held for 0.1 s.
🏋️ Training
| Model | MLP, 3 hidden layers of 512, 562,187 parameters, predicts the scaled state change |
| Data | 1,000 JSBSim flights of 60 s at 10 Hz: random start altitude, airspeed and heading; a PD pilot chases random roll and pitch targets with noisy sticks and a drifting throttle |
| Steps | 20,000, batch size 1024, one-step MSE with input noise 0.02 |
| Optimizer | AdamW, one-cycle lr 0.001 |
| Hardware | NVIDIA A10G, 0.7 min |
📊 Results
Open-loop rollouts on 500 windows from flights whose seeds never appear in training. The model gets the true commands and nothing else; errors are RMS against JSBSim. Hold keeps the last known state, the trivial baseline.
| Horizon | Model | Altitude (ft) | Roll (°) | Pitch (°) | Heading (°) | Airspeed (kt) |
|---|---|---|---|---|---|---|
| 1s | model | 0.03 | 0.04 | 0.03 | 0.02 | 0.01 |
| 1s | hold | 5.79 | 9.83 | 2.62 | 2.52 | 1.01 |
| 5s | model | 0.30 | 0.09 | 0.08 | 0.06 | 0.04 |
| 5s | hold | 30.59 | 18.86 | 4.05 | 10.98 | 5.12 |
| 10s | model | 0.64 | 0.15 | 0.09 | 0.15 | 0.09 |
| 10s | hold | 54.77 | 20.05 | 4.49 | 20.56 | 8.45 |
⚠️ Limitations
- One simulated aircraft in calm air: no wind, turbulence, flaps or ground handling, and no deliberate stalls.
- Only the flight envelope the PD pilot visits: moderate bank and pitch, cruise speeds. Rollouts outside it are guesses.
- Errors grow with the horizon, as for any open-loop model.
- Downloads last month
- 3
Collection including jgalego/c172-flight-dynamics
Evaluation results
- altitude_ft RMSE at 1s on JSBSim Cessna 172, held-out flightsself-reported0.025
- roll_deg RMSE at 1s on JSBSim Cessna 172, held-out flightsself-reported0.037
- pitch_deg RMSE at 1s on JSBSim Cessna 172, held-out flightsself-reported0.032
- heading_deg RMSE at 1s on JSBSim Cessna 172, held-out flightsself-reported0.017
- airspeed_kt RMSE at 1s on JSBSim Cessna 172, held-out flightsself-reported0.005
- altitude_ft RMSE at 5s on JSBSim Cessna 172, held-out flightsself-reported0.303
- roll_deg RMSE at 5s on JSBSim Cessna 172, held-out flightsself-reported0.092
- pitch_deg RMSE at 5s on JSBSim Cessna 172, held-out flightsself-reported0.075