Use RS power estimation for serving cell RSRP/SNR measurements. Use correlation of RS sequences for neighbour cell verification of Cell ID

master
Ismael Gomez 7 years ago
parent c2098ad626
commit 809c550ca2

@ -82,10 +82,13 @@ typedef struct {
srslte_interp_lin_t srslte_interp_lin_3;
srslte_interp_lin_t srslte_interp_lin_mbsfn;
float rssi[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS];
float rsrp[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS];
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 cfo;
bool rsrp_neighbour;
bool cfo_estimate_enable;
uint32_t cfo_estimate_sf_mask;
@ -158,6 +161,9 @@ SRSLTE_API void srslte_chest_dl_cfo_estimate_enable(srslte_chest_dl_t *q,
SRSLTE_API void srslte_chest_dl_average_subframe(srslte_chest_dl_t *q,
bool enable);
SRSLTE_API void srslte_chest_dl_set_rsrp_neighbour(srslte_chest_dl_t *q,
bool rsrp_for_neighbour);
SRSLTE_API float srslte_chest_dl_get_noise_estimate(srslte_chest_dl_t *q);
SRSLTE_API float srslte_chest_dl_get_cfo(srslte_chest_dl_t *q);
@ -185,4 +191,6 @@ SRSLTE_API float srslte_chest_dl_get_rsrp_port(srslte_chest_dl_t *q,
SRSLTE_API float srslte_chest_dl_get_rsrp(srslte_chest_dl_t *q);
SRSLTE_API float srslte_chest_dl_get_rsrp_neighbour(srslte_chest_dl_t *q);
#endif

@ -152,7 +152,9 @@ int srslte_chest_dl_init(srslte_chest_dl_t *q, uint32_t max_prb)
}
q->noise_alg = SRSLTE_NOISE_ALG_REFS;
q->rsrp_neighbour = false;
q->smooth_filter_len = 3;
srslte_chest_dl_set_smooth_filter3_coeff(q, 0.1);
@ -545,7 +547,7 @@ void chest_interpolate_noise_est(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, ui
}
}
int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, uint32_t sf_idx, uint32_t port_id, uint32_t rxant_id)
int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, uint32_t sf_idx, uint32_t port_id, uint32_t rxant_id)
{
uint32_t npilots = SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id);
@ -557,14 +559,18 @@ int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, u
q->pilot_estimates, npilots);
/* Compute RSRP for the channel estimates in this port */
double energy = cabs(srslte_vec_acc_cc(q->pilot_estimates, npilots)/npilots);
q->rsrp[rxant_id][port_id] = energy*energy;
if (q->rsrp_neighbour) {
double energy = cabs(srslte_vec_acc_cc(q->pilot_estimates, npilots)/npilots);
q->rsrp_corr[rxant_id][port_id] = energy*energy;
}
q->rsrp[rxant_id][port_id] = srslte_vec_avg_power_cf(q->pilot_recv_signal, npilots);
q->rssi[rxant_id][port_id] = srslte_chest_dl_rssi(q, input, port_id);
chest_interpolate_noise_est(q, input, ce, sf_idx, port_id, rxant_id, SRSLTE_SF_NORM);
return 0;
}
int srslte_chest_dl_estimate_port_mbsfn(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, uint32_t sf_idx, uint32_t port_id, uint32_t rxant_id, uint16_t mbsfn_area_id)
{
@ -623,6 +629,10 @@ int srslte_chest_dl_estimate_multi_mbsfn(srslte_chest_dl_t *q, cf_t *input[SRSLT
return SRSLTE_SUCCESS;
}
void srslte_chest_dl_set_rsrp_neighbour(srslte_chest_dl_t *q, bool rsrp_for_neighbour) {
q->rsrp_neighbour = rsrp_for_neighbour;
}
void srslte_chest_dl_average_subframe(srslte_chest_dl_t *q, bool enable)
{
q->average_subframe = enable;
@ -710,6 +720,19 @@ float srslte_chest_dl_get_rsrp_port(srslte_chest_dl_t *q, uint32_t port) {
return sum;
}
float srslte_chest_dl_get_rsrp_neighbour_port(srslte_chest_dl_t *q, uint32_t port) {
float sum = 0.0f;
for (int j = 0; j < q->cell.nof_ports; ++j) {
sum +=q->rsrp_corr[port][j];
}
if (q->cell.nof_ports) {
sum /= q->cell.nof_ports;
}
return sum;
}
float srslte_chest_dl_get_rsrp(srslte_chest_dl_t *q) {
float max = -0.0f;
for (int i = 0; i < q->last_nof_antennas; ++i) {
@ -720,3 +743,14 @@ float srslte_chest_dl_get_rsrp(srslte_chest_dl_t *q) {
}
return max;
}
float srslte_chest_dl_get_rsrp_neighbour(srslte_chest_dl_t *q) {
float max = -0.0f;
for (int i = 0; i < q->last_nof_antennas; ++i) {
float v = srslte_chest_dl_get_rsrp_neighbour_port(q, i);
if (v > max) {
max = v;
}
}
return max;
}

@ -171,6 +171,7 @@ private:
ret_code run_multiple_subframes(cf_t *buffer, uint32_t offset, uint32_t sf_idx, uint32_t nof_sf);
float rssi();
float rsrp();
float rsrp_n();
float rsrq();
float snr();
uint32_t frame_st_idx();
@ -183,7 +184,7 @@ private:
uint32_t nof_subframes;
uint32_t current_prb;
float rx_gain_offset;
float mean_rsrp, mean_rsrq, mean_snr, mean_rssi;
float mean_rsrp, mean_rsrp_n, mean_rsrq, mean_snr, mean_rssi;
uint32_t final_offset;
const static int RSRP_MEASURE_NOF_FRAMES = 5;
};

@ -1022,6 +1022,7 @@ void phch_recv::measure::init(cf_t *buffer[SRSLTE_MAX_PORTS], srslte::log *log_h
Error("SYNC: Initiating ue_dl_measure\n");
return;
}
srslte_chest_dl_set_rsrp_neighbour(&ue_dl.chest, true);
reset();
}
@ -1054,6 +1055,10 @@ float phch_recv::measure::rsrp() {
return 10*log10(mean_rsrp) + 30 - rx_gain_offset;
}
float phch_recv::measure::rsrp_n() {
return 10*log10(mean_rsrp_n) + 30 - rx_gain_offset;
}
float phch_recv::measure::rsrq() {
return 10*log10(mean_rsrq);
}
@ -1099,12 +1104,13 @@ phch_recv::measure::ret_code phch_recv::measure::run_multiple_subframes(cf_t *in
sf_idx ++;
}
// Fine-tune offset using RS
#ifdef FINE_TUNE_OFFSET_WITH_RS
float max_rsrp = -200;
int best_test_offset = 0;
int test_offset = 0;
bool found_best = false;
// Fine-tune offset using RS
for (uint32_t n=0;n<5;n++) {
test_offset = offset-2+n;
@ -1128,11 +1134,14 @@ phch_recv::measure::ret_code phch_recv::measure::run_multiple_subframes(cf_t *in
}
}
Debug("INTRA: fine-tuning offset: %d, found_best=%d, rem_sf=%d\n", offset, found_best, nof_sf);
offset = found_best?best_test_offset:offset;
#endif
if (offset >= 0 && offset < sf_len*max_sf) {
uint32_t nof_sf = (sf_len*max_sf - offset)/sf_len;
Debug("INTRA: fine-tuning offset: %d, found_best=%d, rem_sf=%d\n", offset, found_best, nof_sf);
final_offset = offset;
@ -1161,25 +1170,28 @@ phch_recv::measure::ret_code phch_recv::measure::run_subframe(uint32_t sf_idx)
}
float rsrp = srslte_chest_dl_get_rsrp(&ue_dl.chest);
float rsrp_n = srslte_chest_dl_get_rsrp_neighbour(&ue_dl.chest);
float rsrq = srslte_chest_dl_get_rsrq(&ue_dl.chest);
float snr = srslte_chest_dl_get_snr(&ue_dl.chest);
float rssi = srslte_vec_avg_power_cf(buffer[0], SRSLTE_SF_LEN_PRB(current_prb));
if (cnt == 0) {
mean_rsrp = rsrp;
mean_rsrq = rsrq;
mean_snr = snr;
mean_rssi = rssi;
mean_rsrp = rsrp;
mean_rsrp_n = rsrp_n;
mean_rsrq = rsrq;
mean_snr = snr;
mean_rssi = rssi;
} else {
mean_rsrp = SRSLTE_VEC_CMA(rsrp, mean_rsrp, cnt);
mean_rsrq = SRSLTE_VEC_CMA(rsrq, mean_rsrq, cnt);
mean_snr = SRSLTE_VEC_CMA(snr, mean_snr, cnt);
mean_rssi = SRSLTE_VEC_CMA(rssi, mean_rssi, cnt);
mean_rsrp = SRSLTE_VEC_CMA(rsrp, mean_rsrp, cnt);
mean_rsrp_n = SRSLTE_VEC_CMA(rsrp_n, mean_rsrp_n, cnt);
mean_rsrq = SRSLTE_VEC_CMA(rsrq, mean_rsrq, cnt);
mean_snr = SRSLTE_VEC_CMA(snr, mean_snr, cnt);
mean_rssi = SRSLTE_VEC_CMA(rssi, mean_rssi, cnt);
}
cnt++;
log_h->debug("SYNC: Measuring RSRP %d/%d, sf_idx=%d, RSRP=%.1f dBm, SNR=%.1f dB\n",
cnt, nof_subframes, sf_idx, rsrp, snr);
log_h->debug("SYNC: Measuring RSRP %d/%d, sf_idx=%d, RSRP=%.1f dBm, corr-RSRP=%.1f dBm, SNR=%.1f dB\n",
cnt, nof_subframes, sf_idx, rsrp, rsrp_n, snr);
if (cnt >= nof_subframes) {
return MEASURE_OK;
@ -1217,6 +1229,7 @@ void phch_recv::scell_recv::init(srslte::log *log_h, bool sic_pss_enabled, uint3
fprintf(stderr, "Error initiating sync_find\n");
return;
}
srslte_sync_set_sss_algorithm(&sync_find, SSS_FULL);
srslte_sync_cp_en(&sync_find, false);
srslte_sync_set_cfo_pss_enable(&sync_find, true);
srslte_sync_set_threshold(&sync_find, 1.7);
@ -1230,8 +1243,7 @@ void phch_recv::scell_recv::init(srslte::log *log_h, bool sic_pss_enabled, uint3
srslte_sync_set_sss_eq_enable(&sync_find, true);
sync_find.pss.chest_on_filter = true;
sync_find.sss_channel_equalize = true;
sync_find.sss_channel_equalize = false;
reset();
}
@ -1336,17 +1348,27 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset,
case measure::MEASURE_OK:
// Consider a cell to be detectable 8.1.2.2.1.1 from 36.133. Currently only using first condition
if (measure_p.rsrp() > ABSOLUTE_RSRP_THRESHOLD_DBM) {
cells[nof_cells].pci = found_cell.id;
cells[nof_cells].rsrp = measure_p.rsrp();
cells[nof_cells].rsrq = measure_p.rsrq();
cells[nof_cells].offset = measure_p.frame_st_idx();
Info(
"INTRA: Found neighbour cell %d: PCI=%03d, RSRP=%5.1f dBm, peak_idx=%5d, peak_value=%3.2f, sf=%d, max_sf=%d, n_id_2=%d, CFO=%6.1f Hz\n",
nof_cells, cell_id, measure_p.rsrp(), measure_p.frame_st_idx(), sync_find.peak_value,
sf_idx, max_sf5, n_id_2, 15000 * srslte_sync_get_cfo(&sync_find));
nof_cells++;
// Check the cell id has been correctly identified by using the correlation of the RS sequences
// By experimentation, typically the cross-correlation is ~3/4 dB less
if (measure_p.rsrp_n() > measure_p.rsrp() - 6) {
cells[nof_cells].pci = found_cell.id;
cells[nof_cells].rsrp = measure_p.rsrp();
cells[nof_cells].rsrq = measure_p.rsrq();
cells[nof_cells].offset = measure_p.frame_st_idx();
Info(
"INTRA: Found neighbour cell %d: PCI=%03d, RSRP=%5.1f dBm, corr-RSRP=%5.1f dBm, peak_idx=%5d, peak_value=%3.2f, sf=%d, max_sf=%d, n_id_2=%d, CFO=%6.1f Hz\n",
nof_cells, cell_id, measure_p.rsrp(), measure_p.rsrp_n(), measure_p.frame_st_idx(), sync_find.peak_value,
sf_idx, max_sf5, n_id_2, 15000 * srslte_sync_get_cfo(&sync_find));
nof_cells++;
} else {
Info(
"INTRA: Found phantom cell %d: PCI=%03d, RSRP=%5.1f dBm, corr-RSRP=%5.1f dBm, peak_idx=%5d, peak_value=%3.2f, sf=%d, max_sf=%d, n_id_2=%d, CFO=%6.1f Hz\n",
nof_cells, cell_id, measure_p.rsrp(), measure_p.rsrp_n(), measure_p.frame_st_idx(), sync_find.peak_value,
sf_idx, max_sf5, n_id_2, 15000 * srslte_sync_get_cfo(&sync_find));
}
/*
if (sic_pss_enabled) {

Loading…
Cancel
Save