A Tool That Tells You Exactly Which PID Parameters to Change — And My AI Agent Reads It

I Built a Tool That Tells You Exactly Which PID Parameters to Change — And My AI Agent Reads It

Three hours staring at step response graphs manually. Four test flights. That’s what it used to cost me to get a roll axis tuned. Now my agent runs stune analyze flight_15.bin and comes back with exact parameter deltas — while I eat lunch.

pip install smarttune-cli && stune analyze flight_15.bin --platform ardupilot

Every suggestion is capped at ±20%. It tells you what to change, never writes a parameter. You verify, you fly safe.


What’s happening under the hood (and why agents can consume it directly):

SmartTune has a platform abstraction layerPlatformAdapter is an abstract base class with parse(), capabilities(), map_param_to_platform(). ArduPilot .bin, Betaflight .bbl (parsed by a 1000+ line pure-Python decoder that handles I/P/S/E frame types, variable-byte encoding, Elias delta predictors), and PX4 .ulg all feed into one FlightData dataclass. Every analyzer only reads FlightData. Adding a new platform means writing one adapter, not touching any analysis code.

The core algorithms:

  • Step response: On ArduPilot, SmartTune replicates the WebTools PIDReview.js pipeline exactly — Hanning-windowed FFT → single-to-double-sided spectral conversion → SNR regularization via cumulative Gaussian integral → Wiener deconvolution (H = Pyx / (Pxx + sn)) → per-window step averaging with 93.75% overlap. On low sample-rate data (<20Hz, common in real APM logs), it falls back to a time-domain step extractor — detects step edges via first-order differences, normalizes per-step-by-amplitude, averages windows in the time domain. Both paths output the same signal shape so downstream analysis is identical.

  • Vibration: 3-axis independent Welch FFT (Hanning window) → max envelope across axes — this preserves per-axis peak features rather than collapsing into an L2-norm that smears motor peaks into DC. Peak detection uses median-based noise floor estimation + 30dB SNR threshold + scipy.find_peaks with 15dB prominence. Source identification maps peak frequencies against KB-defined bands (motor 30-250Hz, prop blade pass 251-400Hz, structural resonance 401-500Hz, high-frequency >500Hz) with harmonic inheritance — a 160Hz peak with a 320Hz harmonic is tagged “motor + 2nd harmonic”, not two separate sources.

  • PID metrics: 10%→90% rise time, overshoot %, settling time (±10% band), zero-crossing oscillation count, steady-state error %. Evaluated against per-axis per-platform thresholds with a weighted scoring function. Each axis gets an EXCELLENT/GOOD/MARGINAL/POOR/UNUSABLE rating.

  • Tuning rules: Knowledge-base-driven, not hardcoded. Each rule defines a symptom → (parameter, action, factor) mapping. “HIGH_OS” → decrease P by ×0.85 and D by ×0.90. “SLOW_RISE” → increase P by ×1.15. Rules are ranked by severity, deduplicated across conflicts (same parameter can’t get two opposing adjustments), clamped to per-axis bounds, and the result is a concrete list of ParamRef objects with current → suggested values.

The knowledge base is programmable. Six layers deep-merge at load time: builtin_commonbuiltin_{platform}~/.smarttune/knowledge/common~/.smarttune/knowledge/{platform}pro_commonpro_{platform}. Thresholds, tuning rules, frequency bands, vibration levels — all in JSON files that agents can read and write. Your agent can modify the tuning rules without touching Python code.

Agent-first from day one:

Feature Why it matters for agents
--format json / --format markdown Agents don’t parse ANSI escape codes
Semantic exit codes (E10xx–E50xx) Agent gets E1001 = file not found, not a wall of text
FlightData dataclass Platform-agnostic input; all analyzers share one contract
ParamRef suggestions Output has exact current → suggested values, not vague “try lowering P”
6-layer programmable KB Agents can read rules and write new ones
±20% cap, read-only Safety constraint baked in at the architecture level
No cloud deps Works in a container, a sandbox, or a tent

My agent workflow (OpenClaw, but any agent framework works):

# Claude Code / Codex / QwenPaw / Hermes / OpenClaw — all the same
result = subprocess.run(["stune", "analyze", "-i", "log.bin", "--platform", "ardupilot"])
if result.returncode == 0:  # E0000 = success
    report = json.load(open("output/analysis.md"))
    # Write diagnostic with per-parameter recommendations

