MS/BS Power Control Loop: Fix downscaling averaging bug

The bug showed up in previous commit and is fixed in this commit. It can
be seen how rounding error is carried over time in the average
measurement, and affects final values.

Change-Id: I680d1c94bd4bae179b14b26662a819fa1462a5c8
This commit is contained in:
Pau Espin 2021-09-02 21:29:44 +02:00
parent aac12bfd67
commit e0febb700a
4 changed files with 11 additions and 9 deletions

View File

@ -36,6 +36,8 @@
/* We don't want to deal with floating point, so we scale up */
#define EWMA_SCALE_FACTOR 100
/* EWMA_SCALE_FACTOR/2 = +50: Round to nearest value when downscaling, otherwise floor() is applied. */
#define EWMA_ROUND_FACTOR (EWMA_SCALE_FACTOR / 2)
/* Base Low-Pass Single-Pole IIR Filter (EWMA) formula:
*
@ -84,8 +86,8 @@ static int do_pf_ewma(const struct gsm_power_ctrl_meas_params *mp,
return Val;
}
*Avg100 += A * (Val - *Avg100 / EWMA_SCALE_FACTOR);
return *Avg100 / EWMA_SCALE_FACTOR;
*Avg100 += A * (Val - (*Avg100 + EWMA_ROUND_FACTOR) / EWMA_SCALE_FACTOR);
return (*Avg100 + EWMA_ROUND_FACTOR) / EWMA_SCALE_FACTOR;
}
/* Calculate target RxLev value from lower/upper thresholds */

View File

@ -204,11 +204,11 @@ static void test_pf_algo_ewma(void)
/* Avg[t] = (0.2 * 40) + (0.8 * 29.60) = RXLEV 31.68 (-78.32 dBm),
* but due to up-/down-scaling artefacts we get the following:
* Avg100[t] = Avg100[t - 1] + A * (Pwr - Avg[t] / 100)
* Avg100[t] = 2960 + 20 * (40 - (2960 / 100))
* Avg100[t] = 2960 + 20 * (40 - 29)
* Avg[t] = 3180 / 100 = 31.80 */
* Avg100[t] = 2960 + 20 * (40 - ((2960+50) / 100)) <- HERE we lose 0.1: (2960+50) / 100) = 30.1
* Avg100[t] = 2960 + 20 * (40 - 30) <- HERE we lose 20*0.1 = 2.0! (upscaled, hence we lose finally 2.0/100=0.2)
* Avg[t] = (3160) / 100 = 31.60*/
apply_power_test(lchan, -70, good_lqual, 1, 9); /* RXLEV 40 */
CHECK_RXLEV_AVG100(31.80);
CHECK_RXLEV_AVG100(31.60);
mp->ewma.alpha = 70; /* 30% smoothing */
lchan->ms_power_ctrl.current = 15;

View File

@ -23,8 +23,8 @@
(bts=0,trx=0,ts=0,ss=0) Lowering MS power control level 14 (2 dBm) => 15 (0 dBm): ms-pwr-lvl[curr 14, max 0], RSSI[curr -40, avg -47, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB
(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 15 (0 dBm): ms-pwr-lvl[curr 15, max 2], RSSI[curr -75, avg -75, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB
(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 15 (0 dBm) => 13 (3 dBm): ms-pwr-lvl[curr 15, max 2], RSSI[curr -90, avg -78, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB
(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 13 (4 dBm) => 11 (8 dBm): ms-pwr-lvl[curr 13, max 2], RSSI[curr -90, avg -81, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB
(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 11 (8 dBm) => 9 (12 dBm): ms-pwr-lvl[curr 11, max 2], RSSI[curr -70, avg -79, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB
(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 13 (4 dBm) => 11 (8 dBm): ms-pwr-lvl[curr 13, max 2], RSSI[curr -90, avg -80, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB
(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 11 (8 dBm) => 9 (11 dBm): ms-pwr-lvl[curr 11, max 2], RSSI[curr -70, avg -78, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB
(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 15 (0 dBm): ms-pwr-lvl[curr 15, max 2], RSSI[curr -50, avg -50, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB
(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 15 (0 dBm): ms-pwr-lvl[curr 15, max 2], RSSI[curr -50, avg -50, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB
(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 15 (0 dBm) => 13 (4 dBm): ms-pwr-lvl[curr 15, max 2], RSSI[curr -110, avg -92, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB

View File

@ -62,7 +62,7 @@ lchan_ms_pwr_ctrl(RxLvl=-90 dBm) returns 1 (expected 1)
Avg[t] is RxLev 29.60 (expected 29.60)
lchan_ms_pwr_ctrl(RxLvl=-70 dBm) returns 1 (expected 1)
MS current power 11 -> 9 (expected 9)
Avg[t] is RxLev 31.80 (expected 31.80)
Avg[t] is RxLev 31.60 (expected 31.60)
lchan_ms_pwr_ctrl(RxLvl=-50 dBm) returns 0 (expected 0)
MS current power 15 -> 15 (expected 15)
Avg[t] is RxLev 60.00 (expected 60.00)