DEV Community

FPVtune
FPVtune

Posted on

I built an auto PID tuning tool for Betaflight — here's how it works under the hood

I fly FPV drones as a hobby, and if you've ever tried to tune Betaflight PIDs manually, you know the pain. Fly a pack, check blackbox logs, tweak one number, fly again, repeat for hours. I got tired of it and decided to build something to automate the process.

The problem

Betaflight doesn't have a real autotune feature (unlike iNav or Ardupilot). The closest thing we had was PIDtoolbox, which is great for visualizing blackbox data but doesn't actually tell you what to change. You still need to know what you're looking at.

Most pilots either:

  • Copy someone else's PIDs and hope for the best
  • Spend weekends doing test flights and manual tuning
  • Pay someone to tune their quad

None of these are great options.

What I built

FPVtune — a web-based tool that reads your Betaflight blackbox logs and generates optimized PID settings using a neural network.

The basic flow:

  1. Record a blackbox log (just fly normally for 30 seconds)
  2. Upload the .bbl or .bfl file to fpvtune.com
  3. Get back a full set of PID and filter recommendations

No install needed, works in the browser.

How it works under the hood

Here's the interesting part for the dev crowd.

Blackbox parsing

Betaflight blackbox logs are binary files with a custom format. I wrote a Python parser that extracts gyro data, motor outputs, setpoint, PID controller outputs (P/I/D terms), and RC commands at the logged sample rate (usually 2kHz for gyro, 500Hz-1kHz for PID).

The tricky part is handling different Betaflight versions — the log format has changed across versions, and there are edge cases with corrupt logs, partial writes (battery died mid-flight), and different logging rates.

Signal analysis

Once parsed, the raw data goes through several analysis steps:

# Simplified version of the analysis pipeline
def analyze_axis(gyro, setpoint, pid_p, pid_d, motor, axis='roll'):
    # Step response analysis - how fast does the quad respond?
    step_response = compute_step_response(setpoint, gyro)

    # Noise floor analysis - where is the noise?
    noise_spectrum = np.fft.rfft(gyro)
    noise_floor = estimate_noise_floor(noise_spectrum)

    # Prop wash detection - oscillations after throttle changes
    throttle_events = detect_throttle_cuts(motor)
    propwash_severity = measure_oscillation(gyro, throttle_events)

    # D-term noise vs effectiveness tradeoff
    d_noise = rms(highpass(pid_d, cutoff=100))
    d_effectiveness = correlation(pid_d, gyro_error_derivative)

    return AnalysisResult(step_response, noise_floor, 
                          propwash_severity, d_noise, d_effectiveness)
Enter fullscreen mode Exit fullscreen mode

The key metrics I extract:

  • Step response delay — how many ms between stick input and quad response
  • Overshoot — does the quad overshoot the target angle?
  • Noise floor by frequency — where is motor/prop noise showing up?
  • Prop wash severity — how bad are the oscillations after throttle blips?
  • D-term noise ratio — is D actually helping or just adding noise?

The neural network

The model takes these extracted features and predicts optimal PID values. It was trained on a dataset of ~2000 blackbox logs with known "good" tunes (collected from experienced FPV pilots who shared their logs and final PID values).

The architecture is pretty simple — a feed-forward network with 3 hidden layers. Nothing fancy. The hard part was building the training dataset, not the model itself.

Input (28 features) → Dense(128, ReLU) → Dense(64, ReLU) → Dense(32, ReLU) → Output (18 PID values)
Enter fullscreen mode Exit fullscreen mode

The 18 outputs cover P, I, D for roll/pitch/yaw, plus filter settings (gyro lowpass, D-term lowpass, notch filters).

Why not just use rules?

I actually started with a rule-based system ("if noise is high, lower D; if response is slow, raise P"). It worked okay for simple cases but fell apart with edge cases — like when you have both high noise AND slow response, which means the filters are too aggressive and you need to fix those first before touching PIDs.

The neural network handles these multi-variable interactions much better than hand-written rules.

Tech stack

  • Backend: Python, FastAPI
  • Frontend: React
  • Blackbox parser: Custom Python (no existing library handled all the edge cases)
  • ML: PyTorch for training, ONNX for inference
  • Database: PostgreSQL

The whole thing is open source on GitHub.

Results so far

I've been testing it on my own quads (5" freestyle, 3" cinewhoop, 7" long range) and the results have been surprisingly good. Prop wash handling improved noticeably on my freestyle build without me having to think about filter settings at all.

It's not perfect — it sometimes suggests filter settings that are too aggressive on noisy builds, and it doesn't handle RPM filtering tuning yet. But for getting a solid baseline tune, it saves hours of manual work.

Try it out

The tool is live at fpvtune.com. It costs $9.90 for a full analysis, but I have a beta test code if you want to try it free:

Code: FPVTUNE-BETA-2026 (limited uses)

Just upload your blackbox log, and on the payment page expand the "Activation Code" section and enter the code.

I'd love feedback from other pilots and devs. If you fly FPV and have blackbox logs lying around, give it a shot and let me know how the suggestions compare to your current tune.


If you're interested in the technical details of blackbox log parsing or the training pipeline, I'm happy to write a follow-up post going deeper into either topic. Drop a comment!

Top comments (0)