mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 04:30:28 +00:00
Merge remote-tracking branch 'origin/fix-ema-init' into integration_2026_w16 (!4051)
Fix EMA cold-start for noise and SNR/RSSI measurements Initialize n0_subband_power and power control avg_snr/avg_rssi directly from the first measurement instead of starting from zero. Starting from zero causes the EMA to converge slowly, leading to underestimated noise power at gNB startup. This results in inflated SNR estimates, which triggers UE uplink power ramp-up, antenna saturation, and a positive feedback loop of increasing noise.
This commit is contained in:
@@ -162,6 +162,7 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_sy
|
||||
int32_t n0_subband_tot_perANT[frame_parms->nb_antennas_rx];
|
||||
memset(n0_subband_tot_perANT, 0, sizeof(n0_subband_tot_perANT));
|
||||
|
||||
bool init_meas = measurements->n0_subband_power == NULL;
|
||||
allocCast2D(n0_subband_power,
|
||||
unsigned int,
|
||||
measurements->n0_subband_power,
|
||||
@@ -174,6 +175,9 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_sy
|
||||
if (nb_symb[rb] > 0) {
|
||||
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
|
||||
tmp_n0_subband[aarx][rb] /= nb_symb[rb];
|
||||
// Initialize n0_subband_power from the first measurement before EMA
|
||||
if (init_meas)
|
||||
n0_subband_power[aarx][rb] = tmp_n0_subband[aarx][rb];
|
||||
// apply exponential moving average to smooth noise measurements
|
||||
n0_subband_power[aarx][rb] = 0.9 * n0_subband_power[aarx][rb] + 0.1 * tmp_n0_subband[aarx][rb];
|
||||
n0_subband_tot_perPRB += n0_subband_power[aarx][rb];
|
||||
|
||||
@@ -4190,6 +4190,21 @@ void nr_mac_pc_snr(nr_power_control_t *pc, int snrx10, int rssi)
|
||||
pc->tpc_in_flight = PC_AVG_CNST * pc->tpc_in_flight; // + (1 - PC_AVG_CNST) * 0.0f
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enter new SNR and RSSI value for the latest UL transmission as new
|
||||
* fixed averages. Reset "TPC in flight" to zero.
|
||||
*
|
||||
* @param pc the power control loop
|
||||
* @param snrx10 the current SNR measurement multiplied by 10
|
||||
* @param rssi the current RSSI measurement
|
||||
*/
|
||||
void nr_mac_pc_reset_snr(nr_power_control_t *pc, int snrx10, int rssi)
|
||||
{
|
||||
pc->avg_snr = 0.1f * snrx10;
|
||||
pc->avg_rssi = rssi;
|
||||
pc->tpc_in_flight = 0.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set a new target SNR for this power control loop, which can be
|
||||
* updated on a continuous basis, and will be reflected immediately upon
|
||||
|
||||
@@ -910,6 +910,9 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, frame_t frame, slot_t slot, con
|
||||
NR_SCHED_UNLOCK(&nrmac->sched_lock);
|
||||
return;
|
||||
}
|
||||
// Msg4 Ack: reset average with first measurement
|
||||
if (uci_01->ul_cqi != 0xff)
|
||||
nr_mac_pc_reset_snr(&UE->UE_sched_ctrl.pucch_pc, uci_01->ul_cqi * 5 - 640, uci_01->rssi);
|
||||
}
|
||||
if (harq_confidence == 1) {
|
||||
UE->mac_stats.pucch0_DTX++;
|
||||
|
||||
@@ -762,11 +762,9 @@ static void nr_rx_ra_sdu(const module_id_t mod_id,
|
||||
}
|
||||
|
||||
if (ul_cqi != 0xff) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
// Msg3: reset average. If this fails (e.g., ul_cqi == 0xff)
|
||||
// Msg3: reset average with first measurement. If this fails (e.g., ul_cqi == 0xff)
|
||||
// everything starts from predetermined value
|
||||
sched_ctrl->pusch_pc.avg_snr = 0.1 * (ul_cqi * 5 - 640);
|
||||
sched_ctrl->pusch_pc.avg_rssi = rssi;
|
||||
nr_mac_pc_reset_snr(&UE->UE_sched_ctrl.pusch_pc, ul_cqi * 5 - 640, rssi);
|
||||
}
|
||||
|
||||
if (!sdu) { // NACK
|
||||
|
||||
@@ -500,6 +500,7 @@ void post_process_ulsch(gNB_MAC_INST *nr_mac, post_process_pusch_t *pusch, NR_UE
|
||||
|
||||
float nr_mac_get_snr(const nr_power_control_t *pc);
|
||||
void nr_mac_pc_snr(nr_power_control_t *pc, int snrx10, int rssi);
|
||||
void nr_mac_pc_reset_snr(nr_power_control_t *pc, int snrx10, int rssi);
|
||||
void nr_mac_set_target_snrx10(nr_power_control_t *pc, int target_snrx10);
|
||||
void nr_mac_set_rssi_threshold(nr_power_control_t *pc, int rssi_threshold);
|
||||
void nr_mac_signal_dtx(nr_power_control_t *pc);
|
||||
|
||||
Reference in New Issue
Block a user