My own agent does this every time I come back from a test flight — reads the stune output, writes a full diagnostic, and tells me “roll P is too low by 15%, suggested ATC_RAT_RLL_P = 0.098.”


I’m Raylan — Monash Malaysia freshman, part of an APM firmware dev group with Nanjing University. I work on ArduPilot firmware daily (ParallelFC multi-FC redundancy, self-learning PID, STM32H743/H753 custom hardware). This tool is built on 2+ years of firmware-level understanding — it knows which ArduPilot parameters exist, how the notch filter chain interacts with the gyro LPF, and what a real motor noise peak looks like vs. a structural resonance.

GitHub: https://github.com/raylanlin/smarttune-cli — MIT, open-source. 309 tests passing.

If this saves your agent even one test flight, :star: it.

1 Like

PID gains are just a small part of the process of safely and correctly configuring a UAS.

Do you plan to extend this tool to cover more of it?

Take a look at the ArduPilot methodic configurator software to find all the other steps that you are missing.

Good PIDs are only possible after filtering.

Good filtering is only possible after correct ESC configuration, etc.

We ArduPilot developers have been explaining this for years, PIDs are just a small part at the end of the configuration process.

This tool might give beginners the wrog idea that this is all the configuration they need. It is not.

And there is QickTune and autotune. Both fully automatic methods.

3 Likes

Fair point — PID is just the start. The scope is intentionally unbounded; the idea is to build the open-source infrastructure layer that agents use for drone tuning, not a one-purpose utility. Vibration health, motor trending, parameter validation from log history — all in scope. Always MIT, always agent-first.

That’s the right dependency chain — filtering before PID, ESC config before filtering. My plan: analysis first (what ships now), then active parameter writing. The end state is an agent calling stune to complete the full loop: analyse → recommend → write → validate. Could integrate with existing Linux-based configurators (Methodic Configurator included) so agents can script end-to-end vehicle setup through one CLI.

1 Like

Or you could run autotune …

2 Likes

No, closer to the end.

If you follow a solid work flow such as AMC, most drones will be tuned in just a few flights, with the PIDs set using quicktune and/or autotune. On a well built and properly configured drone, autotune will produce a very good tune.

I don’t doubt your tool will produce results, but currently I can autotune in one flight and be done. Why would I choose to use an AI tool to iterate my PIDs over multiple flights?

(And if your reply is AI generated or edited …. don’t bother)

1 Like

For a 5" quad I’d run autotune too and be done with it. But for larger platforms — say a 60kg Agras or a custom airframe with non-standard hardware — nobody’s going to risk an in-flight auto-tune loop. If something goes wrong mid-air you can’t just “land and try again.” SmartTune is a read-only reference for an engineer to review before touching parameters. It’s a different workflow for a different risk profile.

In our industrial drone space 150kg+ platforms are already common, and we work on light manned eVTOL. Nobody runs autotune on those. SmartTune is what an engineer reads before touching params — same as using Claude Code to review before commit.

I review tons of logs using AI and despite my expert input it still makes significant mistakes. I would trust autotune any day over AI generated PIDs for a large, dangerous vehicle.

4 Likes

I think the confusion is on what “AI” contributes here. SmartTune’s PID suggestions come from deterministic signal processing — Wiener deconvolution, Welch FFT, rule-based symptom→action mapping. Same input always produces the same output. The model reads structured JSON, not raw logs.

Before SmartTune, asking an AI to analyze flight logs meant eating raw .bin files with zero structure — of course it makes mistakes, it had no systematic data to work with. That’s exactly the gap SmartTune fills. It gives the model quantified, platform-agnostic analysis so the AI can make informed tuning suggestions instead of guessing.

With a proper data pipeline like this, and the capabilities of today’s models — Claude, Codex, DeepSeek-v4 — you get a genuinely

I disagree. Autotune and quick tune can be used with many larger platforms when set up correctly.

Regardless, good luck with your project. Another tool in the tool box is always handy.

2 Likes

I don’t think you will get much traction. The forum has been Crop Dusted with these Tools in recent months. Try the Discord channel

1 Like

You can always try the tool I use if you want - GitHub - fossuav/aap: ArduPilot AI Playbooks · GitHub - it has a /log-analyse skill and does a decent job of identifying problems and recommending solutions. YMMV.

Nice, but you could have changed the title to which currently seems to suggest it uses an AI underneath…

1 Like