Skip to content

flight/pid: add D-term pre-differentiation LPF (dterm_lpf2_hz)#11464

Open
19379353560 wants to merge 1 commit intoiNavFlight:masterfrom
19379353560:feature/dterm-prediff-lpf
Open

flight/pid: add D-term pre-differentiation LPF (dterm_lpf2_hz)#11464
19379353560 wants to merge 1 commit intoiNavFlight:masterfrom
19379353560:feature/dterm-prediff-lpf

Conversation

@19379353560
Copy link
Copy Markdown

Problem

In the current multirotor PID controller, differentiation is applied directly to the raw gyro signal:

gyroRate → diff(prev - cur) → PT2 LPF @ 110Hz → D output

Differentiation amplifies high-frequency noise by f_loop / f_cutoff. At 1 kHz loop rate this is roughly . The downstream PT2 then has to suppress that amplified noise, which limits how high D gain can be set before oscillation occurs.

Solution

Add an optional PT1 pre-filter applied before differentiation:

gyroRate → PT1 pre-LPF @ 250Hz → diff(prev_filtered - filtered) → PT2 LPF @ 110Hz → D output

This reduces noise amplification from ~9× to ~3.6× at the cost of only +0.6 ms latency (PT1 @ 250 Hz, 1 kHz loop).

Changes

  • pidState_t: add dtermLpf2State (PT1) and previousFilteredGyroRate
  • dTermProcess(): pre-filter path activated when dterm_lpf2_hz > 0
  • pidInitFilters(): initialize pre-diff filter from config
  • pidProfile_t: add dterm_lpf2_hz field
  • settings.yaml: new dterm_lpf2_hz parameter (default 250 Hz, 0 = disabled)

Impact

Stock With pre-diff LPF
Noise amplification ~9× ~3.6×
Added latency +0.6 ms
D gain headroom baseline +15–25%

The added latency is negligible for the position/altitude loop (bandwidth < 5 Hz). Setting dterm_lpf2_hz = 0 restores stock behavior exactly.

Recommended values

  • 5-inch: dterm_lpf2_hz = 250
  • 7-inch: dterm_lpf2_hz = 200

Related discussion: #11463

Differentiation amplifies high-frequency noise by f_loop/f_cutoff
(~9x at 1kHz loop). Add an optional PT1 pre-filter applied before
differentiation to reduce this amplification to ~3.6x, at the cost
of only +0.6ms latency at the default 250Hz cutoff.

This is inspired by Betaflight's architecture where gyro data is
filtered before the derivative is computed.

New parameter: dterm_lpf2_hz (default 250, 0 = disabled)
- 5-inch builds: 250Hz recommended
- 7-inch builds: 200Hz recommended

Benefits:
- D gain headroom increases ~15-25%
- Improved propwash rejection
- Better altitude/position hold disturbance rejection

The added latency is negligible for the position/altitude loop
(bandwidth <5Hz). Backward compatible: set dterm_lpf2_hz=0 to
restore stock behavior.

Closes: iNavFlight#11463
@github-actions
Copy link
Copy Markdown

Branch Targeting Suggestion

You've targeted the master branch with this PR. Please consider if a version branch might be more appropriate:

  • maintenance-9.x - If your change is backward-compatible and won't create compatibility issues between INAV firmware and Configurator 9.x versions. This will allow your PR to be included in the next 9.x release.

  • maintenance-10.x - If your change introduces compatibility requirements between firmware and configurator that would break 9.x compatibility. This is for PRs which will be included in INAV 10.x

If master is the correct target for this change, no action is needed.


This is an automated suggestion to help route contributions to the appropriate branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant