Change in osmo-bts[master]: MS/BS Power Control Loop: Do RxLEV meas avg & delta calculations dire...

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

pespin gerrit-no-reply at lists.osmocom.org
Thu Sep 2 18:39:35 UTC 2021


pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bts/+/25328 )


Change subject: MS/BS Power Control Loop: Do RxLEV meas avg & delta calculations directly on RxLevels
......................................................................

MS/BS Power Control Loop: Do RxLEV meas avg & delta calculations directly on RxLevels

Before this comits, averaging and delta calculation was done in RSSI,
but stored the averaging cached state in variables named "rxlev", which
was really confusing. Let's keeping averaging and delta calculations
based on RxLevels.

Some of the tests change results due to test passing RSSI -45, which is
an invalid Rxlev (only up to -47 is supported).

Change-Id: I4cff8394f22b5d47789163051364ff594b2bcd74
---
M src/common/power_control.c
M tests/power/ms_power_loop_test.c
2 files changed, 36 insertions(+), 44 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/28/25328/1

diff --git a/src/common/power_control.c b/src/common/power_control.c
index cb96177..b3066cd 100644
--- a/src/common/power_control.c
+++ b/src/common/power_control.c
@@ -113,22 +113,18 @@
  * to be applied to the current Tx power level to approach the target level. */
 static int calc_delta_rxlev(const struct gsm_power_ctrl_params *params,
 		      struct lchan_power_ctrl_state *state,
-		      const int rxlev_dbm_avg)
+		      const uint8_t rxlev)
 {
-	uint8_t rxlev_avg;
 	int delta;
 
-	/* FIXME: avoid this conversion, accept RxLev as-is */
-	rxlev_avg = dbm2rxlev(rxlev_dbm_avg);
-
 	/* Check if RxLev is within the threshold window */
-	if (rxlev_avg >= params->rxlev_meas.lower_thresh &&
-	    rxlev_avg <= params->rxlev_meas.upper_thresh)
+	if (rxlev >= params->rxlev_meas.lower_thresh &&
+	    rxlev <= params->rxlev_meas.upper_thresh)
 		return 0;
 
 	/* How many dBs measured power should be increased (+) or decreased (-)
 	 * to reach expected power. */
-	delta = CALC_TARGET(params->rxlev_meas) - rxlev_avg;
+	delta = CALC_TARGET(params->rxlev_meas) - rxlev;
 
 	/* Don't ever change more than PWR_{LOWER,RAISE}_MAX_DBM during one loop
 	 * iteration, i.e. reduce the speed at which the MS transmit power can
@@ -183,7 +179,7 @@
 	enum gsm_band band = bts->band;
 	int8_t new_power_lvl; /* TS 05.05 power level */
 	int8_t ms_dbm, new_dbm, current_dbm, bsc_max_dbm;
-	int8_t ul_rssi_dbm_avg;
+	uint8_t rxlev_avg;
 	int16_t ul_lqual_cb_avg;
 	const struct gsm_power_ctrl_meas_params *ci_meas;
 
@@ -221,14 +217,14 @@
 	/* If computed C/I is out of acceptable thresholds: */
 	ci_meas = lchan_get_ci_thresholds(lchan);
 	ul_lqual_cb_avg = do_avg_algo(ci_meas, &state->ci_meas_proc, ul_lqual_cb);
-	ul_rssi_dbm_avg = do_avg_algo(&params->rxlev_meas, &state->rxlev_meas_proc, ul_rssi_dbm);
+	rxlev_avg = do_avg_algo(&params->rxlev_meas, &state->rxlev_meas_proc, dbm2rxlev(ul_rssi_dbm));
 	if (ul_lqual_cb_avg < ci_meas->lower_thresh * 10) {
 		new_dbm = ms_dbm + params->inc_step_size_db;
 	} else if (ul_lqual_cb_avg > ci_meas->upper_thresh * 10) {
 		new_dbm = ms_dbm - params->red_step_size_db;
 	} else {
 		/* Calculate the new Tx power value (in dBm) */
-		new_dbm = ms_dbm + calc_delta_rxlev(params, state, ul_rssi_dbm_avg);
+		new_dbm = ms_dbm + calc_delta_rxlev(params, state, rxlev_avg);
 	}
 
 	/* Make sure new_dbm is never negative. ms_pwr_ctl_lvl() can later on
@@ -252,7 +248,7 @@
 		LOGPLCHAN(lchan, DLOOP, LOGL_INFO, "Keeping MS power at control level %d (%d dBm): "
 			  "ms-pwr-lvl[curr %" PRIu8 ", max %" PRIu8 "], RSSI[curr %d, avg %d, thresh %d..%d] dBm,"
 			  " C/I[curr %d, avg %d, thresh %d..%d] dB\n",
-			  new_power_lvl, new_dbm, ms_power_lvl, state->max, ul_rssi_dbm, ul_rssi_dbm_avg,
+			  new_power_lvl, new_dbm, ms_power_lvl, state->max, ul_rssi_dbm, rxlev2dbm(rxlev_avg),
 			  rxlev2dbm(params->rxlev_meas.lower_thresh), rxlev2dbm(params->rxlev_meas.upper_thresh),
 			  ul_lqual_cb/10, ul_lqual_cb_avg/10, ci_meas->lower_thresh, ci_meas->upper_thresh);
 		return 0;
@@ -264,7 +260,7 @@
 		  " C/I[curr %d, avg %d, thresh %d..%d] dB\n",
 		  (new_dbm > current_dbm) ? "Raising" : "Lowering",
 		  state->current, current_dbm, new_power_lvl, new_dbm, ms_power_lvl,
-		  state->max, ul_rssi_dbm, ul_rssi_dbm_avg,
+		  state->max, ul_rssi_dbm, rxlev2dbm(rxlev_avg),
 		  rxlev2dbm(params->rxlev_meas.lower_thresh), rxlev2dbm(params->rxlev_meas.upper_thresh),
 		  ul_lqual_cb/10, ul_lqual_cb_avg/10, ci_meas->lower_thresh, ci_meas->upper_thresh);
 
@@ -286,8 +282,7 @@
 	const struct gsm_power_ctrl_params *params = state->dpc_params;
 	uint8_t rxqual_full, rxqual_sub;
 	uint8_t rxlev_full, rxlev_sub;
-	uint8_t rxqual, rxqual_avg, rxlev;
-	int8_t dl_rssi_dbm, dl_rssi_dbm_avg;
+	uint8_t rxqual, rxqual_avg, rxlev, rxlev_avg;
 	int new_att;
 
 	/* Check if dynamic BS Power Control is enabled */
@@ -341,8 +336,7 @@
 		rxlev = rxlev_full;
 	}
 
