dynpower: describe the adaptive SNR thresholds - #548
Draft
MUSTARDTIGERFPV wants to merge 1 commit into
Draft
Conversation
The Dynamic Power and Signal Health pages both described the fixed per-rate SNR thresholds as the whole algorithm. Since 4.0 those values are only the starting point. The TX keeps a 48 sample window of the SNR reported by the RX and derives both thresholds from its mean and standard deviation. - Lower power at mean + 0.5 x standard deviation in 4.1. - Raise power at mean - (scale x standard deviation), where scale runs from 3.25 at 100% LQ down to a floor of 0.25 at 85% LQ, and the raise threshold is held at least 1dB below the lower threshold. - Samples are only collected while instantaneous LQ is 99% or higher, and the window is cleared on a packet rate change. - Raising on SNR also requires the signal to be weak, and can add more than one power level per telemetry update. Expand Starting Power. Dropping to the minimum power is done by ResetPower(), which also runs after a committed configuration change, not only at power up. It deliberately does not lower the power while armed, and with Dynamic Power disabled it sets the configured Max Power instead. Document the receiver overload protection. An RSSI of -5dBm or higher lowers the power one level, and this runs even when Dynamic Power is disabled, which is a common source of confusion on the bench. Also correct two values in the Signal Health tables that did not match the rate tables in common.cpp: - 2.4GHz 250Hz lower power is 9.5dB, not 8.5dB. The Dynamic Power page already said 9.5dB, so the two pages disagreed. - 900MHz 50Hz raise power is -1.0dB, not 1.0dB. Three boundary conditions were stated as strict inequalities but are inclusive in the code: the 50% LQ hard limit, the 85% LQ top up, and the FLRC lower power RSSI limit.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Dynamic Power and Signal Health pages both present the fixed per-rate SNR thresholds as the whole algorithm. Since 4.0 those values are only the starting point, so both pages describe behavior the firmware no longer has.
The algorithm
The TX keeps a 48 sample window (
StdevAccumulator.h,WINDOW_SIZE = 48) of the SNR reported by the receiver and derives both thresholds from its mean and standard deviation.mean + 0.5 x stdevdynpower.cpp,(snr_stat_mean + (snr_stat_stdev / 2)) / 16mean - (scale x stdev)dynpower.cpp,(snr_stat_mean - (snr_stat_stdev * scale_factor_numerator) / 4) / 16scaleis 3.25 at 100% LQ, floors at 0.25 from 85% LQ downstd::max(..., 1), over 4snr_thre_up_limit = snr_thre_dn_scaled - SNR1dBif (lq_current >= 99) dynpower_stat_snr.add(snrScaled)dynpower_stat_snr.reset()on RF index changerssi <= sens + 21 || lq_avg <= 95whileloop withsnrScaled += SNR_SCALE(2)The
0.5coefficient is 4.1 specific; 4.0 used1.5. The page is worded to scope this.Signal Health table corrections
Two cells did not match the rate tables in
common.cpp:SNR_SCALE(9.5). The Dynamic Power page already said 9.5dB, so the two pages contradicted each other.SNR_SCALE(-1).The other ten cells were checked against the rate tables and are correct. The table intro now says these are starting thresholds and links to the algorithm.
Starting Power
The existing claim is correct but incomplete. Dropping to minimum power is done by
ResetPower(), which also runs after a committed configuration change, not only at power up. It deliberately does not lower the power while armed, and with Dynamic Power disabled it applies the configuredMax Powerinstead.Receiver overload protection
Not previously documented. An RSSI of -5dBm or higher lowers the power one level, and this check sits above the
if (!config.GetDynamicPower()) return;guard, so it runs even with Dynamic Power disabled. This is a common source of confusion on the bench.Smaller fixes
Three boundary conditions were written as strict inequalities but are inclusive in code: the 50% LQ hard limit, the 85% LQ top up, and the FLRC lower power RSSI limit.