Average sampling offset estimate before adjusting timing to be more robust against EVA and ETU fading

master
Ismael Gomez 7 years ago
parent c689343d81
commit 467ba4e326

@ -497,6 +497,8 @@ typedef struct {
float cfo_loop_bw_ref; float cfo_loop_bw_ref;
float cfo_loop_ref_min; float cfo_loop_ref_min;
float cfo_loop_pss_tol; float cfo_loop_pss_tol;
float sfo_ema;
uint32_t sfo_correct_period;
uint32_t cfo_loop_pss_conv; uint32_t cfo_loop_pss_conv;
uint32_t cfo_ref_mask; uint32_t cfo_ref_mask;
bool average_subframe_enabled; bool average_subframe_enabled;

@ -61,6 +61,8 @@
#include "srslte/phy/common/timestamp.h" #include "srslte/phy/common/timestamp.h"
#include "srslte/phy/io/filesource.h" #include "srslte/phy/io/filesource.h"
#define DEFAULT_SAMPLE_OFFSET_CORRECT_PERIOD 10
#define DEFAULT_SFO_EMA_COEFF 0.1
#define DEFAULT_CFO_BW_PSS 0.05 #define DEFAULT_CFO_BW_PSS 0.05
#define DEFAULT_CFO_PSS_MIN 400 // typical bias of PSS estimation. #define DEFAULT_CFO_PSS_MIN 400 // typical bias of PSS estimation.
@ -140,7 +142,6 @@ typedef struct SRSLTE_API {
int next_rf_sample_offset; int next_rf_sample_offset;
int last_sample_offset; int last_sample_offset;
float mean_sample_offset; float mean_sample_offset;
float mean_sfo;
uint32_t sample_offset_correct_period; uint32_t sample_offset_correct_period;
float sfo_ema; float sfo_ema;
@ -248,8 +249,11 @@ SRSLTE_API float srslte_ue_sync_get_sfo(srslte_ue_sync_t *q);
SRSLTE_API int srslte_ue_sync_get_last_sample_offset(srslte_ue_sync_t *q); SRSLTE_API int srslte_ue_sync_get_last_sample_offset(srslte_ue_sync_t *q);
SRSLTE_API void srslte_ue_sync_set_sample_offset_correct_period(srslte_ue_sync_t *q, SRSLTE_API void srslte_ue_sync_set_sfo_correct_period(srslte_ue_sync_t *q,
uint32_t nof_subframes); uint32_t nof_subframes);
SRSLTE_API void srslte_ue_sync_set_sfo_ema(srslte_ue_sync_t *q,
float ema_coefficient);
SRSLTE_API void srslte_ue_sync_get_last_timestamp(srslte_ue_sync_t *q, SRSLTE_API void srslte_ue_sync_get_last_timestamp(srslte_ue_sync_t *q,
srslte_timestamp_t *timestamp); srslte_timestamp_t *timestamp);

@ -41,11 +41,9 @@
#define MAX_TIME_OFFSET 128 #define MAX_TIME_OFFSET 128
#define TRACK_MAX_LOST 100 #define TRACK_MAX_LOST 10
#define TRACK_FRAME_SIZE 32 #define TRACK_FRAME_SIZE 32
#define FIND_NOF_AVG_FRAMES 4 #define FIND_NOF_AVG_FRAMES 4
#define DEFAULT_SAMPLE_OFFSET_CORRECT_PERIOD 0
#define DEFAULT_SFO_EMA_COEFF 0.1
cf_t dummy_buffer0[15*2048/2]; cf_t dummy_buffer0[15*2048/2];
@ -386,7 +384,7 @@ int srslte_ue_sync_set_cell(srslte_ue_sync_t *q, srslte_cell_t cell)
srslte_sync_set_em_alpha(&q->sfind, 1); srslte_sync_set_em_alpha(&q->sfind, 1);
srslte_sync_set_threshold(&q->sfind, 3.0); srslte_sync_set_threshold(&q->sfind, 3.0);
srslte_sync_set_em_alpha(&q->strack, 0.2); srslte_sync_set_em_alpha(&q->strack, 0.0);
srslte_sync_set_threshold(&q->strack, 1.2); srslte_sync_set_threshold(&q->strack, 1.2);
} }
@ -464,14 +462,14 @@ void srslte_ue_sync_set_cfo_tol(srslte_ue_sync_t *q, float cfo_tol) {
} }
float srslte_ue_sync_get_sfo(srslte_ue_sync_t *q) { float srslte_ue_sync_get_sfo(srslte_ue_sync_t *q) {
return q->mean_sfo/5e-3; return q->mean_sample_offset/5e-3;
} }
int srslte_ue_sync_get_last_sample_offset(srslte_ue_sync_t *q) { int srslte_ue_sync_get_last_sample_offset(srslte_ue_sync_t *q) {
return q->last_sample_offset; return q->last_sample_offset;
} }
void srslte_ue_sync_set_sample_offset_correct_period(srslte_ue_sync_t *q, uint32_t nof_subframes) { void srslte_ue_sync_set_sfo_correct_period(srslte_ue_sync_t *q, uint32_t nof_subframes) {
q->sample_offset_correct_period = nof_subframes; q->sample_offset_correct_period = nof_subframes;
} }
@ -563,7 +561,7 @@ static int track_peak_ok(srslte_ue_sync_t *q, uint32_t track_idx) {
uint32_t frame_idx = 0; uint32_t frame_idx = 0;
if (q->sample_offset_correct_period) { if (q->sample_offset_correct_period) {
frame_idx = q->frame_ok_cnt%q->sample_offset_correct_period; frame_idx = q->frame_ok_cnt%q->sample_offset_correct_period;
q->mean_sample_offset += (float) q->last_sample_offset/q->sample_offset_correct_period; q->mean_sample_offset = SRSLTE_VEC_EMA((float) q->last_sample_offset, q->mean_sample_offset, q->sfo_ema);
} else { } else {
q->mean_sample_offset = q->last_sample_offset; q->mean_sample_offset = q->last_sample_offset;
} }
@ -590,22 +588,11 @@ static int track_peak_ok(srslte_ue_sync_t *q, uint32_t track_idx) {
// Adjust RF sampling time based on the mean sampling offset // Adjust RF sampling time based on the mean sampling offset
q->next_rf_sample_offset = (int) round(q->mean_sample_offset); q->next_rf_sample_offset = (int) round(q->mean_sample_offset);
// Reset PSS averaging if correcting every a period longer than 1
if (q->sample_offset_correct_period > 1) {
srslte_sync_reset(&q->strack);
}
// Compute SFO based on mean sample offset
if (q->sample_offset_correct_period) {
q->mean_sample_offset /= q->sample_offset_correct_period;
}
q->mean_sfo = SRSLTE_VEC_EMA(q->mean_sample_offset, q->mean_sfo, q->sfo_ema);
if (q->next_rf_sample_offset) { if (q->next_rf_sample_offset) {
INFO("Time offset adjustment: %d samples (%.2f), mean SFO: %.2f Hz, %.5f samples/5-sf, ema=%f, length=%d\n", INFO("Time offset adjustment: %d samples (%.2f), mean SFO: %.2f Hz, ema=%f, length=%d\n",
q->next_rf_sample_offset, q->mean_sample_offset, q->next_rf_sample_offset, q->mean_sample_offset,
srslte_ue_sync_get_sfo(q), srslte_ue_sync_get_sfo(q),
q->mean_sfo, q->sfo_ema, q->sample_offset_correct_period); q->sfo_ema, q->sample_offset_correct_period);
} }
q->mean_sample_offset = 0; q->mean_sample_offset = 0;
} }