-	dl_rssi_dbm = rxlev2dbm(rxlev);
-	dl_rssi_dbm_avg = do_avg_algo(&params->rxlev_meas, &state->rxlev_meas_proc, dl_rssi_dbm);
+	rxlev_avg = do_avg_algo(&params->rxlev_meas, &state->rxlev_meas_proc, rxlev);
 	rxqual_avg = do_avg_algo(&params->rxqual_meas, &state->rxqual_meas_proc, rxqual);
 	/* If RxQual > L_RXQUAL_XX_P, try to increase Tx power */
 	if (rxqual_avg > params->rxqual_meas.lower_thresh) {
@@ -365,7 +359,7 @@
 		 *   RxLev + Delta = TxPwr - PathLoss -  TxAtt + Delta
 		 *   RxLev + Delta = TxPwr - PathLoss - (TxAtt - Delta)
 		 */
-		new_att = state->current - calc_delta_rxlev(params, state, dl_rssi_dbm_avg);
+		new_att = state->current - calc_delta_rxlev(params, state, rxlev_avg);
 	}
 
 	/* Make sure new TxAtt is never negative: */
@@ -380,7 +374,7 @@
 		LOGPLCHAN(lchan, DLOOP, LOGL_INFO, "Keeping DL attenuation at %u dB: "
 			  "max %u dB, RSSI[curr %d, avg %d, thresh %d..%d] dBm, "
 			  "RxQual[curr %d, avg %d, thresh %d..%d]\n",
-			  state->current,  state->max, dl_rssi_dbm, dl_rssi_dbm_avg,
+			  state->current,  state->max, rxlev2dbm(rxlev), rxlev2dbm(rxlev_avg),
 			  rxlev2dbm(params->rxlev_meas.lower_thresh), rxlev2dbm(params->rxlev_meas.upper_thresh),
 			  rxqual, rxqual_avg, params->rxqual_meas.lower_thresh, params->rxqual_meas.upper_thresh);
 		return 0;
@@ -390,7 +384,7 @@
 		  "max %u dB, RSSI[curr %d, avg %d, thresh %d..%d] dBm, "
 		   "RxQual[curr %d, avg %d, thresh %d..%d]\n",
 		  (new_att > state->current) ? "Raising" : "Lowering",
-		  state->current, new_att, state->max, dl_rssi_dbm, dl_rssi_dbm_avg,
+		  state->current, new_att, state->max, rxlev2dbm(rxlev), rxlev2dbm(rxlev_avg),
 		  rxlev2dbm(params->rxlev_meas.lower_thresh), rxlev2dbm(params->rxlev_meas.upper_thresh),
 		  rxqual, rxqual_avg, params->rxqual_meas.lower_thresh, params->rxqual_meas.upper_thresh);
 	state->current = new_att;
diff --git a/tests/power/ms_power_loop_test.c b/tests/power/ms_power_loop_test.c
index f0c0250..e53cc43 100644
--- a/tests/power/ms_power_loop_test.c
+++ b/tests/power/ms_power_loop_test.c
@@ -185,32 +185,30 @@
 	lchan->ms_power_ctrl.max = ms_pwr_ctl_lvl(GSM_BAND_1800, 26);
 	OSMO_ASSERT(lchan->ms_power_ctrl.max == 2);
 
