Your drone's flight log, decoded.
FlightMD is a production-grade, open-source flight log analyser for PX4, ArduPilot, and MAVLink telemetry logs. A deterministic diagnostic engine generates plain-English analysis reports for drone pilots and engineers — fully functional offline, with an optional AI layer for polished summaries and Q&A.
Upload a PX4 (.ulg), ArduPilot (.bin), or MAVLink telemetry (.tlog) flight log —
format is auto-detected. Within 20 seconds you receive a structured diagnostic report:
- Overall health score (0–100) with label
- Categorised findings — oscillation, vibration, EKF, battery, GPS, parameters, motors
- Plain-English explanations of every issue, generated by a deterministic rule engine (no AI required)
- Exact parameter changes to fix each problem (copy-pasteable)
- PDF export — a printable flight analysis report for internal review and maintenance tracking
- GPX/KML export — the flight's GPS track, ready to open in Google Earth, QGIS, or any GIS tool
- Auto-located flights — GPS coordinates are reverse-geocoded to a city/country label on the report, free and offline-friendly (OpenStreetMap Nominatim, no API key)
- Cross-flight trends (opt-in) — tag a flight with an airframe label and watch its health score, and the raw numbers behind it, move across every flight under that label
- Flight-to-flight diff — compare any two reports side by side to check whether a tuning change actually helped
- Commercial drone pilots who stare at log graphs without knowing what they mean
- UAV engineers tuning new airframes
- Fleet operators who need post-flight health checks before the next day
- Students learning PX4 tuning
Most flight-log tools stop at plotting curves. Flight Review and UAV Log Viewer will show you a vibration graph — you still have to know what "45 rad/s² on IMU1" means and what parameter to change because of it. Fleet-management SaaS platforms go further on diagnosis, but the report lives behind a login, a subscription, and someone else's server, and the "insight" is usually an opaque LLM call you can't reproduce or audit.
FlightMD's position is different on three axes at once:
- Deterministic, not black-boxed. Every finding comes from one of seven rule-based analysis engines (oscillation, vibration, EKF, battery, GPS, parameters, motors) — the same log always produces the same report, and every severity and recommendation can be traced back to a specific threshold in the code. AI is optional and, when enabled, only rewrites the tone of the executive summary — it never invents a finding.
- Actionable, not just descriptive. Every finding ships with the exact parameter name and value
to change (
MPC_XY_P: 0.95 → 1.4), not just a chart with a red zone on it. - Free to self-host, not a walled garden. No login, no account required. Reports are ephemeral by default (expire after 1 hour) — cross-flight trend history is opt-in, only kept for flights you explicitly tag, never collected automatically. MIT-licensed, and the optional AI layer defaults to Groq's free tier so running your own instance costs nothing.
AirData UAV is the closest real competitor — a paid, account-required fleet-ops
platform (Free tier → $14.99/mo → Enterprise) with broad drone/app support (DJI GO/Fly/Pilot, Autel,
Parrot, Litchi, DroneDeploy, Pix4D, plus PX4 .ulg/ArduPilot .bin upload) and genuinely good fleet
tooling: maintenance scheduling, compliance report generation, alert thresholds, and wind/RF-interference
map visualization. It's a different value proposition, not a strict subset — checked directly against
their site, pricing page, and real ArduPilot-user reports: for PX4/ArduPilot logs specifically, there's
no oscillation/vibration/EKF/parameter-tuning analysis anywhere in their materials, and their "Auto
Analysis" tool is described by an experienced ArduPilot user on their own forum as "outdated and mostly
useless." Their strength is fleet operations; FlightMD's is root-cause diagnosis — with the fleet-ops
features below now closing the gap without needing an account.
| FlightMD | PX4 Flight Review | UAV Log Viewer | AirData UAV | |
|---|---|---|---|---|
| Multi-format: PX4 · ArduPilot · MAVLink | ✅ one tool, auto-detected | ❌ PX4 only | Partial | ✅ |
| Root-cause explanations (not just plots) | ✅ 7 deterministic rule engines | ❌ | ❌ | ❌ basic visualization only for PX4/ArduPilot |
| Exact parameter fix per finding | ✅ | ❌ | ❌ | ❌ |
| Cross-flight trend analysis | ✅ opt-in, no account needed | ❌ single-log only | ❌ single-log only | ✅ requires an account |
| Side-by-side flight comparison | ✅ | ❌ | ❌ | Partial |
| Maintenance tracking & checklists | ✅ opt-in, per airframe | ❌ | ❌ | ✅ |
| Flight/maintenance record export | ✅ PDF, your own recordkeeping | ❌ | ❌ | ✅ "compliance reports" |
| Fleet alert thresholds | ✅ webhook-based (Slack/Discord) | ❌ | ❌ | ✅ |
| Wind / signal-quality path visualization | ✅ 3D path colour-coded by wind or GPS HDOP | ❌ | ❌ | ✅ wind maps, RF interference |
| Fully functional with zero AI/cloud calls | ✅ | ✅ | ✅ | ❌ |
| Optional AI layer with a free tier | ✅ Groq, no cost to operator | ❌ | ❌ | ❌ |
| Open source / self-hostable | ✅ MIT | ✅ BSD | ✅ | ❌ closed source |
| No login, ephemeral by default | ✅ reports expire in 1h unless tagged | ✅ | ✅ | ❌ accounts required, 6–24mo archives |
| Interactive 3D flight-path visualization | ✅ | ❌ | Basic 2D | ✅ |
| Time to report | ~20s | Instant (client-side plots) | Instant (client-side plots) | Varies |
Rather than trust synthetic test data alone, FlightMD was run against 50 real flight logs pulled
from PX4's own public Flight Review database — 11 vehicle types (quads, hexes, VTOLs, fixed-wing,
even a coaxial helicopter and a rover), 8.4GB total, selected by vehicle type and file size only,
before any of them were analysed. 49 of 50 processed in under 4 seconds; the one outlier is
root-caused and disclosed, not hidden from the average. Full methodology, the honest cross-check
against PX4's own (occasionally noisy) error metadata, and every bug the effort surfaced are in
verification/VERIFICATION_REPORT.md.
- Frontend: https://flightmd.vercel.app
- API: https://flightmd-api.onrender.com
- API Docs: https://flightmd-api.onrender.com/docs
flightmd/
├── flightmd_core/ ← Pure Python analysis package (pip-installable)
├── api/ ← FastAPI web service
├── frontend/ ← Next.js 14 web app
└── tests/ ← pytest test suite
pip install -r api/requirements.txt
python -m uvicorn api.main:app --reloadRun this from the repository root, not from inside api/ — api/main.py imports its
sibling modules as api.config, api.routers, etc., so the repo root needs to be on
sys.path, which python -m uvicorn from the root guarantees and cd api && uvicorn main:app
does not.
No API key required — the analysis engine is fully deterministic and offline. To enable optional AI-polished summaries and the AI Q&A assistant, grab a free key from Groq (no phone verification, 1,000 requests/day on Llama 3.3 70B):
export AI_PROVIDER=groq
export GROQ_API_KEY=your_key_hereOr use Claude instead, if you have an Anthropic key and want that quality:
export AI_PROVIDER=anthropic
export ANTHROPIC_API_KEY=your_key_herecd frontend
npm install
NEXT_PUBLIC_API_URL=http://localhost:8000 npm run devfrom flightmd_core import run_analysis
report = await run_analysis(
ulog_path="flight.ulg",
file_name="flight.ulg",
file_size=1234567,
)
print(f"Health: {report.overall_score}/100 ({report.score_label})")
for finding in report.findings:
print(f"[{finding.severity}] {finding.title}")
print(f" → {finding.plain_english}")To enable AI-polished summaries, pass an AIEnhancer:
from flightmd_core import run_analysis
from flightmd_core.services.ai_enhancer import AIEnhancer
report = await run_analysis(
ulog_path="flight.ulg",
file_name="flight.ulg",
file_size=1234567,
ai_enhancer=AIEnhancer(provider="groq", groq_api_key="your_key_here"),
# or: AIEnhancer(provider="anthropic", anthropic_api_key="your_key_here")
)| Module | What it checks | Weight |
|---|---|---|
| Oscillation | FFT-based roll/pitch/yaw oscillation detection | 20% |
| Vibration | IMU RMS + clip analysis | 20% |
| EKF | Innovation spikes, solution validity flags | 20% |
| Battery | Voltage sag, IR estimation, capacity fade | 15% |
| GPS | Fix quality, HDOP, jamming, spoofing | 15% |
| Parameters | Anomalies vs PX4 defaults, dangerous combos | 5% |
| Motors | ESC telemetry, motor balance, RPM dropouts | 5% |
An eighth module, Ascent & Recovery Analysis, runs on every flight but isn't weighted into
overall_score above — see below.
ArduPilot/PX4/MAVLink telemetry isn't only a multirotor thing — sounding rockets and high-altitude
balloons (HABs) often fly the same autopilots or stream MAVLink-compatible telemetry from a custom
flight computer. Since neither has a declared "Rocket" vehicle type to key off (ArduPilot has no
rocket firmware; vehicle_type in the report is unreliable for this), the Ascent & Recovery
analyser detects the flight shape itself from the GPS altitude trace — a single dominant climb-
then-descend peak, at a scale or G-profile no ordinary multirotor flight produces — and skips
gracefully (not an error) for the multi-leg survey/mapping missions that make up the vast majority
of flights FlightMD sees. When it does apply:
- Apogee detection — peak altitude AGL, time-to-apogee, descent duration.
- High-G launch profile — peak boost acceleration and duration, plus a warning if angular rates during the boost phase suggest asymmetric thrust or tumbling under power.
- Parachute deployment detection — finds the sharp descent-rate change a successful deployment produces; warns if it happened very close to the ground, and flags critical if no deployment signature is found before the descent reaches near ground level (i.e. an apparent chute failure).
Because this module is inapplicable to typical drone flights, it's excluded from the weighted
overall_score — its findings appear in the report, but a rocket/HAB-only concern never dilutes or
gets diluted by the general multirotor scoring.
Every finding is generated fresh from a single flight — but some problems (a battery pack's internal resistance creeping up, a frame slowly loosening) only show up as a trend across many flights, long before any single flight is bad enough to trigger a finding.
- Tag a flight with an airframe label at upload time (e.g.
Quad-1) to opt it into trend history. Untagged flights are unaffected — they stay ephemeral and expire in 1 hour, exactly as before. Nothing is retained unless you explicitly name an airframe. GET /trends/{airframe_label}returns every tagged flight's overall score, all seven module scores, and the raw numbers behind them (oscillation frequency, battery sag per cell, GPS HDOP, etc. —key_metricson eachAnalyserResult) so you can see drift before it becomes a finding.GET /diff?a={report_id}&b={report_id}compares any two flights — score deltas, which findings were resolved vs newly introduced, and how each parameter recommendation changed. Doesn't require tagging; works on any two reports that still exist.
Both are backed by the same deterministic analysis output — no separate AI call, no additional computation beyond re-shaping data that was already produced per-flight.
Tagging an airframe (above) also unlocks a small set of fleet-ops features, opt-in and per-airframe — none of this is collected unless you name an airframe:
- Maintenance tracking & checklists. Log maintenance events (date, type, notes) per airframe;
set a maintenance interval in hours and FlightMD tells you how many flight-hours have accumulated
since the last logged service, flagging when it's due. A simple pre-flight checklist template lives
alongside it.
GET/PUT /airframe/{label}/config,POST /airframe/{label}/maintenance. - Flight & maintenance record export.
GET /export/airframe/{label}/pdfgenerates a PDF of the airframe's flight history, maintenance log, and checklist — for your own recordkeeping, not a regulatory certification. FlightMD doesn't assert compliance with anything; it just hands you your own data in one document, consistent with the rest of the report never making a compliance claim. - Alert thresholds via webhook. Set rules like "alert if overall score drops below 80" or "alert if battery sag exceeds 0.5V/cell" per airframe, plus a webhook URL (Slack/Discord-compatible). When a new tagged flight breaches a rule, FlightMD posts a message — no account, no email server, just a webhook you already control. The URL is validated https-only and must resolve to a public address before anything is ever sent to it.
- Wind speed / GPS signal-quality path visualization. The 3D flight-path scene can colour-code the path by wind speed (PX4 logs with a converged wind estimate) or GPS signal quality (HDOP, all formats) instead of a flat colour — a toggle appears automatically when a report has that data.
Every upload has an optional, unchecked-by-default "Contribute this log anonymously" box. Checking it saves a copy of the raw log and its generated report to a growing, anonymous dataset — no name, account, or upload source attached, just the log and its analysis. It's independent of airframe tagging: contribute, tag for trends, both, or neither.
This is used to validate FlightMD's rule engine against a wider variety of real airframes and
firmware versions than any one operator sees, and — as the dataset grows — as the raw material for a
FlightMD-trained model down the line. GET /dataset/stats reports the running total (log count and
combined size) so the effect of opting in is visible, not a black box.
flightmd_core is architecturally designed to be imported directly by UAOP (Unified Autonomy Operating Platform) as a Python package dependency:
# In UAOP's pyproject.toml
dependencies = [
"flightmd-core>=1.0.0",
]The FlightMDReport data contract (schema_version = "1.5") will remain stable across minor versions.
- Backend: Render.com free tier (Singapore region)
- Frontend: Vercel free tier
- CI/CD: GitHub Actions
See api/render.yaml and frontend/vercel.json for deployment configs.
- Fork the repo
- Create a feature branch:
git checkout -b feat/your-feature - Run tests:
cd api && pytest ../tests/ -v - Submit a PR
MIT — see LICENSE
Built by Pradum Behl, India