Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Flight Trajectory Prediction

4D flight trajectory prediction (lat, lon, altitude, time) using real-world ADS-B data from the OpenSky Network.
Temporal Transformer trained on 25,000+ real flights over the Paris terminal area (TMA).

Python PyTorch Docker Data


Motivation

Air traffic management systems need to predict where an aircraft will be in the next few minutes - for conflict detection, runway sequencing, and fuel optimization. This project builds a real ML system for that task, trained on actual ADS-B transponder data rather than a packaged benchmark dataset.


Results

The Transformer is compared against a kinematic baseline (constant velocity + heading + vertical rate - what a radar operator would extrapolate by hand):

Horizon Kinematic Baseline Transformer Gain
+1 min 0.80 km (median) 1.14 km -
+2 min 1.60 km 1.93 km -
+3 min 2.93 km 2.69 km −8%
+6 min 12.42 km 4.84 km −61%

Evaluated on 39,289 test windows from 3,835 held-out flights. Haversine error (great-circle distance), median.

ADE / FDE @ 5 min horizon (baseline): ADE = 5.38 km, FDE = 12.60 km

The model underperforms the baseline at short horizons (+1/+2 min), where constant-velocity kinematics is hard to beat. It gains a significant advantage at longer horizons (+6 min), where aircraft maneuvers, phase transitions, and traffic patterns diverge from naive extrapolation.


Dataset

  • Source: OpenSky Network REST API (ADS-B state vectors)
  • Area: Paris TMA bounding box - lat [48.0, 49.5], lon [1.0, 3.5]
  • Collection: 7 days (June 2026), polling every 30s, ~938k raw state vectors
  • After preprocessing: 25,571 clean flights, median duration 13.5 min
Stage Count
Raw state vectors 937,923
Flight segments detected 32,648
After duration filter 25,698
After resample + quality filter 25,571

Architecture

Input sequence (10 × 30s = 5 min context)
12 features per step:
  Δlat, Δlon, Δaltitude          ← displacement deltas
  velocity, vertical_rate         ← kinematic state
  sin(heading), cos(heading)      ← circular heading encoding
  Δheading, velocity_roc          ← rate of change
  phase (climb/cruise/descent)    ← flight phase embedding
  baro_altitude, elapsed_s_norm   ← absolute context
        │
        ▼
Linear projection → d_model=256
        │
        ▼
Learned positional encoding
        │
        ▼
6 × Transformer encoder layers
  (8 heads, FFN dim=1024, GELU, Pre-LN, dropout=0.3)
        │
        ▼
[CLS] token pooling
        │
        ▼
4 × independent prediction heads
  → [Δlat, Δlon, Δalt] at +1/+2/+3/+6 min

4.9M parameters - trained on a T4 GPU (Google Colab), ~82 epochs, early stopping.

Why a Transformer over LSTM?
Self-attention lets every timestep attend to every other directly - no vanishing gradient over long sequences. Empirically outperforms LSTM on trajectory prediction tasks at horizons > 3 min.


Pipeline

OpenSky API (OAuth2)
      │
      ▼
scripts/run_collector.py     ← ADS-B polling, parquet output, budget management
      │
      ▼
src/data/preprocess.py       ← flight segmentation, resample(30s), interpolation
      │
      ▼
src/data/dataset.py          ← sliding windows, feature engineering, normalisation
      │
      ▼
src/models/transformer.py    ← TrajectoryTransformer
      │
      ▼
scripts/train.py             ← AdamW + cosine LR + warmup + early stopping
      │
      ▼
src/eval/baseline.py         ← kinematic baseline + haversine metrics
      │
      ▼
src/serving/api.py           ← FastAPI inference endpoint
      │
      ▼
docs/demo.html               ← live map demo (Leaflet)

Quickstart

Prerequisites

Setup

git clone https://github.com/JeremyMaille/flight-trajectory-prediction.git
cd flight-trajectory-prediction

python3 -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate
pip install -r requirements.txt

cp .env.example .env
# Fill in your OpenSky OAuth2 credentials

Collect data

export $(grep -v '^#' .env | xargs)
python scripts/run_collector.py
# Collects ADS-B state vectors every 30s into data/raw/
# Budget: 3500 API credits/day (resets at midnight UTC)