-#define CHECK_UL_RSSI_AVG100(exp) \
-	printf("\tAvg[t] is %2.2f dBm (expected %2.2f dBm)\n", \
+#define CHECK_RXLEV_AVG100(exp) \
+	printf("\tAvg[t] is RxLev %2.2f (expected %2.2f)\n", \
 	       ((float) *avg100) / 100, exp);
 
 	/* UL RSSI remains constant => no UL power change */
 	apply_power_test(lchan, -75, good_lqual, 0, 15);
-	CHECK_UL_RSSI_AVG100(-75.00);
+	CHECK_RXLEV_AVG100((float)dbm2rxlev(-75)); /* RXLEV 35 */
 
-	/* Avg[t] = (0.2 * -90) + (0.8 * -75) = -78.0 dBm */
-	apply_power_test(lchan, -90, good_lqual, 1, 13);
-	CHECK_UL_RSSI_AVG100(-78.00);
+	/* Avg[t] = (0.2 * 20) + (0.8 * 35) = RXLEV 32, (-78 dBm) */
+	apply_power_test(lchan, -90, good_lqual, 1, 13); /* -90 dBm = RXLEV 20 */
+	CHECK_RXLEV_AVG100(32.00);
 
-	/* Avg[t] = (0.2 * -90) + (0.8 * -78) = -80.4 dBm */
-	apply_power_test(lchan, -90, good_lqual, 1, 11);
-	CHECK_UL_RSSI_AVG100(-80.40);
+	/* Avg[t] = (0.2 * 20) + (0.8 * 32) = RXLEV 29.6 (-80.4 dBm) */
+	apply_power_test(lchan, -90, good_lqual, 1, 11);  /* -90 dBm = RXLEV 20 */
+	CHECK_RXLEV_AVG100(29.60);
 
-	/* Avg[t] = (0.2 * -70) + (0.8 * -80.4) = -78.32 dBm,
+	/* 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] = -8040 + 20 * (-70 - (-8040 / 100))
-	 *   Avg100[t] = -8040 + 20 * (-70 - (-8040 / 100))
-	 *   Avg100[t] = -8040 + 20 * (-70 + 80)
-	 *   Avg100[t] = -8040 + 200 = -7840
-	 *   Avg[t] = -7840 / 100 = -78.4 */
-	apply_power_test(lchan, -70, good_lqual, 1, 9);
-	CHECK_UL_RSSI_AVG100(-78.40);
+	 *   Avg100[t] = 2960 + 20 * (40 - (2960 / 100))
+	 *   Avg100[t] = 2960 + 20 * (40 - 29)
+	 *   Avg100[t] = 3180 / 100 = 31.80 */
+	apply_power_test(lchan, -70, good_lqual, 1, 9); /* RXLEV 40 */
+	CHECK_RXLEV_AVG100(31.80);
 
 	mp->ewma.alpha = 70; /* 30% smoothing */
 	lchan->ms_power_ctrl.current = 15;
@@ -218,17 +216,17 @@
 		(struct gsm_power_ctrl_meas_proc_state) { 0 };
 
 	/* This is the first sample, the filter outputs it as-is */
-	apply_power_test(lchan, -50, good_lqual, 0, 15);
-	CHECK_UL_RSSI_AVG100(-50.00);
+	apply_power_test(lchan, -50, good_lqual, 0, 15); /* RXLEV 60 */
+	CHECK_RXLEV_AVG100((float)dbm2rxlev(-50));
 
-	/* Avg[t] = (0.7 * -50) + (0.3 * -50) = -50.0 dBm */
+	/* Avg[t] = (0.7 * 60) + (0.3 * 60) = RXLEV 60 (-50.0 dBm) */
 	apply_power_test(lchan, -50, good_lqual, 0, 15);
-	CHECK_UL_RSSI_AVG100(-50.0);
+	CHECK_RXLEV_AVG100((float)dbm2rxlev(-50));
 
 	/* Simulate SACCH block loss (-110 dBm):
-	 * Avg[t] = (0.7 * -110) + (0.3 * -50) = -92.0 dBm */
-	apply_power_test(lchan, -110, good_lqual, 1, 13);
-	CHECK_UL_RSSI_AVG100(-92.0);
+	 * Avg[t] = (0.7 * 0) + (0.3 * 60) = RXLEV 18.0 (-92.0 dBm) */
+	apply_power_test(lchan, -110, good_lqual, 1, 13); /* RXLEV 0 */
+	CHECK_RXLEV_AVG100(18.0);
 }
 
 static void test_power_hysteresis(void)

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-bts/+/25328
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Change-Id: I4cff8394f22b5d47789163051364ff594b2bcd74
Gerrit-Change-Number: 25328
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210902/b311041f/attachment.htm>


More information about the gerrit-log mailing list