Open Source Drone Flight Analysis
Analyze crash logs. Diagnose failures. Ship safer drones.
$ goose serve flight.ulgπͺΏ GOOSE v1.3.0 β Flight Analysis DashboardββββββββββββββββββββββββββββββββββββββββββββParsing flight.ulg ... β (14,832 samples, 18m 42s)Running 11 analysis plugins ... [β] crash_detection CRITICAL Motor #3 failure at T+847s [β] vibration WARNING RMS spike 3.2Ο above baseline [β] battery_sag OK Max sag: 0.31V (within limits) [β] gps_health OK Min sats: 12, max HDOP: 1.4 [β] motor_saturation CRITICAL Motor #3 saturated 100% (6.2s) [β] ekf_consistency WARNING Innovation spike before crash [β] rc_signal OK Min RSSI: -68 dBm [β] attitude_tracking WARNING Uncontrolled roll divergence [β] position_tracking CRITICAL Position loss after T+847s [β] failsafe_events INFO LAND failsafe triggered T+849s [β] log_health OK No dropouts detectedββββββββββββββββββββββββββββββββββββββββROOT CAUSE: Motor #3 electrical failureCONFIDENCE: 94%CRASH SCORE: 87/100 (CRITICAL)Dashboard ready β http://localhost:8000 Flight Analysis Summary: 18m 42s flight, Quadcopter in Position mode (fw v1.14.3). Overall score: 23/100 (Critical). CRITICAL β Motor #3 electrical failure. 94% confidence. CRITICAL β Motor #3 saturated 100% for 6.2s before impact. 3 warnings: vibration spike, EKF innovation, roll divergence. Interactive charts, flight path map, and gauges ready.
Snort for drone flight data β pattern-match your telemetry against known failure signatures.
Automatic crash diagnosis with confidence scoring and inspection checklists
Altitude, battery, motors, attitude, vibration, GPS β all with zoom/pan
GPS track on dark satellite tiles with timeline-linked position scrubbing
Plain-English flight summary generated from findings β no AI, pure analysis
Vibration, GPS, battery, motors, EKF, attitude, RC, position tracking, and more
Battery, vibration, motor balance, and stability gauges with color-coded scoring
Write your own analysis plugins, share with pip install
Full GUI at localhost β no terminal required. Upload, analyze, explore
pip install goose-flightOne command. No Docker, no accounts, no cloud.
goose crash flight.ulgPoint it at your log. Get a root-cause report in seconds.
goose serveLocal web UI opens at localhost:8000 with full findings.
A clean pipeline from raw log bytes to scored findings β no magic, no black boxes.
.ulg / .bin / .tlog / .csv | [ Parser Layer ] Auto-detects format | [ Normalized Flight Object ] pandas DataFrames + metadata | [ Plugin Engine ] Discovers & runs all plugins | [ Findings + Scoring + Narrative ] Severity, scores, evidence, summary | ββββββ΄βββββ | | [ CLI ] [ Web Dashboard ] Terminal localhost:8000 output Score ring, gauges, + JSON interactive charts, flight path map, auto narrative
Auto-detects log format from file header magic bytes. Normalises timestamps, resamples to a common time base, and handles corrupt or truncated files gracefully.
All data lives in typed pandas DataFrames keyed by stream name. Every plugin sees the same interface regardless of whether the log came from PX4, ArduPilot, or a custom autopilot.
Discovers plugins via Python entry-points β no config file needed. Runs each plugin in isolation, catches exceptions so one bad plugin never kills the run.
Each finding carries a severity (critical / warning / info / pass) and a 0β100 score. The overall flight score is a weighted average, with crash_detection weighted highest.
11 active plugins in v1.3 Β· 8 more planned Β· write your own in ~50 lines of Python
crash_detectionactiveMotor failure, power loss, GPS loss, impact signature detection
Detects rapid altitude loss (>5 m/s sustained), sudden attitude divergence (>30 deg in <2s), motor output drops to zero, and high-g impact signatures. Classifies crashes as motor_failure, power_loss, gps_loss, pilot_error, mechanical, or unknown with confidence scoring.
vibrationactiveAccelerometer RMS/peak analysis, clipping, bearing degradation
Computes RMS and peak vibration per axis against PX4 thresholds: good <15 m/sΒ², warning 15β30, bad >30. Detects accelerometer clipping/saturation and bearing degradation trends over flight duration.
battery_sagactiveVoltage sag under load, brownout risk, cell health
Measures voltage drop under load, minimum cell voltage (warning <3.5V, critical <3.3V), brownout risk detection (>0.5V drop in <1s), and battery temperature monitoring.
gps_healthactiveSatellite count, HDOP, dropout detection, jamming
Monitors satellite count (warning <10, critical <6), HDOP quality (warning >2.0, critical >4.0), GPS dropout detection, fix type degradation, and jamming indicators.
motor_saturationactiveOutput limits, asymmetry, failure signatures
Detects motors hitting 100% output (saturated), motor asymmetry between axes, motor failure signatures (output drops to 0 while others compensate), and remaining motor headroom.
ekf_consistencyactiveInnovation monitoring, filter health, fault detection
Checks velocity and position innovation ratios (warning >0.8, critical >1.0), magnetometer consistency, EKF reset detection, and estimator fault flags.
rc_signalactiveRSSI monitoring, dropout detection, stuck channels
Monitors RSSI minimum and average (warning <70%, critical <50%), signal dropout detection (gaps >2s), stuck channel detection, and RC failsafe event tracking.
attitude_trackingactiveRoll/pitch/yaw error vs setpoint, oscillation
Compares roll/pitch/yaw actual vs setpoint, computes RMS tracking error per axis (warning >5 deg, critical >15 deg), detects PID oscillation via sign-change rate analysis.
position_trackingactivePosition error vs commanded, hover drift
Measures horizontal position error via Haversine calculation (warning >3m, critical >10m), vertical altitude error (warning >2m, critical >5m), and hover drift detection during low-velocity flight.
failsafe_eventsactiveFailsafe triggers, emergency mode transitions
Catalogs all failsafe triggers with timestamps, identifies emergency mode transitions (RTL, LAND, emergency), distinguishes failsafe-triggered vs pilot-initiated mode changes.
log_healthactiveData integrity, dropouts, rate checks
Checks for data dropouts (timestamp gaps >1s), verifies all expected data streams are present, validates data rates (warning if <1 Hz), and cross-checks measured duration against metadata.
geofencehelp wantedMonitor position against defined boundaries, detect breaches
View issue βwind_estimationhelp wantedEstimate wind speed/direction from GPS ground track vs airspeed
View issue βcompass_healthhelp wantedDetect magnetic interference, compass-motor calibration issues
View issue βthermal_analysishelp wantedMonitor ESC/motor/battery temperatures for overheating
View issue βpropulsion_efficiencyhelp wantedCalculate thrust-to-weight, power consumption per meter
View issue βnoise_analysishelp wantedDetect EMI/electrical noise affecting sensors
View issue βlidar_healthhelp wantedValidate rangefinder readings against barometer/GPS altitude
View issue βterrain_followinghelp wantedCheck terrain-relative altitude accuracy
View issue βThe plugin API is dead simple. If you know pandas, you can ship a plugin in an afternoon.
Normalized data from any log format. pandas DataFrames for time-series (position, attitude, battery, motors, vibration, GPS, EKF, RC). Lists for events and mode changes. Dict for parameters.
What your plugin returns. Title, severity (critical / warning / info / pass), score (0β100), description, evidence dict, optional phase and timestamps.
90β100 = pass (green), 60β89 = warning (amber), 0β59 = critical (red). Overall flight score is a weighted average of all plugin scores.
Plugins can tag findings with the flight phase they occurred in β takeoff, on_mission, landing, etc. β for contextual reporting.
1. Implement the Plugin class
from goose.plugins.base import Pluginfrom goose.core.finding import Findingfrom goose.core.flight import Flightclass WindEstimationPlugin(Plugin): """Estimate wind speed and direction from flight data.""" name = "wind_estimation" version = "1.0.0" description = "Estimates wind conditions from GPS and airspeed data" min_mode = "position" def analyze(self, flight: Flight, config: dict) -> list[Finding]: findings = [] if flight.velocity.empty: return [Finding( plugin_name=self.name, title="No velocity data available", severity="info", score=50, description="Wind estimation requires velocity data.", )] # Access flight.velocity, flight.position, flight.gps, etc. # All time-series data is in pandas DataFrames ground_speed = ( flight.velocity["vx"]**2 + flight.velocity["vy"]**2 )**0.5 max_speed = float(ground_speed.max()) findings.append(Finding( plugin_name=self.name, title=f"Max ground speed: {max_speed:.1f} m/s", severity="pass", score=95, description=f"Peak ground speed was {max_speed:.1f} m/s.", evidence={"max_ground_speed_ms": round(max_speed, 2)}, )) return findings
2. Register via entry-points
# In your plugin's pyproject.toml[project.entry-points."goose.plugins"]wind_estimation = "my_package:WindEstimationPlugin"
3. Install and discover
pip install goose-plugin-wind# Plugin is automatically discovered by Goosegoose plugins list # Shows your new plugin
Plugin and implements analyze()pyproject.toml entry points β Goose auto-discovers on installgoose-plugin-xyz on PyPICheck the GitHub issues for plugins tagged good first issue β 8 planned plugins are waiting for community authors.
| Format | Autopilot | Status |
|---|---|---|
| ULog (.ulg) | PX4 | Supported |
| DataFlash (.bin/.log) | ArduPilot | Coming v1.4 |
| MAVLink tlog (.tlog) | GCS recordings | Planned |
| CSV | Custom autopilots | Planned |
11 plugins, ULog parser, CLI, Web UI, JSON reports, scoring engine
Interactive charts, flight path map, health gauges, auto narrative, timeline scrubber
SVG flight path, timeline-synced charts + map, auto narrative, health gauges
Cockpit themes, drag-drop layout, timeline-linked gauges, ArduPilot parser
Online analysis at flygoose.dev, fleet baselines, PDF reports, team features
Built on battle-tested open source Python tooling
Open source, no strings attached. Build on it, fork it, ship it.
Apache-2.0