@ -65,7 +65,6 @@ public:
float cur_radio_power; float cur_radio_power;
float cur_pusch_power; float cur_pusch_power;
float avg_rsrp; float avg_rsrp;
float avg_rsrp_cqi;
float avg_rsrp_dbm; float avg_rsrp_dbm;
float avg_rsrq_db; float avg_rsrq_db;
float avg_rssi_dbm; float avg_rssi_dbm;

@ -187,6 +187,14 @@ void parse_args(all_args_t *args, int argc, char *argv[]) {
bpo::value<int>(&args->expert.phy.cqi_fixed)->default_value(-1), bpo::value<int>(&args->expert.phy.cqi_fixed)->default_value(-1),
"Fixes the reported CQI to a constant value. Default disabled.") "Fixes the reported CQI to a constant value. Default disabled.")
("expert.sfo_correct_period",
bpo::value<uint32_t>(&args->expert.phy.sfo_correct_period)->default_value(DEFAULT_SAMPLE_OFFSET_CORRECT_PERIOD),
"Period in ms to correct sample time")
("expert.sfo_emma",
bpo::value<float>(&args->expert.phy.sfo_ema)->default_value(DEFAULT_SFO_EMA_COEFF),
"EMA coefficient to average sample offsets used to compute SFO")
("expert.snr_ema_coeff", ("expert.snr_ema_coeff",
bpo::value<float>(&args->expert.phy.snr_ema_coeff)->default_value(0.1), bpo::value<float>(&args->expert.phy.snr_ema_coeff)->default_value(0.1),
"Sets the SNR exponential moving average coefficient (Default 0.1)") "Sets the SNR exponential moving average coefficient (Default 0.1)")

