Added UE synchronization error metric (hard-coded disabled by default)

This commit is contained in:
Xavier Arteaga 2019-04-12 17:35:49 +02:00
parent 06a9d8eb6f
commit a1a797589a
7 changed files with 57 additions and 2 deletions

View File

@ -63,6 +63,7 @@ typedef struct SRSLTE_API {
float rsrq_ant_port_db[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS];
float rssi_dbm;
float cfo;
float sync_error;
} srslte_chest_dl_res_t;
typedef enum SRSLTE_API {
@ -98,6 +99,7 @@ typedef struct SRSLTE_API {
float rsrp[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS];
float rsrp_corr[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS];
float noise_estimate[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS];
float sync_err[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS];
float cfo;
/* Use PSS for noise estimation in LS linear interpolation mode */
@ -118,6 +120,7 @@ typedef struct SRSLTE_API {
bool rsrp_neighbour;
bool cfo_estimate_enable;
uint32_t cfo_estimate_sf_mask;
bool sync_error_enable;
} srslte_chest_dl_cfg_t;

View File

@ -691,6 +691,19 @@ static int estimate_port(srslte_chest_dl_t* q,
srslte_vec_prod_conj_ccc(
q->pilot_recv_signal, q->csr_refs.pilots[port_id / 2][sf->tti % 10], q->pilot_estimates, npilots);
// Estimate synchronization error
if (cfg->sync_error_enable) {
uint32_t nsymb = srslte_refsignal_cs_nof_symbols(&q->csr_refs, sf, port_id);
float k = (float)srslte_symbol_sz(q->cell.nof_prb) / 6.0f;
float sum = 0.0f;
for (uint32_t i = 0; i < nsymb; i++) {
sum += srslte_vec_estimate_frequency(q->pilot_estimates + i * npilots / nsymb, npilots / nsymb) * k;
}
q->sync_err[rxant_id][port_id] = sum / nsymb;
} else {
q->sync_err[rxant_id][port_id] = NAN;
}
/* Compute RSRP for the channel estimates in this port */
if (cfg->rsrp_neighbour) {
double energy = cabs(srslte_vec_acc_cc(q->pilot_estimates, npilots)/npilots);
@ -843,6 +856,7 @@ static void fill_res(srslte_chest_dl_t* q, srslte_chest_dl_res_t* res)
res->rsrq_db = db(res->rsrq);
res->snr_db = db(get_snr(q));
res->rssi_dbm = dbm(get_rssi(q));
res->sync_error = q->sync_err[0][0]; // Take only the channel used for synch
for (uint32_t port_id = 0; port_id < q->cell.nof_ports; port_id++) {
res->rsrp_port_dbm[port_id] = dbm(get_rsrp_port(q, port_id));

View File

@ -44,6 +44,7 @@ struct dl_metrics_t
float turbo_iters;
float mcs;
float pathloss;
float sync_err;
};
struct ul_metrics_t

View File

@ -61,6 +61,7 @@ public:
void set_crnti(uint16_t rnti);
void enable_pregen_signals(bool enabled);
/* Methods for plotting */
int read_ce_abs(float* ce_abs, uint32_t tx_antenna, uint32_t rx_antenna);
uint32_t get_cell_nof_ports()
{
@ -72,6 +73,8 @@ public:
}
uint32_t get_rx_nof_antennas() { return phy->args->nof_rx_ant; }
int read_pdsch_d(cf_t* pdsch_d);
float get_sync_error();
float get_cfo();
void start_plot();
private:

View File

@ -652,6 +652,7 @@ void cc_worker::update_measurements()
dl_metrics.rssi = phy->avg_rssi_dbm;
dl_metrics.pathloss = phy->pathloss[cc_idx];
dl_metrics.sinr = phy->avg_snr_db_cqi[cc_idx];
dl_metrics.sync_err = ue_dl.chest_res.sync_error;
phy->set_dl_metrics(dl_metrics, cc_idx);
phy->set_ul_metrics(ul_metrics, cc_idx);

View File

@ -154,6 +154,7 @@ void phy_common::set_ue_dl_cfg(srslte_ue_dl_cfg_t* ue_dl_cfg)
}
chest_cfg->rsrp_neighbour = false;
chest_cfg->sync_error_enable = false;
chest_cfg->interpolate_subframe = args->interpolate_subframe_enabled;
chest_cfg->cfo_estimate_enable = args->cfo_ref_mask != 0;
chest_cfg->cfo_estimate_sf_mask = args->cfo_ref_mask;
@ -610,6 +611,8 @@ void phy_common::set_dl_metrics(const dl_metrics_t m, uint32_t cc_idx)
dl_metrics[cc_idx].rssi = dl_metrics[cc_idx].rssi + (m.rssi - dl_metrics[cc_idx].rssi) / dl_metrics_count;
dl_metrics[cc_idx].rsrp = dl_metrics[cc_idx].rsrp + (m.rsrp - dl_metrics[cc_idx].rsrp) / dl_metrics_count;
dl_metrics[cc_idx].sinr = dl_metrics[cc_idx].sinr + (m.sinr - dl_metrics[cc_idx].sinr) / dl_metrics_count;
dl_metrics[cc_idx].sync_err =
dl_metrics[cc_idx].sync_err + (m.sync_err - dl_metrics[cc_idx].sync_err) / dl_metrics_count;
dl_metrics[cc_idx].pathloss =
dl_metrics[cc_idx].pathloss + (m.pathloss - dl_metrics[cc_idx].pathloss) / dl_metrics_count;
dl_metrics[cc_idx].turbo_iters =

View File

@ -395,7 +395,19 @@ int sf_worker::read_pdsch_d(cf_t* pdsch_d)
{
return cc_workers[0]->read_pdsch_d(pdsch_d);
}
float sf_worker::get_sync_error()
{
dl_metrics_t dl_metrics[SRSLTE_MAX_CARRIERS] = {};
phy->get_dl_metrics(dl_metrics);
return dl_metrics->sync_err;
}
float sf_worker::get_cfo()
{
sync_metrics_t sync_metrics = {};
phy->get_sync_metrics(sync_metrics);
return sync_metrics.cfo;
}
} // namespace srsue
/***********************************************************
@ -419,9 +431,17 @@ static uint32_t icfo = 0;
static float cfo_buffer[CFO_PLOT_LEN];
#endif /* CFO_PLOT_LEN > 0 */
#define SYNC_PLOT_LEN 0 /* Set to non zero for enabling Sync error plot */
#if SYNC_PLOT_LEN > 0
static plot_real_t psync;
static uint32_t isync = 0;
static float sync_buffer[SYNC_PLOT_LEN];
#endif /* SYNC_PLOT_LEN > 0 */
void* plot_thread_run(void* arg)
{
srsue::sf_worker* worker = (srsue::sf_worker*)arg;
uint32_t row_count = 0;
sdrgui_init();
for (uint32_t tx = 0; tx < worker->get_cell_nof_ports(); tx++) {
@ -436,13 +456,14 @@ void* plot_thread_run(void* arg)
plot_real_addToWindowGrid(&pce[tx][rx], (char*)"srsue", tx, rx);
}
}
row_count = worker->get_rx_nof_antennas();
plot_scatter_init(&pconst);
plot_scatter_setTitle(&pconst, (char*)"PDSCH - Equalized Symbols");
plot_scatter_setXAxisScale(&pconst, -4, 4);
plot_scatter_setYAxisScale(&pconst, -4, 4);
plot_scatter_addToWindowGrid(&pconst, (char*)"srsue", 0, worker->get_rx_nof_antennas());
plot_scatter_addToWindowGrid(&pconst, (char*)"srsue", 0, row_count);
#if CFO_PLOT_LEN > 0
plot_real_init(&pcfo);
@ -450,9 +471,18 @@ void* plot_thread_run(void* arg)
plot_real_setLabels(&pcfo, (char*)"Time", (char*)"Hz");
plot_real_setYAxisScale(&pcfo, -4000, 4000);
plot_scatter_addToWindowGrid(&pcfo, (char*)"srsue", 1, worker->get_rx_nof_antennas());
plot_scatter_addToWindowGrid(&pcfo, (char*)"srsue", 1, row_count++);
#endif /* CFO_PLOT_LEN > 0 */
#if SYNC_PLOT_LEN > 0
plot_real_init(&psync);
plot_real_setTitle(&psync, (char*)"Sync error (in samples)");
plot_real_setLabels(&psync, (char*)"Time", (char*)"Error");
plot_real_setYAxisScale(&psync, -2, +2);
plot_scatter_addToWindowGrid(&psync, (char*)"srsue", 1, row_count++);
#endif /* SYNC_PLOT_LEN > 0 */
int n;
int readed_pdsch_re = 0;
while (1) {