Preprocess

python src/data/preprocess.py
# Segments flights, resamples to 30s grid, engineers features
# Output: data/processed/flights/*.parquet

Evaluate baseline

python src/eval/baseline.py
# Prints kinematic baseline metrics (haversine error, ADE/FDE)

Train (recommended: Google Colab T4)

# Open notebooks/train_colab_v2.ipynb in Colab
# Runtime → Change runtime type → T4 GPU
# Runtime → Run All

Or locally:

python scripts/train.py
mlflow ui   # monitor at http://localhost:5000

Run the API + demo

docker compose up --build
# API available at http://localhost:8000
# Open docs/demo.html in your browser

API

GET  /health              → model status
GET  /flights             → list available flights
GET  /demo/{flight_id}    → fetch a real flight for the demo
POST /predict             → predict future positions

Example prediction request:

curl -X POST http://localhost:8000/predict \
  -H "Content-Type: application/json" \
  -d '{
    "points": [
      {"ts": "2026-06-20T10:00:00Z", "latitude": 48.85, "longitude": 2.35,
       "baro_altitude": 10000, "velocity": 230, "true_track": 90, "vertical_rate": 0},
      ...  // 10 points minimum, ~30s apart
    ]
  }'

Response:

{
  "status": "ok",
  "predictions": [
    {"horizon_label": "+1 min", "pred_latitude": 48.853, "pred_longitude": 2.578, "pred_altitude": 9998},
    {"horizon_label": "+2 min", "pred_latitude": 48.856, "pred_longitude": 2.806, "pred_altitude": 9995},
    {"horizon_label": "+3 min", "pred_latitude": 48.860, "pred_longitude": 3.034, "pred_altitude": 9990},
    {"horizon_label": "+6 min", "pred_latitude": 48.871, "pred_longitude": 3.718, "pred_altitude": 9975}
  ]
}

Limitations & Future Work

  • Short horizons: The kinematic baseline outperforms the model at +1/+2 min. On very short horizons, physics-based extrapolation is hard to beat without a much larger dataset.
  • Data volume: 25k flights over 7 days is a limited training set. Performance would improve significantly with historical data via the OpenSky Trino interface (access requested).
  • Geographic scope: Trained exclusively on the Paris TMA - the model may not generalise to other airspaces without retraining.
  • No intent encoding: The model has no access to flight plan data, which would substantially improve longer-horizon predictions.

Stack

Component Technology
Data collection OpenSky REST API (OAuth2), Python
Data processing pandas, pyarrow, resample/interpolate
ML framework PyTorch 2.x
Model Temporal Transformer (custom)
Experiment tracking MLflow
Serving FastAPI + Uvicorn
Containerisation Docker + docker-compose
Demo Leaflet.js
Training environment Google Colab (T4 GPU)

Project Structure

flight-trajectory-prediction/
├── data/
│   ├── raw/                    # ADS-B parquet files (gitignored)
│   └── processed/flights/      # per-flight parquet (gitignored)
├── docs/
│   └── demo.html               # live map demo
├── models/
│   ├── best_model.pt           # trained checkpoint (gitignored)
│   └── norm_stats.json         # normalisation statistics
├── notebooks/
│   └── train_colab_v2.ipynb    # Colab training notebook (Run All)
├── scripts/
│   ├── run_collector.py        # ADS-B data collector
│   └── train.py                # training entry point
├── src/
│   ├── data/
│   │   ├── preprocess.py       # flight segmentation + resampling
│   │   └── dataset.py          # PyTorch Dataset + feature engineering
│   ├── eval/
│   │   └── baseline.py         # kinematic baseline + metrics
│   ├── models/
│   │   └── transformer.py      # TrajectoryTransformer architecture
│   └── serving/
│       └── api.py              # FastAPI inference service
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
└── .env.example

Author

Jérémy Maille - Ingénieur IA & Machine Learning
CESI École d'Ingénieurs (Bac+5) GitHub · LinkedIn

About

Transformer-based aircraft trajectory prediction from live ADS-B data · end-to-end pipeline with FastAPI inference API + Docker

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages