Skip to content

flight/pid,sensors/gyro: D-term pre-diff LPF + code quality improvements#11465

Open
19379353560 wants to merge 3 commits intoiNavFlight:maintenance-9.xfrom
19379353560:feature/gyro-pid-v2-for-pr
Open

flight/pid,sensors/gyro: D-term pre-diff LPF + code quality improvements#11465
19379353560 wants to merge 3 commits intoiNavFlight:maintenance-9.xfrom
19379353560:feature/gyro-pid-v2-for-pr

Conversation

@19379353560
Copy link
Copy Markdown

Summary

Combines the D-term pre-differentiation LPF optimization with follow-up code quality improvements.

Part 1: D-term pre-differentiation LPF

Filters gyro before differentiation instead of after, reducing noise amplification.

Metric Before After
Noise amplification ~9× ~3.6×
Added latency +0.6ms
D-gain headroom baseline +15–25%

Files changed:

  • pid.h: add dterm_lpf2_hz to pidProfile_t
  • pid.c: add dtermLpf2State / previousFilteredGyroRate to pidState_t, initialize and apply in pidInitFilters() / dTermProcess()
  • settings.yaml: add dterm_lpf2_hz parameter (default 250Hz, range 0–500)

Part 2: Code quality improvements

  • dTermProcess: early return when kD==0, remove redundant newDTerm variable
  • pidInitFilters: merge 3 separate axis loops into 1, extract const float dT = US2S(refreshRate)
  • pidApplyMulticopterRateController: factor out antiWindupScaler*dT from I-term update
  • Add const to itermLimit in both FW and MC rate controllers
  • gyroFilter: rename preLulupreFilterGyro, add const

Test plan

  • Build MATEKH743: compiles cleanly, zero errors
  • Run unit tests: make check

艾多多 added 2 commits March 31, 2026 01:43
- dTermProcess: early return when kD==0, remove redundant variable
- pidInitFilters: merge 3 init loops into 1, extract common US2S(refreshRate) subexpression
- pidApplyMulticopterRateController: factor out antiWindupScaler*dT from I-term update
- gyroFilter: rename preLulu to preFilterGyro, add const
- pidApplyFixedWingRateController/pidApplyMulticopterRateController: add const to itermLimit

No behavior change. All modifications are structural/readability improvements.
…ments

Pre-differentiation LPF (v1, from master):
- pid.h: add dterm_lpf2_hz field to pidProfile_t
- pid.c: add dtermLpf2State and previousFilteredGyroRate to pidState_t
- pid.c: initialize pre-diff filter in pidInitFilters()
- pid.c: apply pre-diff filter in dTermProcess() before differentiation
- settings.yaml: add dterm_lpf2_hz parameter (default 250Hz, range 0-500)

Code quality improvements (v2):
- dTermProcess: early return when kD==0, remove redundant newDTerm variable
- pidInitFilters: merge 3 axis loops into 1, extract common dT subexpression
- pidApplyMulticopterRateController: factor out antiWindupScaler*dT
- Add const to itermLimit in both FW and MC rate controllers
- gyroFilter: rename preLulu to preFilterGyro, add const

Noise reduction: diff amplification ~9x -> ~3.6x, latency +0.6ms at 1kHz.
@19379353560
Copy link
Copy Markdown
Author

Hi, just wanted to kindly ping this PR for review. This builds on the D-term pre-differentiation LPF work in #11464 with additional code quality improvements. Would appreciate any feedback from the maintainers when you have a chance. Thanks!

@github-actions
Copy link
Copy Markdown

Test firmware build ready — commit cf3ff81

Download firmware for PR #11465

228 targets built. Find your board's .hex file by name on that page (e.g. MATEKF405SE.hex). Files are individually downloadable — no GitHub login required.

Development build for testing only. Use Full Chip Erase when flashing.

@sensei-hacker
Copy link
Copy Markdown
Member

sensei-hacker commented Apr 18, 2026

Thanks for this.

One thing in the code that I wonder about.

previousFilteredGyroRate is not reset on filter re-init — if pidInitFilters() is called with the feature transitioning from disabled→enabled (such as a VTOL mid-flight profile change), the stale zero causes a short D-term spike scaled by kD × dT_inv × gyroRate. At 1kHz that multiplier is 1000 — potentially significant.

Then we need some folks to flight test it.

I think the default post filter is 110 Hz, doubling the filter frequency may have other effects different from the core of this change, right?

Speaking of the default, would it make sense to SETTING_DTERM_LPF2_HZ_DEFAULT rather than hard-coding 250, so that settings.yaml is the single source of truth?

But we'd probably default it to zero (disabled), at least for a release cycle.

@19379353560 19379353560 force-pushed the feature/gyro-pid-v2-for-pr branch from d0bacbe to bdc2d95 Compare April 19, 2026 07:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants