Skip to content

Betaflight PID AutoTune - application that takes the guesswork out of FPV drone tuning 😀

Notifications You must be signed in to change notification settings

eddycek/bfautotune

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

283 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Betaflight PID AutoTune

Desktop application that takes the guesswork out of FPV drone tuning.

Most pilots tune their drones by hand β€” changing PID numbers, test flying, reading Blackbox graphs, and repeating. It's slow, confusing, and error-prone.

BFAutoTune connects to your Betaflight flight controller over USB, guides you through two short test flights, analyzes the Blackbox data automatically (FFT noise analysis for filters, step response metrics for PIDs), and applies optimized settings with one click. No graph reading, no spreadsheets, no guesswork.

How it works: Connect FC β†’ Fly hover + throttle sweeps β†’ App tunes filters β†’ Fly stick snaps β†’ App tunes PIDs β†’ Done.

Download

Pre-built binaries are available on the Releases page:

Platform Format File
macOS Disk Image Betaflight.PID.AutoTune-*.dmg
Windows Installer Betaflight.PID.AutoTune-Setup-*.exe
Linux AppImage Betaflight.PID.AutoTune-*.AppImage

Note: macOS builds are currently unsigned. On first launch, right-click the app and select Open, or run xattr -cr /Applications/Betaflight\ PID\ AutoTune.app in Terminal to bypass Gatekeeper.

Supported Betaflight Versions

Tier Version Notes
Minimum BF 4.3 (API 1.44) Oldest supported β€” connects and works
Recommended BF 4.5+ (API 1.46) Best feature coverage
Actively tested BF 4.5.x, 2025.12.x User's fleet

Connecting with BF 4.2 or earlier will show an error and auto-disconnect. See BF Version Policy for detailed rationale and version-specific notes.

Current Status

  • Phase 1: βœ… Complete - MSP connection, profile management, snapshots
  • Phase 2: βœ… Complete - Blackbox analysis, automated tuning, rollback
  • Phase 2.5: βœ… Complete - Profile simplification, interactive analysis charts
  • Phase 3: βœ… Complete - Mode-aware wizard, read-only analysis, flight guides
  • Phase 4: βœ… Complete - Stateful two-flight tuning workflow
  • Phase 6: βœ… Complete - CI/CD with GitHub Actions (tests on PR, cross-platform releases on tag)

See SPEC.md for detailed phase tracking and test counts.

Features

Connection & Profiles

  • USB serial connection to Betaflight flight controllers (MSP protocol)
  • Multi-drone profile management with automatic FC detection by serial number
  • Profile auto-selection on connect, profile locking while FC is connected
  • 10 preset profiles (Tiny Whoop, 5" Freestyle, 7" Long Range, etc.)
  • Cross-platform (Windows, macOS, Linux)

Configuration Management

  • CLI export (diff/dump) for full configuration backup
  • Configuration snapshots with versioning and comparison
  • Snapshot restore/rollback via CLI command replay
  • GitHub-style diff view for snapshot comparison

Blackbox Analysis

  • Blackbox log download from FC flash storage (adaptive chunking)
  • Binary BBL log parser (validated against BF Explorer, 245 tests)
  • Multi-session support (multiple flights per file)
  • FC diagnostics: debug_mode, logging rate, and feedforward configuration display with warnings + one-click fix

Automated Tuning

  • Filter tuning: FFT noise analysis (Welch's method, Hanning window, peak detection)
  • PID tuning: Step response analysis (rise time, overshoot, settling, ringing)
  • Flight style preferences: Smooth (cinematic), Balanced (freestyle), or Aggressive (racing) β€” PID thresholds adapt to pilot preference
  • RPM filter awareness: Detects RPM filter state via MSP or BBL headers, widens safety bounds when active (gyro LPF1 up to 500 Hz), recommends dynamic notch optimization (count/Q), diagnoses motor harmonic anomalies
  • Feedforward awareness: Detects FF state from BBL headers, classifies FF-dominated overshoot, adjusts P/D recommendations accordingly
  • Data quality scoring: Rates input flight data 0-100 (excellent/good/fair/poor), adjusts recommendation confidence based on data quality, warns about insufficient hover time, missing axes, or too few steps
  • Convergent recommendations (idempotent - rerunning produces same result)
  • Safety bounds prevent extreme values, plain-English explanations
  • One-click apply with automatic safety snapshot

Two-Flight Guided Workflow

  • Stateful tuning session: filters first (hover + throttle sweeps), then PIDs (stick snaps)
  • Step-by-step banner with progress indicator (10 phases including optional verification)
  • Smart reconnect detection: auto-advances when flight data detected
  • Post-erase guidance: flash erased notification with flight guide
  • Mode-aware wizard adapts UI for filter vs PID analysis
  • Optional verification hover after PID apply for before/after noise comparison
  • Tuning completion summary with applied changes, noise metrics, and PID response data

Tuning History

  • Archived tuning records per profile (persistent across sessions)
  • Before/after noise spectrum overlay with dB delta indicators
  • Applied filter and PID changes table with old β†’ new values
  • Expandable history cards on the dashboard

Interactive Charts

  • FFT spectrum chart (noise per axis, floor lines, peak markers)
  • Step response chart (setpoint vs gyro trace, metrics overlay)
  • Axis tabs (Roll/Pitch/Yaw/All) for both chart types

Tech Stack

  • Electron - Desktop application framework
  • TypeScript - Type-safe development
  • React - UI framework
  • Vite - Fast build tool
  • serialport - USB serial communication
  • MSP Protocol - Betaflight communication protocol
  • fft.js - FFT computation for noise analysis
  • Recharts - SVG-based interactive analysis charts
  • ESLint + Prettier - Code linting and formatting (lint-staged pre-commit)

Installation

Prerequisites

  • Node.js 20+ and npm
  • Python 3 (for native module compilation)
  • Build tools:
    • macOS: Xcode Command Line Tools (xcode-select --install)
    • Windows: Visual Studio Build Tools or windows-build-tools
    • Linux: build-essential package

Setup

  1. Clone the repository:
git clone https://github.com/eddycek/bfautotune.git
cd bfautotune
  1. Install dependencies:
npm install
  1. Rebuild native modules for Electron:
npm run rebuild

Development

Start the development server:

npm run dev

This will:

  • Start Vite dev server for hot reload
  • Launch Electron with the app
  • Open DevTools automatically

Demo Mode (No Hardware Needed)

Start the app with a simulated flight controller for offline UX testing:

npm run dev:demo

Demo mode auto-connects to a virtual FC, creates a demo profile, and generates realistic blackbox data. The full 10-phase tuning workflow is functional β€” real FFT and step response analysis runs on the simulated data. See docs/OFFLINE_UX_TESTING.md for details.

Testing

All UI changes must include tests. Tests automatically run before commits. Coverage thresholds enforced: 80% lines/functions/statements, 75% branches.

Unit tests: 1877 tests across 96 files β€” MSP protocol, storage managers, IPC handlers, UI components, hooks, BBL parser fuzz, analysis pipeline validation, E2E workflows.

Playwright E2E: 16 tests across 3 spec files β€” launches real Electron app in demo mode, walks through complete tuning cycles.

# Run unit tests in watch mode
npm test

# Run unit tests once
npm run test:run

# Open interactive test UI
npm run test:ui

# Generate coverage report
npm run test:coverage

# Run E2E tests (builds app, then runs Playwright)
npm run test:e2e

# Run E2E with Playwright UI
npm run test:e2e:ui

# Generate 5 tuning sessions for demo screenshots (~2 min)
npm run demo:generate-history

See TESTING.md for complete testing guidelines, test inventory, and best practices. See docs/COMPREHENSIVE_TESTING_PLAN.md for the full testing plan and architecture.

Building

Build the application for your platform:

npm run build

Output will be in the release/ directory.

Releasing

Releases are automated via GitHub Actions. To create a new release:

# Update version in package.json, then:
git tag v0.2.0
git push origin v0.2.0

This triggers the release workflow which builds native installers for macOS (.dmg), Windows (.exe), and Linux (.AppImage), then uploads them as a draft GitHub Release. Review the draft and publish it manually.

Project Structure

bfautotune/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ main/                    # Main process (Node.js)
β”‚   β”‚   β”œβ”€β”€ index.ts             # Entry point, event wiring
β”‚   β”‚   β”œβ”€β”€ window.ts            # Window management
β”‚   β”‚   β”œβ”€β”€ msp/                 # MSP communication
β”‚   β”‚   β”‚   β”œβ”€β”€ MSPClient.ts     # High-level MSP API (connect, read/write, download)
β”‚   β”‚   β”‚   β”œβ”€β”€ MSPConnection.ts # Serial port + CLI mode + reboot handling
β”‚   β”‚   β”‚   β”œβ”€β”€ MSPProtocol.ts   # Protocol encoding/decoding (MSP v1)
β”‚   β”‚   β”‚   β”œβ”€β”€ commands.ts      # MSP command definitions
β”‚   β”‚   β”‚   └── types.ts         # MSP type definitions
β”‚   β”‚   β”œβ”€β”€ blackbox/            # BBL binary log parser (6 modules, 245 tests)
β”‚   β”‚   β”œβ”€β”€ analysis/            # FFT noise + step response analysis (11 modules, FF-aware)
β”‚   β”‚   β”‚   β”œβ”€β”€ FFTCompute.ts        # Welch's method, Hanning window
β”‚   β”‚   β”‚   β”œβ”€β”€ SegmentSelector.ts   # Hover segment detection
β”‚   β”‚   β”‚   β”œβ”€β”€ NoiseAnalyzer.ts     # Peak detection, noise classification
β”‚   β”‚   β”‚   β”œβ”€β”€ FilterRecommender.ts # Noise-based filter targets
β”‚   β”‚   β”‚   β”œβ”€β”€ FilterAnalyzer.ts    # Filter analysis orchestrator
β”‚   β”‚   β”‚   β”œβ”€β”€ StepDetector.ts      # Step input detection in setpoint
β”‚   β”‚   β”‚   β”œβ”€β”€ StepMetrics.ts       # Rise time, overshoot, settling, FF classification
β”‚   β”‚   β”‚   β”œβ”€β”€ PIDRecommender.ts    # Flight-PID-anchored P/D recommendations, FF-aware
β”‚   β”‚   β”‚   β”œβ”€β”€ PIDAnalyzer.ts       # PID analysis orchestrator (FF context wiring)
β”‚   β”‚   β”‚   β”œβ”€β”€ DataQualityScorer.ts # Flight data quality scoring (0-100)
β”‚   β”‚   β”‚   β”œβ”€β”€ headerValidation.ts  # BB header diagnostics
β”‚   β”‚   β”‚   └── constants.ts         # Tunable thresholds
β”‚   β”‚   β”œβ”€β”€ storage/             # Data managers
β”‚   β”‚   β”‚   β”œβ”€β”€ ProfileManager.ts        # Multi-drone profile CRUD
β”‚   β”‚   β”‚   β”œβ”€β”€ ProfileStorage.ts        # File-based profile storage
β”‚   β”‚   β”‚   β”œβ”€β”€ SnapshotManager.ts       # Configuration snapshots
β”‚   β”‚   β”‚   β”œβ”€β”€ BlackboxManager.ts       # BB log file management
β”‚   β”‚   β”‚   β”œβ”€β”€ TuningSessionManager.ts  # Tuning session state machine
β”‚   β”‚   β”‚   β”œβ”€β”€ TuningHistoryManager.ts # Tuning history archive
β”‚   β”‚   β”‚   └── FileStorage.ts           # Generic file storage utilities
β”‚   β”‚   β”œβ”€β”€ demo/               # Demo mode (offline UX testing)
β”‚   β”‚   β”‚   β”œβ”€β”€ MockMSPClient.ts       # Simulated FC (47 tests)
β”‚   β”‚   β”‚   └── DemoDataGenerator.ts   # Realistic BBL generation (22 tests)
β”‚   β”‚   β”œβ”€β”€ ipc/                 # IPC handlers
β”‚   β”‚   β”‚   β”œβ”€β”€ handlers/       # Domain-split handler modules (11 files)
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ index.ts            # DI container, registerIPCHandlers
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ types.ts            # HandlerDependencies interface
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ events.ts           # Event broadcast functions
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ connectionHandlers.ts
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ fcInfoHandlers.ts
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ snapshotHandlers.ts
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ profileHandlers.ts
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ pidHandlers.ts
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ blackboxHandlers.ts
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ analysisHandlers.ts
β”‚   β”‚   β”‚   β”‚   └── tuningHandlers.ts
β”‚   β”‚   β”‚   └── channels.ts     # Channel definitions
β”‚   β”‚   └── utils/               # Logger, error types
β”‚   β”‚
β”‚   β”œβ”€β”€ preload/                 # Preload script
β”‚   β”‚   └── index.ts             # window.betaflight API bridge
β”‚   β”‚
β”‚   β”œβ”€β”€ renderer/                # Renderer process (React)
β”‚   β”‚   β”œβ”€β”€ App.tsx              # Main layout, session routing
β”‚   β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”‚   β”œβ”€β”€ ConnectionPanel/       # Port selection, connect/disconnect
β”‚   β”‚   β”‚   β”œβ”€β”€ FCInfo/                # FC details + BB diagnostics + FixSettingsConfirmModal
β”‚   β”‚   β”‚   β”œβ”€β”€ BlackboxStatus/        # Flash storage, download, erase
β”‚   β”‚   β”‚   β”œβ”€β”€ SnapshotManager/       # Snapshot CRUD, diff view, restore
β”‚   β”‚   β”‚   β”œβ”€β”€ TuningWizard/          # Multi-step guided wizard
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ charts/            # SpectrumChart, StepResponseChart, AxisTabs
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ FilterAnalysisStep, PIDAnalysisStep  # Analysis result views
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ SessionSelectStep, TestFlightGuideStep # Pre-analysis steps
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ TuningSummaryStep, WizardProgress     # Summary + progress
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ RecommendationCard, ApplyConfirmationModal
β”‚   β”‚   β”‚   β”‚   └── FlightGuideContent # Flight phase instructions
β”‚   β”‚   β”‚   β”œβ”€β”€ TuningStatusBanner/    # Workflow progress banner
β”‚   β”‚   β”‚   β”œβ”€β”€ AnalysisOverview/      # Read-only analysis view
β”‚   β”‚   β”‚   β”œβ”€β”€ TuningHistory/         # History panel + completion summary
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ TuningHistoryPanel, TuningSessionDetail
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ TuningCompletionSummary  # Replaces banner on completion
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ NoiseComparisonChart     # Before/after spectrum overlay
β”‚   β”‚   β”‚   β”‚   └── AppliedChangesTable      # Setting changes with % diff
β”‚   β”‚   β”‚   β”œβ”€β”€ TuningWorkflowModal/   # Two-flight workflow help
β”‚   β”‚   β”‚   β”œβ”€β”€ Toast/                 # Toast notification system
β”‚   β”‚   β”‚   β”œβ”€β”€ ProfileWizard.tsx      # New FC profile creation wizard
β”‚   β”‚   β”‚   β”œβ”€β”€ ProfileSelector.tsx    # Profile switching dropdown
β”‚   β”‚   β”‚   β”œβ”€β”€ ErrorBoundary.tsx      # React error boundary (crash recovery)
β”‚   β”‚   β”‚   β”œβ”€β”€ ProfileCard.tsx        # Individual profile display
β”‚   β”‚   β”‚   β”œβ”€β”€ ProfileEditModal.tsx   # Profile editing dialog
β”‚   β”‚   β”‚   └── ProfileDeleteModal.tsx # Profile deletion confirmation
β”‚   β”‚   β”œβ”€β”€ hooks/               # React hooks (11)
β”‚   β”‚   β”‚   β”œβ”€β”€ useConnection.ts       # Connection state management
β”‚   β”‚   β”‚   β”œβ”€β”€ useProfiles.ts         # Profile CRUD operations
β”‚   β”‚   β”‚   β”œβ”€β”€ useSnapshots.ts        # Snapshot management
β”‚   β”‚   β”‚   β”œβ”€β”€ useTuningSession.ts    # Tuning session lifecycle
β”‚   β”‚   β”‚   β”œβ”€β”€ useTuningWizard.ts     # Wizard state (parse/analyze/apply)
β”‚   β”‚   β”‚   β”œβ”€β”€ useAnalysisOverview.ts # Read-only analysis state
β”‚   β”‚   β”‚   β”œβ”€β”€ useTuningHistory.ts    # Tuning history loading
β”‚   β”‚   β”‚   β”œβ”€β”€ useBlackboxInfo.ts     # BB flash info
β”‚   β”‚   β”‚   β”œβ”€β”€ useBlackboxLogs.ts     # BB log list
β”‚   β”‚   β”‚   β”œβ”€β”€ useFCInfo.ts           # FC info polling
β”‚   β”‚   β”‚   └── useToast.ts            # Toast context consumer
β”‚   β”‚   β”œβ”€β”€ utils/               # Renderer utilities
β”‚   β”‚   β”‚   └── bbSettingsUtils.ts     # BB settings status computation
β”‚   β”‚   β”œβ”€β”€ contexts/            # React contexts
β”‚   β”‚   β”‚   └── ToastContext.tsx
β”‚   β”‚   └── test/                # Test setup
β”‚   β”‚       └── setup.ts         # window.betaflight mock
β”‚   β”‚
β”‚   └── shared/                  # Shared types & constants
β”‚       β”œβ”€β”€ types/               # TypeScript interfaces (9 type files)
β”‚       β”œβ”€β”€ utils/               # Shared utilities (metrics extraction, spectrum downsampling)
β”‚       └── constants/           # MSP codes, presets, flight guides
β”‚
β”œβ”€β”€ e2e/                         # Playwright E2E tests (demo mode)
β”‚   β”œβ”€β”€ electron-app.ts          # Shared fixture (launchDemoApp, helpers)
β”‚   β”œβ”€β”€ demo-smoke.spec.ts       # 4 smoke tests
β”‚   β”œβ”€β”€ demo-tuning-cycle.spec.ts  # 11 tuning cycle tests
β”‚   └── demo-generate-history.spec.ts  # 5-cycle history generator
β”‚
└── docs/                        # Design docs (see docs/README.md for full index)
    β”œβ”€β”€ BBL_PARSER_VALIDATION.md             # Parser validation against BF Explorer
    β”œβ”€β”€ BF_VERSION_POLICY.md                 # BF version compatibility policy
    β”œβ”€β”€ COMPREHENSIVE_TESTING_PLAN.md        # 9-phase testing plan
    β”œβ”€β”€ FEEDFORWARD_AWARENESS.md             # FF detection, warnings, recommendations
    β”œβ”€β”€ FLIGHT_STYLE_PROFILES.md             # Smooth/Balanced/Aggressive flight styles
    β”œβ”€β”€ RPM_FILTER_AWARENESS.md              # RPM filter detection and bounds
    β”œβ”€β”€ TUNING_HISTORY_AND_COMPARISON.md     # Session history + before/after comparison
    β”œβ”€β”€ TUNING_WORKFLOW_REVISION.md          # Two-flight tuning workflow design
    β”œβ”€β”€ TUNING_WORKFLOW_FIXES.md             # Download/analyze fix + phase transitions
    β”œβ”€β”€ TUNING_PRECISION_IMPROVEMENTS.md     # Research: tuning accuracy improvements
    └── UX_IMPROVEMENT_IDEAS.md              # UX improvement backlog

Usage

1. First Connection & Profile Setup

  1. Connect your flight controller via USB
  2. Click Scan to detect available serial ports
  3. Select your FC from the dropdown and click Connect
  4. On first connection with a new FC, the Profile Wizard opens automatically:
    • Choose a preset profile (e.g., "5 inch Freestyle") or create a custom one
    • Enter drone name, size, weight, motor KV, battery config
    • Profile is linked to the FC's unique serial number
  5. A baseline snapshot is created automatically, capturing the FC's current configuration

On subsequent connections, the app recognizes the FC by serial number and auto-selects the correct profile.

2. Pre-Flight Setup

Before flying, check the Flight Controller Information panel:

  • Debug Mode should be GYRO_SCALED for noise analysis β€” BF 4.3–4.5 only (not needed on BF 2025.12+, hidden automatically)
  • Logging Rate should be at least 2 kHz (shown with green checkmark or amber warning)
  • Feedforward section shows current FF configuration read from FC (boost, per-axis gains, smoothing, jitter factor, transition, max rate limit)

If settings are wrong, click Fix Settings in the FC info panel β€” the app sends the CLI commands and reboots the FC automatically. During an active tuning session, the TuningStatusBanner also shows an amber pre-flight warning with a one-click fix button.

3. Guided Two-Flight Tuning

Click Start Tuning Session to begin the guided workflow. The status banner at the top tracks your progress through 10 phases:

Flight 1: Filter Tuning

  1. Erase Flash β€” Clear old Blackbox data before flying
  2. Fly filter test flight β€” Hover with gentle throttle sweeps (30-60 seconds)
  3. Reconnect β€” App auto-detects new flight data on reconnect
  4. Download log β€” Download Blackbox data from FC
  5. Analyze β€” Click Analyze to open the filter wizard:
    • Auto-parses the log and runs FFT noise analysis
    • Shows noise spectrum, detected peaks, and filter recommendations
    • Review recommendations, then click Apply Filters (creates safety snapshot + reboots FC)

Flight 2: PID Tuning

  1. Erase Flash β€” Clear flash for the PID test flight
  2. Fly PID test flight β€” Sharp stick snaps on all axes (roll, pitch, yaw)
  3. Reconnect & download β€” Same as above
  4. Analyze β€” Opens the PID wizard:
    • Detects step inputs, measures response metrics (overshoot, rise time, settling)
    • Shows step response charts and PID recommendations
    • Click Apply PIDs to apply changes

Optional: Verification Hover

  1. After PID apply, the banner offers an optional verification hover (30s gentle hover)
  2. If flown, the app compares before/after noise spectra with a dB delta indicator

The session shows a completion summary with all applied changes, noise metrics, and PID response data. You can start a new tuning cycle to iterate further. Past sessions are archived in the Tuning History panel on the dashboard.

4. Quick Analysis (No Tuning Session)

If you just want to analyze a log without applying changes:

  1. Connect FC and download a Blackbox log
  2. Click Analyze on any downloaded log (without starting a tuning session)
  3. Opens a read-only Analysis Overview β€” shows both filter and PID analysis on a single page
  4. No Apply buttons β€” purely informational, great for reviewing flight data

5. Managing Snapshots

Snapshots capture the FC's full CLI configuration at a point in time.

  • Baseline β€” Auto-created on first connection, cannot be deleted
  • Manual β€” Create anytime via "Create Snapshot" button with optional label
  • Auto (safety) β€” Created automatically before applying tuning changes
  • Compare β€” Click to see GitHub-style diff between snapshots
  • Restore β€” Roll back to any snapshot (creates a safety backup first, sends CLI commands, reboots FC)
  • Export β€” Download as .txt file

6. Exporting Configuration

The FC Info panel provides two export options:

  • Export CLI Diff β€” Only changed settings (recommended for sharing/backup)
  • Export CLI Dump β€” Full configuration dump

7. Blackbox Storage Management

The Blackbox Storage panel shows flash usage and downloaded logs:

  • Download β€” Downloads all flight data from FC flash to local storage
  • Erase Flash β€” Permanently deletes all data from FC flash (required before each test flight)
  • Test Read β€” Diagnostic tool to verify FC flash communication
  • Open Folder β€” Opens the local log storage directory

During an active tuning session, Blackbox actions are driven by the status banner (single point of action).

Troubleshooting

Port Access Issues

macOS/Linux:

sudo chmod 666 /dev/ttyUSB0  # or your port

Windows:

  • Install STM32 VCP drivers
  • Check Device Manager for COM port

Rebuild Native Modules

If serialport doesn't work after installation:

npm run rebuild

Connection Timeout

  • Ensure FC is powered on
  • Check USB cable (data cable, not charge-only)
  • Try different USB port
  • Restart the application

FC Not Detected

  • Verify FC is in MSP mode (not CLI or DFU)
  • Check Betaflight Configurator can connect
  • Install proper USB drivers

"FC not responding to MSP commands"

  • Caused by reconnecting too quickly after disconnect
  • Wait for the 3-second cooldown timer, then retry
  • If persistent, physically unplug and replug the USB cable

MSP Protocol

The app uses the MultiWii Serial Protocol (MSP) v1 to communicate with Betaflight:

  • MSP_API_VERSION - Get API version
  • MSP_FC_VARIANT / MSP_FC_VERSION - Firmware identification
  • MSP_BOARD_INFO - Board and target information
  • MSP_UID - Unique FC serial number (for profile matching)
  • MSP_PID / MSP_SET_PID - Read/write PID configuration
  • MSP_FILTER_CONFIG - Read current filter settings
  • MSP_PID_ADVANCED - Read feedforward configuration (boost, gains, smoothing, jitter, transition)
  • MSP_DATAFLASH_SUMMARY - Flash storage information
  • MSP_DATAFLASH_READ - Download Blackbox data
  • MSP_DATAFLASH_ERASE - Erase flash storage
  • CLI Mode - For configuration export, snapshot restore, and filter tuning

Configuration Storage

All data is stored locally per platform:

  • macOS: ~/Library/Application Support/bfautotune/data/
  • Windows: %APPDATA%/bfautotune/data/
  • Linux: ~/.config/bfautotune/data/

Subdirectories:

  • profiles/ β€” Drone profile JSON files + metadata index
  • snapshots/ β€” Configuration snapshot JSON files
  • blackbox/ β€” Downloaded Blackbox log files (.bbl)
  • tuning/ β€” Tuning session state files (per profile)
  • tuning-history/ β€” Archived tuning records (per profile)

How Autotuning Works

Betaflight PID AutoTune automates the two core aspects of FPV drone tuning: filter tuning (reducing noise) and PID tuning (improving flight response). Both use Blackbox log analysis to produce data-driven recommendations.

Filter Tuning (FFT Analysis)

The filter tuning pipeline analyzes gyro noise to determine optimal lowpass filter cutoff frequencies.

Pipeline: SegmentSelector β†’ FFTCompute β†’ NoiseAnalyzer β†’ FilterRecommender

  1. Segment selection β€” Identifies stable hover segments from throttle and gyro data, excluding takeoff, landing, and aggressive maneuvers
  2. FFT computation β€” Applies Welch's method (Hanning window, 50% overlap, 4096-sample windows) to compute power spectral density for each axis
  3. Noise analysis β€” Estimates the noise floor (lower quartile), detects prominent peaks (>6 dB above local floor), and classifies noise sources:
    • Frame resonance (80–200 Hz)
    • Motor harmonics (equally-spaced peaks)
    • Electrical noise (>500 Hz)
  4. Filter recommendation β€” Maps the measured noise floor (dB) to a target cutoff frequency (Hz) via linear interpolation between safety bounds

Filter Safety Bounds

Filter Min Cutoff Max Cutoff (no RPM) Max Cutoff (with RPM) Source
Gyro LPF1 75 Hz 300 Hz 500 Hz BF Tuning Guide: 50 Hz = "very noisy", 80 Hz = "slightly noisy"; 75 Hz is a conservative midpoint
D-term LPF1 70 Hz 200 Hz 300 Hz BF Filtering Wiki: "70–90 Hz range" for D-term

The minimum cutoffs are derived from the official Betaflight guides. The maximum cutoffs represent the point where further relaxation provides negligible latency benefit. With RPM filter active, maximums are raised because 36 per-motor notch filters already handle motor noise, so the lowpass can afford to be more relaxed.

Noise-Based Targeting (Linear Interpolation)

The cutoff target is computed from the worst-case noise floor across roll and pitch axes (dB), mapped linearly to the cutoff range:

t = (noiseFloorDb - (-10)) / ((-70) - (-10))
targetHz = minHz + t Γ— (maxHz - minHz)
Noise Floor (dB) Meaning Gyro LPF1 Target D-term LPF1 Target
-10 dB (very noisy) Extreme vibration/noise 75 Hz (min) 70 Hz (min)
-40 dB (moderate) Typical mid-range quad ~188 Hz ~135 Hz
-70 dB (very clean) Pristine signal 300 Hz (max) 200 Hz (max)

The -10 dB and -70 dB anchor points are calibrated from real Blackbox logs across various frame sizes (3"–7"). This is our own interpolation method β€” not a community standard β€” designed to produce convergent (idempotent) recommendations: same noise data always produces the same target, regardless of current settings.

Filter Decision Table

Rule Trigger Condition Action Confidence Source / Rationale
Noise floor β†’ lowpass Overall noise = high or low Set gyro/D-term LPF1 to noise-based target High (noisy) / Medium (clean) Linear interpolation from BF guide bounds (see above)
Dead zone |target βˆ’ current| ≀ 5 Hz No change recommended β€” Prevents micro-adjustments that add no real benefit
Resonance peak β†’ cutoff Peak β‰₯ 12 dB above local floor AND below current cutoff Lower cutoff to peakFreq βˆ’ 20 Hz (clamped to bounds) High Strong resonance passing through the filter must be blocked
Disabled gyro LPF + resonance gyro_lpf1 = 0 (disabled) AND resonance peak detected Enable gyro LPF1 at peakFreq βˆ’ 20 Hz High Common BF 4.4+ config with RPM filter; re-enable when needed
Dynamic notch range Peak below dyn_notch_min_hz Lower dyn_notch_min to peakFreq βˆ’ 20 Hz (floor: 50 Hz) Medium Notch can't track peaks outside its configured range
Dynamic notch range Peak above dyn_notch_max_hz Raise dyn_notch_max to peakFreq + 20 Hz (ceiling: 1000 Hz) Medium Same as above, upper bound
RPM β†’ notch count RPM filter active AND dyn_notch_count > 1 Reduce dyn_notch_count to 1 High Motor noise handled by RPM notches; fewer dynamic notches = less CPU + latency
RPM β†’ notch Q RPM filter active AND dyn_notch_q < 500 Raise dyn_notch_q to 500 High Only frame resonances remain; narrower notch = less signal distortion
RPM motor diagnostic RPM filter active AND motor harmonics still detected (β‰₯ 12 dB) Warning: check motor_poles / ESC telemetry Medium Motor harmonics should not exist with working RPM filter
Deduplication Multiple rules target same setting Keep more aggressive value, upgrade confidence β€” Ensures a single coherent recommendation per setting

RPM filter awareness: When the RPM filter is active (detected via MSP or BBL headers), the recommender widens safety bounds because motor noise is already handled by the 36 narrow notch filters tracking motor frequencies. It also recommends dynamic notch optimization (count 3β†’1, Q 300β†’500) since only frame resonances remain. If motor harmonics are still detected with RPM active, a diagnostic warns about possible motor_poles misconfiguration or ESC telemetry issues.

Filter Methodology Sources

Source What We Use From It
Betaflight PID Tuning Guide Gyro LPF1 cutoff range (50–80 Hz for noisy quads), general filtering philosophy
BF Filtering Wiki D-term LPF1 "70–90 Hz" recommendation, dynamic notch configuration
BF Configurator RPM-aware max cutoffs (verified against Configurator auto-adjust behavior)
Oscar Liang: PID Filter Tuning Blackbox-based filter tuning workflow, noise floor interpretation
PIDtoolbox Spectral analysis methodology, noise floor percentile approach
Real Blackbox logs (3"–7" quads) Calibration of -10 dB / -70 dB noise anchor points

PID Tuning (Step Response Analysis)

PID tuning works by detecting sharp stick inputs ("steps") in the Blackbox log and measuring how the drone's gyro (actual rotation) tracks the pilot's command (setpoint).

Pipeline: StepDetector β†’ StepMetrics β†’ PIDRecommender

Step 1: Detect Step Inputs

A "step" is a rapid, decisive stick movement. The detector scans setpoint data for each axis (roll, pitch, yaw):

  1. Compute the setpoint derivative at each sample
  2. Flag samples where |derivative| > 500 deg/s/s as potential step edges
  3. Group consecutive high-derivative samples into a single edge
  4. Validate each candidate:
    • Minimum magnitude: step must be β‰₯ 100 deg/s
    • Hold time: setpoint must hold near the new value for β‰₯ 50 ms (not just a transient spike)
    • Cooldown: at least 100 ms gap between consecutive steps (avoids rapid stick reversals)

Step 2: Measure Response Metrics

For each valid step, the algorithm extracts a 300 ms response window and computes:

Metric Definition How It's Measured
Rise time How fast the drone responds Time from 10% to 90% of final gyro value
Overshoot How much gyro exceeds the target Peak deviation beyond steady-state, as % of step magnitude
Settling time How quickly oscillations die out Last time gyro exits the Β±2% band around steady-state
Latency Delay before first movement Time until gyro moves >5% of step magnitude from baseline
Ringing Post-step oscillation count Zero-crossings around steady-state, counted as full cycles

These metrics follow standard control theory definitions (consistent with MATLAB stepinfo).

Step 3: Generate PID Recommendations

The recommendation engine applies rule-based tuning logic anchored to the PID values from the Blackbox log header (the PIDs that were active during the flight). This anchoring makes recommendations convergent β€” applying them and re-analyzing the same log produces no further changes.

Decision Table:

The thresholds below show the Balanced (default) values. These adapt based on the pilot's flight style preference (set in the profile):

Threshold Smooth Balanced Aggressive
Overshoot ideal 3% 10% 18%
Overshoot max 12% 25% 35%
Settling max 250 ms 200 ms 150 ms
Ringing max 1 cycle 2 cycles 3 cycles
Moderate overshoot 8% 15% 25%
Sluggish rise time 120 ms 80 ms 50 ms

Decision Table (Balanced thresholds shown):

Condition Action Step Size Confidence Rationale
Overshoot > 25% (severity 1–2Γ—) Increase D +5 High D-term dampens bounce-back (Betaflight guide)
Overshoot > 25% (severity 2–4Γ—) Increase D +10 High Proportional step for faster convergence
Overshoot > 25% (severity > 4Γ—) Increase D +15 High Extreme overshoot needs aggressive dampening
Overshoot > 25% AND (severity > 2Γ— OR D β‰₯ 60% of max) Also decrease P -5 / -10 High D alone insufficient at extreme overshoot
Overshoot 15–25% Increase D +5 Medium Moderate overshoot, D-first strategy
Overshoot < 10% AND rise time > 80 ms Increase P +5 Medium Sluggish response needs more authority (FPVSIM)
Ringing > 2 cycles Increase D +5 Medium Oscillation = underdamped response
Settling > 200 ms AND overshoot < 15% Increase D +5 Low Slow convergence, may have other causes

Yaw axis uses relaxed thresholds (1.5x overshoot limit, 1.5x sluggish threshold).

Safety Bounds:

Parameter Min Max
P gain 20 120
D gain 15 80
I gain 30 120

Key design decisions:

  • D-first strategy for overshoot β€” Increasing D (dampening) is always the first action. P is only reduced as a supplement when overshoot is extreme (>2Γ— threshold) or D is already near its ceiling (β‰₯60% of max). This is safer for beginners because lowering P too aggressively can make the drone feel unresponsive.
  • Proportional step sizing β€” Step sizes scale with overshoot severity: Β±5 for mild issues (baseline, consistent with FPVSIM guidance), Β±10 for significant overshoot (2–4Γ— threshold), and Β±15 for extreme cases (>4Γ— threshold). This reduces the number of tuning flights needed while staying within safety bounds. All changes are clamped to safe min/max ranges (P: 20–120, D: 15–80).
  • Flight-PID anchoring β€” Recommendations target values relative to the PIDs recorded in the Blackbox header, not the FC's current values. This prevents recommendation drift when PIDs are changed between flights and log analysis.
  • Feedforward awareness β€” The recommender detects whether feedforward is active from BBL headers (feedforward_boost > 0). At each step's overshoot peak, it compares |pidF| vs |pidP| magnitude. When overshoot is FF-dominated (FF contributes more than P), the engine skips P/D changes and instead recommends reducing feedforward_boost. This prevents misattributing FF-caused overshoot to P/D imbalance.
  • Flight style adaptation β€” PID thresholds adjust based on the user's profile flight style. Smooth (cinematic) pilots get tighter overshoot tolerances and accept slower response. Aggressive (racing) pilots tolerate more overshoot in exchange for maximum snap. The Balanced default matches the standard thresholds. Style is set per-profile and preset profiles include sensible defaults (e.g., 5" Race β†’ Aggressive).

Interactive Analysis Charts

Analysis results are visualized with interactive SVG charts (Recharts):

  • Spectrum Chart β€” FFT noise spectrum per axis (roll/pitch/yaw), with noise floor reference lines and peak frequency markers. Helps users visually understand where noise lives in the frequency domain.
  • Step Response Chart β€” Overlaid setpoint vs. gyro traces for individual steps, with prev/next navigation and a metrics overlay (overshoot %, rise time, settling time, latency). Shows exactly how the drone tracked each stick input.
  • Axis Tabs β€” Shared roll/pitch/yaw/all tab selector for both chart types.

Charts are integrated directly into the tuning wizard steps (filter analysis and PID analysis) as collapsible sections, open by default.

Safety & Rollback

  • All tuning changes create an automatic safety snapshot before applying
  • One-click rollback to any previous configuration via CLI command replay
  • Safety bounds prevent extreme PID and filter values
  • Plain-English explanations accompany every recommended change

Tuning Methodology Sources

The autotuning rules and thresholds are based on established FPV community practices:

Source Used For
Betaflight PID Tuning Guide P/I/D role definitions, overshoot→D rule, bounce-back diagnostics
FPVSIM Step Response Guide P/D balance via step response graphs, Β±5 step size, baseline values
Oscar Liang: PID Filter Tuning Blackbox-based tuning workflow, PIDToolBox methodology
Plasmatree PID-Analyzer Step response as PID performance metric, deconvolution approach
PIDtoolbox Overshoot 10–15% as ideal range for multirotors
UAV Tech Tuning Principles D-gain as damper, P-gain authority, safety-first approach
Standard control theory (rise time, settling, overshoot definitions) Metric definitions consistent with MATLAB stepinfo

Known Limitations

  • MSP v1 only (v2 support planned)
  • Blackbox analysis supports both onboard flash and SD card storage (SD card uses MSC mode for download)
  • Requires test flights in a safe environment
  • Huffman-compressed Blackbox data not yet supported (rare, BF 4.1+ feature)
  • Feedforward: detection and FF-aware PID recommendations implemented; direct FF parameter tuning (writing feedforward_boost via MSP) not yet supported

Development Roadmap

  • Phase 1: βœ… MSP connection, profiles, snapshots
  • Phase 2: βœ… Blackbox analysis, automated tuning, rollback
  • Phase 2.5: βœ… UX polish β€” profile simplification, interactive analysis charts
  • Phase 3: βœ… Mode-aware wizard, read-only analysis overview, flight guides
  • Phase 4: βœ… Stateful two-flight tuning workflow with smart reconnect, verification flight, tuning history
  • Phase 5: ⬜ Complete manual testing & UX polish (real hardware validation)
  • Phase 6: βœ… CI/CD & cross-platform releases (macOS/Windows/Linux installers)
  • Phase 7a: βœ… Playwright E2E tests (demo mode, 16 tests)
  • Phase 7b: ⬜ E2E tests on real FC in CI pipeline

See SPEC.md for detailed requirements and phase tracking.

License

MIT

Contributing

Contributions welcome! Please open an issue first to discuss changes.

About

Betaflight PID AutoTune - application that takes the guesswork out of FPV drone tuning 😀

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages