SRSUE: Default PHY measurements to NAN

master
Xavier Arteaga 4 years ago committed by Xavier Arteaga
parent 4bfe092a24
commit fc5d069743

@ -168,6 +168,12 @@ public:
*/
uint32_t get_ul_earfcn(uint32_t dl_earfcn);
/**
* @brief Resets measurements from a given CC
* @param cc_idx CC index
*/
void reset_measurements(uint32_t cc_idx);
void update_measurements(uint32_t cc_idx,
const srsran_chest_dl_res_t& chest_res,
srsran_dl_sf_cfg_t sf_cfg_dl,
@ -218,31 +224,25 @@ public:
}
}
}
void reset_neighbour_cells()
{
for (uint32_t i = 0; i < SRSRAN_MAX_CARRIERS; i++) {
avg_rsrp_neigh[i] = NAN;
}
}
private:
std::mutex meas_mutex;
float pathloss[SRSRAN_MAX_CARRIERS] = {};
float cur_pathloss = 0.0f;
float cur_pusch_power = 0.0f;
float avg_rsrp[SRSRAN_MAX_CARRIERS] = {};
float avg_rsrp_dbm[SRSRAN_MAX_CARRIERS] = {};
float avg_rsrq_db[SRSRAN_MAX_CARRIERS] = {};
float avg_rssi_dbm[SRSRAN_MAX_CARRIERS] = {};
float avg_cfo_hz[SRSRAN_MAX_CARRIERS] = {};
float rx_gain_offset = 0.0f;
float avg_sinr_db[SRSRAN_MAX_CARRIERS] = {};
float avg_snr_db[SRSRAN_MAX_CARRIERS] = {};
float avg_noise[SRSRAN_MAX_CARRIERS] = {};
float avg_rsrp_neigh[SRSRAN_MAX_CARRIERS] = {};
uint32_t pcell_report_period = 0;
std::array<float, SRSRAN_MAX_CARRIERS> pathloss = {};
std::array<float, SRSRAN_MAX_CARRIERS> avg_rsrp = {};
std::array<float, SRSRAN_MAX_CARRIERS> avg_rsrp_dbm = {};
std::array<float, SRSRAN_MAX_CARRIERS> avg_rsrq_db = {};
std::array<float, SRSRAN_MAX_CARRIERS> avg_rssi_dbm = {};
std::array<float, SRSRAN_MAX_CARRIERS> avg_cfo_hz = {};
std::array<float, SRSRAN_MAX_CARRIERS> avg_sinr_db = {};
std::array<float, SRSRAN_MAX_CARRIERS> avg_snr_db = {};
std::array<float, SRSRAN_MAX_CARRIERS> avg_noise = {};
std::array<float, SRSRAN_MAX_CARRIERS> avg_rsrp_neigh = {};
static constexpr uint32_t pcell_report_period = 20;
uint32_t rssi_read_cnt = 0;
rsrp_insync_itf* insync_itf = nullptr;

@ -549,6 +549,11 @@ void cc_worker::decode_phich()
void cc_worker::update_measurements(std::vector<phy_meas_t>& serving_cells, cf_t* rssi_power_buffer)
{
// Do not update any measurement if the CC is not configured to prevent false or inaccurate data
if (not phy->cell_state.is_configured(cc_idx)) {
return;
}
phy->update_measurements(
cc_idx, ue_dl.chest_res, sf_cfg_dl, ue_dl_cfg.cfg.pdsch.rs_power, serving_cells, rssi_power_buffer);
}

@ -529,6 +529,10 @@ bool phy::set_scell(srsran_cell_t cell_info, uint32_t cc_idx, uint32_t earfcn)
}
}
// Reset measurements for the given CC after all workers finished processing and have been configured to ensure the
// measurements are not overwritten
common.reset_measurements(cc_idx);
// Change frequency only if the earfcn was modified
if (earfcn_is_different) {
double dl_freq = srsran_band_fd(earfcn) * 1e6;

@ -611,8 +611,31 @@ void phy_common::update_cfo_measurement(uint32_t cc_idx, float cfo_hz)
{
std::unique_lock<std::mutex> lock(meas_mutex);
// use SNR EMA coefficient for averaging
avg_cfo_hz[cc_idx] = SRSRAN_VEC_EMA(cfo_hz, avg_cfo_hz[cc_idx], args->snr_ema_coeff);
// Use SNR EMA coefficient for averaging
avg_cfo_hz[cc_idx] = SRSRAN_VEC_SAFE_EMA(cfo_hz, avg_cfo_hz[cc_idx], args->snr_ema_coeff);
}
void phy_common::reset_measurements(uint32_t cc_idx)
{
// If the CC index exceeds the maximum number of carriers, reset them all
if (cc_idx >= SRSRAN_MAX_CARRIERS) {
for (uint32_t cc = 0; cc < SRSRAN_MAX_CARRIERS; cc++) {
reset_measurements(cc);
}
}
// Default all metrics to NAN to prevent providing invalid information on traces and other layers
std::unique_lock<std::mutex> lock(meas_mutex);
pathloss[cc_idx] = NAN;
avg_rsrp[cc_idx] = NAN;
avg_rsrp_dbm[cc_idx] = NAN;
avg_rsrq_db[cc_idx] = NAN;
avg_rssi_dbm[cc_idx] = NAN;
avg_cfo_hz[cc_idx] = NAN;
avg_sinr_db[cc_idx] = NAN;
avg_snr_db[cc_idx] = NAN;
avg_noise[cc_idx] = NAN;
avg_rsrp_neigh[cc_idx] = NAN;
}
void phy_common::update_measurements(uint32_t cc_idx,
@ -644,7 +667,7 @@ void phy_common::update_measurements(uint32_t cc_idx,
30)
: 0;
if (std::isnormal(rssi_dbm)) {
avg_rssi_dbm[0] = SRSRAN_VEC_EMA(rssi_dbm, avg_rssi_dbm[0], args->snr_ema_coeff);
avg_rssi_dbm[0] = SRSRAN_VEC_SAFE_EMA(rssi_dbm, avg_rssi_dbm[0], args->snr_ema_coeff);
}
rx_gain_offset = get_radio()->get_rx_gain() + args->rx_gain_offset;
@ -658,21 +681,17 @@ void phy_common::update_measurements(uint32_t cc_idx,
// Average RSRQ over DEFAULT_MEAS_PERIOD_MS then sent to RRC
float rsrq_db = chest_res.rsrq_db;
if (std::isnormal(rsrq_db)) {
if (!(sf_cfg_dl.tti % pcell_report_period) || !std::isnormal(avg_rsrq_db[cc_idx])) {
avg_rsrq_db[cc_idx] = rsrq_db;
} else {
avg_rsrq_db[cc_idx] = SRSRAN_VEC_CMA(rsrq_db, avg_rsrq_db[cc_idx], sf_cfg_dl.tti % pcell_report_period);
// Reset average RSRQ measurement
if (sf_cfg_dl.tti % pcell_report_period == 0) {
avg_rsrq_db[cc_idx] = NAN;
}
avg_rsrq_db[cc_idx] = SRSRAN_VEC_SAFE_CMA(rsrq_db, avg_rsrq_db[cc_idx], sf_cfg_dl.tti % pcell_report_period);
}
// Average RSRP taken from CRS
float rsrp_lin = chest_res.rsrp;
if (std::isnormal(rsrp_lin)) {
if (!std::isnormal(avg_rsrp[cc_idx])) {
avg_rsrp[cc_idx] = rsrp_lin;
} else {
avg_rsrp[cc_idx] = SRSRAN_VEC_EMA(rsrp_lin, avg_rsrp[cc_idx], snr_ema_coeff);
}
avg_rsrp[cc_idx] = SRSRAN_VEC_SAFE_EMA(rsrp_lin, avg_rsrp[cc_idx], snr_ema_coeff);
}
/* Correct absolute power measurements by RX gain offset */
@ -680,11 +699,11 @@ void phy_common::update_measurements(uint32_t cc_idx,
// Serving cell RSRP measurements are averaged over DEFAULT_MEAS_PERIOD_MS then sent to RRC
if (std::isnormal(rsrp_dbm)) {
if (!(sf_cfg_dl.tti % pcell_report_period) || !std::isnormal(avg_rsrp_dbm[cc_idx])) {
avg_rsrp_dbm[cc_idx] = rsrp_dbm;
} else {
avg_rsrp_dbm[cc_idx] = SRSRAN_VEC_CMA(rsrp_dbm, avg_rsrp_dbm[cc_idx], sf_cfg_dl.tti % pcell_report_period);
// Reset average RSRP measurement
if (sf_cfg_dl.tti % pcell_report_period == 0) {
avg_rsrp_dbm[cc_idx] = NAN;
}
avg_rsrp_dbm[cc_idx] = SRSRAN_VEC_SAFE_CMA(rsrp_dbm, avg_rsrp_dbm[cc_idx], sf_cfg_dl.tti % pcell_report_period);
}
// Compute PL
@ -693,11 +712,7 @@ void phy_common::update_measurements(uint32_t cc_idx,
// Average noise
float cur_noise = chest_res.noise_estimate;
if (std::isnormal(cur_noise)) {
if (!std::isnormal(avg_noise[cc_idx])) {
avg_noise[cc_idx] = cur_noise;
} else {
avg_noise[cc_idx] = SRSRAN_VEC_EMA(cur_noise, avg_noise[cc_idx], snr_ema_coeff);
}
avg_noise[cc_idx] = SRSRAN_VEC_SAFE_EMA(cur_noise, avg_noise[cc_idx], snr_ema_coeff);
}
// Calculate SINR using CRS from neighbours if are detected
@ -714,20 +729,12 @@ void phy_common::update_measurements(uint32_t cc_idx,
// Average sinr in the log domain
if (std::isnormal(sinr_db)) {
if (!std::isnormal(avg_sinr_db[cc_idx])) {
avg_sinr_db[cc_idx] = sinr_db;
} else {
avg_sinr_db[cc_idx] = SRSRAN_VEC_EMA(sinr_db, avg_sinr_db[cc_idx], snr_ema_coeff);
}
avg_sinr_db[cc_idx] = SRSRAN_VEC_SAFE_EMA(sinr_db, avg_sinr_db[cc_idx], snr_ema_coeff);
}
// Average snr in the log domain
if (std::isnormal(chest_res.snr_db)) {
if (!std::isnormal(avg_snr_db[cc_idx])) {
avg_snr_db[cc_idx] = chest_res.snr_db;
} else {
avg_snr_db[cc_idx] = SRSRAN_VEC_EMA(chest_res.snr_db, avg_snr_db[cc_idx], snr_ema_coeff);
}
avg_snr_db[cc_idx] = SRSRAN_VEC_SAFE_EMA(chest_res.snr_db, avg_snr_db[cc_idx], snr_ema_coeff);
}
// Store metrics
@ -742,9 +749,9 @@ void phy_common::update_measurements(uint32_t cc_idx,
set_ch_metrics(cc_idx, ch);
// Prepare measurements for serving cells
bool active = cell_state.is_configured(cc_idx);
if (active && ((sf_cfg_dl.tti % pcell_report_period) == pcell_report_period - 1)) {
// Prepare measurements for serving cells - skip if any measurement is invalid assuming pure zeros are not possible
if (std::isnormal(avg_rsrp_dbm[cc_idx]) and
std::isnormal(avg_cfo_hz[cc_idx] and ((sf_cfg_dl.tti % pcell_report_period) == pcell_report_period - 1))) {
phy_meas_t meas = {};
meas.rsrp = avg_rsrp_dbm[cc_idx];
meas.rsrq = avg_rsrq_db[cc_idx];
@ -870,21 +877,13 @@ void phy_common::reset()
cur_pathloss = 0;
cur_pusch_power = 0;
sr_last_tx_tti = -1;
pcell_report_period = 20;
last_ri = 0;
{
std::unique_lock<std::mutex> lock(meas_mutex);
ZERO_OBJECT(pathloss);
ZERO_OBJECT(avg_sinr_db);
ZERO_OBJECT(avg_snr_db);
ZERO_OBJECT(avg_rsrp);
ZERO_OBJECT(avg_rsrp_dbm);
ZERO_OBJECT(avg_rsrq_db);
}
cell_state.reset();
// Reset all measurements
reset_measurements(SRSRAN_MAX_CARRIERS);
reset_neighbour_cells();
// Reset all SCell states
cell_state.reset();
// Note: Using memset to reset these members is forbidden because they are real objects, not plain arrays.
{

Loading…
Cancel
Save