@ -344,7 +344,6 @@ void phch_common::reset() {
cur_pusch_power = 0; cur_pusch_power = 0;
avg_snr_db_cqi = 0; avg_snr_db_cqi = 0;
avg_rsrp = 0; avg_rsrp = 0;
avg_rsrp_cqi = 0;
avg_rsrp_dbm = 0; avg_rsrp_dbm = 0;
avg_rsrq_db = 0; avg_rsrq_db = 0;

@ -683,6 +683,10 @@ void phch_recv::set_ue_sync_opts(srslte_ue_sync_t *q, float cfo)
srslte_sync_set_cfo_cp_enable(&q->sfind, false, 0); srslte_sync_set_cfo_cp_enable(&q->sfind, false, 0);
} }
// Set SFO ema and correct period
srslte_ue_sync_set_sfo_correct_period(q, worker_com->args->sfo_correct_period);
srslte_ue_sync_set_sfo_ema(q, worker_com->args->sfo_ema);
sss_alg_t sss_alg = SSS_FULL; sss_alg_t sss_alg = SSS_FULL;
if (!worker_com->args->sss_algorithm.compare("diff")) { if (!worker_com->args->sss_algorithm.compare("diff")) {
sss_alg = SSS_DIFF; sss_alg = SSS_DIFF;

@ -407,7 +407,7 @@ void phch_worker::work_imp()
update_measurements(); update_measurements();
if (chest_ok) { if (chest_ok) {
if (phy->avg_rsrp_dbm > -130.0 && phy->avg_snr_db_cqi > 0.0) { if (phy->avg_rsrp_dbm > -130.0 && phy->avg_snr_db_cqi > -6.0) {
log_h->debug("SNR=%.1f dB, RSRP=%.1f dBm sync=in-sync from channel estimator\n", log_h->debug("SNR=%.1f dB, RSRP=%.1f dBm sync=in-sync from channel estimator\n",
phy->avg_snr_db_cqi, phy->avg_rsrp_dbm); phy->avg_snr_db_cqi, phy->avg_rsrp_dbm);
chest_loop->in_sync(); chest_loop->in_sync();
@ -1433,7 +1433,7 @@ void phch_worker::update_measurements()
} }
// Average RSRP taken from CRS // Average RSRP taken from CRS
float rsrp_lin = srslte_chest_dl_get_rsrp_neighbour(&ue_dl.chest); float rsrp_lin = srslte_chest_dl_get_rsrp(&ue_dl.chest);
if (isnormal(rsrp_lin)) { if (isnormal(rsrp_lin)) {
if (!phy->avg_rsrp) { if (!phy->avg_rsrp) {
phy->avg_rsrp = SRSLTE_VEC_EMA(rsrp_lin, phy->avg_rsrp, snr_ema_coeff); phy->avg_rsrp = SRSLTE_VEC_EMA(rsrp_lin, phy->avg_rsrp, snr_ema_coeff);
@ -1473,17 +1473,7 @@ void phch_worker::update_measurements()
} }
} }
// To compute CQI use RSRP measurements from resource elements in RS since is more robust to time offset phy->avg_snr_db_cqi = 10*log10(phy->avg_rsrp/phy->avg_noise);
float rsrp_lin_cqi = srslte_chest_dl_get_rsrp(&ue_dl.chest);
if (isnormal(rsrp_lin_cqi)) {
if (!phy->avg_rsrp_cqi) {
phy->avg_rsrp_cqi = SRSLTE_VEC_EMA(rsrp_lin_cqi, phy->avg_rsrp_cqi, snr_ema_coeff);
} else {
phy->avg_rsrp_cqi = rsrp_lin_cqi;
}
}
phy->avg_snr_db_cqi = 10*log10(phy->avg_rsrp_cqi/phy->avg_noise);
// Store metrics // Store metrics
dl_metrics.n = phy->avg_noise; dl_metrics.n = phy->avg_noise;

@ -153,6 +153,8 @@ enable = false
# good for long channels. For best performance at highest SNR reduce it to 1. # good for long channels. For best performance at highest SNR reduce it to 1.
# sfo_correct_disable: Disables phase correction before channel estimation to compensate for # sfo_correct_disable: Disables phase correction before channel estimation to compensate for
# sampling frequency offset. Default is enabled. # sampling frequency offset. Default is enabled.
# sfo_ema: EMA coefficient to average sample offsets used to compute SFO
# sfo_correct_period: Period in ms to correct sample time to adjust for SFO
# sss_algorithm: Selects the SSS estimation algorithm. Can choose between # sss_algorithm: Selects the SSS estimation algorithm. Can choose between
# {full, partial, diff}. # {full, partial, diff}.
# estimator_fil_auto: The channel estimator smooths the channel estimate with an adaptative filter. # estimator_fil_auto: The channel estimator smooths the channel estimate with an adaptative filter.
@ -210,6 +212,8 @@ enable = false
#equalizer_mode = mmse #equalizer_mode = mmse
#time_correct_period = 5 #time_correct_period = 5
#sfo_correct_disable = false #sfo_correct_disable = false
#sfo_ema = 0.1
#sfo_correct_period = 10
#sss_algorithm = full #sss_algorithm = full
#estimator_fil_auto = false #estimator_fil_auto = false
#estimator_fil_stddev = 1.0 #estimator_fil_stddev = 1.0

Loading…
Cancel
Save