Skip to content

Experimental: Use fast_powf instead of powf for better performance in PID#11408

Open
DzikuVx wants to merge 5 commits into
maintenance-10.xfrom
dzikuvx-pid-fast_pow
Open

Experimental: Use fast_powf instead of powf for better performance in PID#11408
DzikuVx wants to merge 5 commits into
maintenance-10.xfrom
dzikuvx-pid-fast_pow

Conversation

@DzikuVx
Copy link
Copy Markdown
Member

@DzikuVx DzikuVx commented Mar 7, 2026

No description provided.

@sensei-hacker
Copy link
Copy Markdown
Member

sensei-hacker commented Mar 7, 2026

Interesting.

I see it compiles to about 75 instructions vs roughly 380 instructions on ARM.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new fast_powf() approximation in the common math utilities and switches fixed-wing airspeed-based PID attenuation (TPA) calculations to use it instead of powf(), aiming to improve runtime performance in the PID loop.

Changes:

  • Add fast_powf() to src/main/common/maths.c and expose it via src/main/common/maths.h.
  • Replace powf() with fast_powf() in fixed-wing airspeed TPA and I-term scaling computations in src/main/flight/pid.c.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/main/flight/pid.c Uses fast_powf() for airspeed-based TPA and I-term scaling instead of powf().
src/main/common/maths.h Exposes the new fast_powf() API.
src/main/common/maths.c Implements fast_powf() using a bit-level log2/exp2 approximation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/main/common/maths.c
Comment thread src/main/common/maths.c
Comment on lines +159 to +168
// Convert back to float: 2^result_exp
int32_t result_exp_int = (int32_t)result_exp;
float result_exp_frac = result_exp - (float)result_exp_int;

// Reconstruct float from exponent
u.i = (result_exp_int + 127) << 23;

// Apply fractional part correction using polynomial approximation
// 2^x ≈ 1 + x*(0.69315 + x*(0.24023 + x*0.05550)) for x in [0,1]
float frac_mult = 1.0f + result_exp_frac * (0.69314718f + result_exp_frac * (0.24022650f + result_exp_frac * 0.05550410f));
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

result_exp_frac can be negative when result_exp < 0 (which happens for base<1, common in airspeed scaling). The 2^x polynomial is documented as valid for x in [0,1], but the current int-cast decomposition allows frac outside that domain, which can increase error and introduce discontinuities around integer boundaries. Consider decomposing result_exp using floor (so 0<=frac<1) or otherwise ensuring the polynomial’s input range matches its documented validity.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied in commit 0b0404d. Changed (int32_t)result_exp to (int32_t)floorf(result_exp) so the fractional part is always in [0, 1), ensuring the 2^x polynomial approximation is always evaluated within its valid domain. Also added TestFastPowf unit tests covering base<1 edge cases (where result_exp is negative and fractional), base>1 general cases, special-case short-circuits, and invalid inputs.

Comment thread src/main/common/maths.c
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 31, 2026

Test firmware build ready — commit d0926bd

Download firmware for PR #11408

234 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.

…of negative

Use floorf to calculate integer part of exponent.
@sensei-hacker sensei-hacker added this to the 10.0 milestone May 18, 2026
Copilot AI and others added 2 commits May 18, 2026 03:02
- Use floorf() instead of (int32_t) cast when decomposing result_exp into
  integer and fractional parts. The (int32_t) cast truncates toward zero,
  so for negative result_exp (base<1, common in airspeed TPA scaling)
  the fractional part would be negative, outside the [0,1] domain of the
  2^x polynomial approximation.
- Add TestFastPowf unit test covering special cases, base<1 cases (key
  regression), and base>1 cases with appropriate error tolerances.

Agent-Logs-Url: https://github.com/iNavFlight/inav/sessions/ac361c30-4841-46d4-8d06-d704c02a2f7c

Co-authored-by: sensei-hacker <1971284+sensei-hacker@users.noreply.github.com>
…s and unit tests

Co-authored-by: sensei-hacker <1971284+sensei-hacker@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented May 18, 2026

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • developer.arm.com
    • Triggering command: /usr/local/bin/cmake cmake /home/REDACTED/work/inav/inav -DCMAKE_BUILD_TYPE=Debug -DINAV_TARGET=SITL (dns block)
    • Triggering command: /usr/local/bin/cmake cmake /home/REDACTED/work/inav/inav -DCMAKE_BUILD_TYPE=Debug (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

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.

4 participants