mirror of https://github.com/PentHertz/srsLTE.git
ue_sync: set default offset correction interval to 0. chest_dl: added option to average estimates per subframe
This commit is contained in:
parent
6a254cd077
commit
10cbb9ad92
|
@ -6,13 +6,13 @@ clear
|
||||||
|
|
||||||
plot_noise_estimation_only=false;
|
plot_noise_estimation_only=false;
|
||||||
|
|
||||||
SNR_values_db=100;%linspace(20,35,8);
|
SNR_values_db=linspace(0,20,8);
|
||||||
Nrealizations=1;
|
Nrealizations=10;
|
||||||
|
|
||||||
w1=0.1;
|
w1=0.1;
|
||||||
w2=0.3;
|
w2=0.3;
|
||||||
|
|
||||||
enb.NDLRB = 6; % Number of resource blocks
|
enb.NDLRB = 25; % Number of resource blocks
|
||||||
|
|
||||||
enb.CellRefP = 1; % One transmit antenna port
|
enb.CellRefP = 1; % One transmit antenna port
|
||||||
enb.NCellID = 0; % Cell ID
|
enb.NCellID = 0; % Cell ID
|
||||||
|
@ -181,8 +181,8 @@ for i=1:10
|
||||||
rxGrid_sf = rxGrid(:,(i-1)*14+1:i*14);
|
rxGrid_sf = rxGrid(:,(i-1)*14+1:i*14);
|
||||||
|
|
||||||
%% Channel Estimation with Matlab
|
%% Channel Estimation with Matlab
|
||||||
[hest{1}(:,(1:14)+(i-1)*14), tmpnoise{1}(i), hls(:,(1:4*P)+(i-1)*4*P)] = ...
|
[hest{1}(:,(1:14)+(i-1)*14), tmpnoise{1}(i)] = ...
|
||||||
lteDLChannelEstimate2(enb,cec,rxGrid_sf);
|
lteDLChannelEstimate(enb,cec,rxGrid_sf);
|
||||||
tmpnoise{1}(i)=tmpnoise{1}(i)*sqrt(2)*enb.CellRefP;
|
tmpnoise{1}(i)=tmpnoise{1}(i)*sqrt(2)*enb.CellRefP;
|
||||||
|
|
||||||
%% LS-Linear estimation with srsLTE
|
%% LS-Linear estimation with srsLTE
|
||||||
|
@ -227,17 +227,12 @@ if (length(SNR_values_db) == 1)
|
||||||
tmp{Ntests+1}='Real';
|
tmp{Ntests+1}='Real';
|
||||||
legend(tmp)
|
legend(tmp)
|
||||||
|
|
||||||
xlabel('SNR (dB)')
|
xlabel('Sample')
|
||||||
ylabel('Channel Gain')
|
ylabel('Channel Gain')
|
||||||
grid on;
|
grid on;
|
||||||
|
|
||||||
fprintf('Mean MMSE Robust %.2f dB\n', 10*log10(MSE(4,nreal,snr_idx)))
|
% fprintf('Mean MMSE Robust %.2f dB\n', 10*log10(MSE(4,nreal,snr_idx)))
|
||||||
fprintf('Mean MMSE matlab %.2f dB\n', 10*log10(MSE(1,nreal,snr_idx)))
|
% fprintf('Mean MMSE matlab %.2f dB\n', 10*log10(MSE(1,nreal,snr_idx)))
|
||||||
<<<<<<< HEAD
|
|
||||||
|
|
||||||
=======
|
|
||||||
|
|
||||||
>>>>>>> master
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -116,7 +116,7 @@ for snr_idx=1:length(SNR_values)
|
||||||
rmccFgOut.TotSubframes=1;
|
rmccFgOut.TotSubframes=1;
|
||||||
|
|
||||||
% Perform channel estimation
|
% Perform channel estimation
|
||||||
[hest, nest,estimates] = lteDLChannelEstimate2(rmccFgOut, cec, subframe_rx);
|
[hest, nest] = lteDLChannelEstimate(rmccFgOut, cec, subframe_rx);
|
||||||
|
|
||||||
[cws,symbols] = ltePDSCHDecode(rmccFgOut,rmccFgOut.PDSCH,subframe_rx,hest,nest);
|
[cws,symbols] = ltePDSCHDecode(rmccFgOut,rmccFgOut.PDSCH,subframe_rx,hest,nest);
|
||||||
[trblkout,blkcrc,dstate] = lteDLSCHDecode(rmccFgOut,rmccFgOut.PDSCH, ...
|
[trblkout,blkcrc,dstate] = lteDLSCHDecode(rmccFgOut,rmccFgOut.PDSCH, ...
|
||||||
|
@ -156,6 +156,7 @@ if (length(SNR_values)>1)
|
||||||
axis([min(SNR_values) max(SNR_values) 1/Npackets/(Nsf+1) 1])
|
axis([min(SNR_values) max(SNR_values) 1/Npackets/(Nsf+1) 1])
|
||||||
else
|
else
|
||||||
scatter(real(symbols{1}),imag(symbols{1}))
|
scatter(real(symbols{1}),imag(symbols{1}))
|
||||||
|
plot(
|
||||||
fprintf('Matlab: %d OK\nsrsLTE: %d OK\n',decoded, decoded_srslte);
|
fprintf('Matlab: %d OK\nsrsLTE: %d OK\n',decoded, decoded_srslte);
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -583,11 +583,13 @@ int main(int argc, char **argv) {
|
||||||
sfn++;
|
sfn++;
|
||||||
if (sfn == 1024) {
|
if (sfn == 1024) {
|
||||||
sfn = 0;
|
sfn = 0;
|
||||||
|
/*
|
||||||
printf("\n");
|
printf("\n");
|
||||||
ue_dl.pkt_errors = 0;
|
ue_dl.pkt_errors = 0;
|
||||||
ue_dl.pkts_total = 0;
|
ue_dl.pkts_total = 0;
|
||||||
ue_dl.nof_detected = 0;
|
ue_dl.nof_detected = 0;
|
||||||
nof_trials = 0;
|
nof_trials = 0;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,8 @@
|
||||||
#include "srslte/utils/vector.h"
|
#include "srslte/utils/vector.h"
|
||||||
#include "srslte/utils/convolution.h"
|
#include "srslte/utils/convolution.h"
|
||||||
|
|
||||||
|
#define AVERAGE_SUBFRAME
|
||||||
|
|
||||||
//#define DEFAULT_FILTER_LEN 3
|
//#define DEFAULT_FILTER_LEN 3
|
||||||
|
|
||||||
#ifdef DEFAULT_FILTER_LEN
|
#ifdef DEFAULT_FILTER_LEN
|
||||||
|
@ -165,7 +167,18 @@ void srslte_chest_dl_free(srslte_chest_dl_t *q)
|
||||||
/* Uses the difference between the averaged and non-averaged pilot estimates */
|
/* Uses the difference between the averaged and non-averaged pilot estimates */
|
||||||
static float estimate_noise_pilots(srslte_chest_dl_t *q, uint32_t port_id)
|
static float estimate_noise_pilots(srslte_chest_dl_t *q, uint32_t port_id)
|
||||||
{
|
{
|
||||||
|
float norm = sqrt(2);
|
||||||
|
#ifdef AVERAGE_SUBFRAME
|
||||||
|
int nref=2*q->cell.nof_prb;
|
||||||
|
#else
|
||||||
int nref=SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id);
|
int nref=SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id);
|
||||||
|
if (q->smooth_filter_len == 3) {
|
||||||
|
float a = q->smooth_filter[0];
|
||||||
|
float norm3 = 6.143*a*a+0.04859*a-0.002774;
|
||||||
|
norm /= norm3;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Substract noisy pilot estimates */
|
/* Substract noisy pilot estimates */
|
||||||
srslte_vec_sub_ccc(q->pilot_estimates_average, q->pilot_estimates, q->tmp_noise, nref);
|
srslte_vec_sub_ccc(q->pilot_estimates_average, q->pilot_estimates, q->tmp_noise, nref);
|
||||||
|
|
||||||
|
@ -179,12 +192,6 @@ static float estimate_noise_pilots(srslte_chest_dl_t *q, uint32_t port_id)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Compute average power. Normalized for filter len 3 using matlab */
|
/* Compute average power. Normalized for filter len 3 using matlab */
|
||||||
float norm = 1;
|
|
||||||
if (q->smooth_filter_len == 3) {
|
|
||||||
float a = q->smooth_filter[0];
|
|
||||||
float norm3 = 6.143*a*a+0.04859*a-0.002774;
|
|
||||||
norm /= norm3;
|
|
||||||
}
|
|
||||||
float power = norm*q->cell.nof_ports*srslte_vec_avg_power_cf(q->tmp_noise, nref);
|
float power = norm*q->cell.nof_ports*srslte_vec_avg_power_cf(q->tmp_noise, nref);
|
||||||
return power;
|
return power;
|
||||||
}
|
}
|
||||||
|
@ -225,19 +232,29 @@ static float estimate_noise_empty_sc(srslte_chest_dl_t *q, cf_t *input) {
|
||||||
|
|
||||||
static void interpolate_pilots(srslte_chest_dl_t *q, cf_t *pilot_estimates, cf_t *ce, uint32_t port_id)
|
static void interpolate_pilots(srslte_chest_dl_t *q, cf_t *pilot_estimates, cf_t *ce, uint32_t port_id)
|
||||||
{
|
{
|
||||||
/* interpolate the symbols with references in the freq domain */
|
|
||||||
uint32_t l;
|
#ifdef AVERAGE_SUBFRAME
|
||||||
|
// Interpolate symbol 0 in the frequency domain
|
||||||
|
uint32_t fidx_offset = srslte_refsignal_cs_fidx(q->cell, 0, port_id, 0);
|
||||||
|
srslte_interp_linear_offset(&q->srslte_interp_lin, pilot_estimates,
|
||||||
|
&ce[srslte_refsignal_cs_nsymbol(0,q->cell.cp, port_id) * q->cell.nof_prb * SRSLTE_NRE],
|
||||||
|
fidx_offset, SRSLTE_NRE/2-fidx_offset);
|
||||||
|
// All channel estimates in the subframe are the same
|
||||||
|
for (int l=1;l<2*SRSLTE_CP_NSYMB(q->cell.cp);l++) {
|
||||||
|
memcpy(&ce[l*q->cell.nof_prb*SRSLTE_NRE], ce, q->cell.nof_prb*SRSLTE_NRE*sizeof(cf_t));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
uint32_t l=0;
|
||||||
uint32_t nsymbols = srslte_refsignal_cs_nof_symbols(port_id);
|
uint32_t nsymbols = srslte_refsignal_cs_nof_symbols(port_id);
|
||||||
|
|
||||||
/* Interpolate in the frequency domain */
|
// Interpolate in the frequency domain
|
||||||
for (l=0;l<nsymbols;l++) {
|
for (l=0;l<nsymbols;l++) {
|
||||||
uint32_t fidx_offset = srslte_refsignal_cs_fidx(q->cell, l, port_id, 0);
|
uint32_t fidx_offset = srslte_refsignal_cs_fidx(q->cell, l, port_id, 0);
|
||||||
srslte_interp_linear_offset(&q->srslte_interp_lin, &pilot_estimates[2*q->cell.nof_prb*l],
|
srslte_interp_linear_offset(&q->srslte_interp_lin, &pilot_estimates[2*q->cell.nof_prb*l],
|
||||||
&ce[srslte_refsignal_cs_nsymbol(l,q->cell.cp, port_id) * q->cell.nof_prb * SRSLTE_NRE],
|
&ce[srslte_refsignal_cs_nsymbol(l,q->cell.cp, port_id) * q->cell.nof_prb * SRSLTE_NRE],
|
||||||
fidx_offset, SRSLTE_NRE/2-fidx_offset);
|
fidx_offset, SRSLTE_NRE/2-fidx_offset);
|
||||||
}
|
}
|
||||||
|
// Interpolate in the time domain between symbols
|
||||||
/* Now interpolate in the time domain between symbols */
|
|
||||||
if (SRSLTE_CP_ISNORM(q->cell.cp)) {
|
if (SRSLTE_CP_ISNORM(q->cell.cp)) {
|
||||||
if (nsymbols == 4) {
|
if (nsymbols == 4) {
|
||||||
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(0), &cesymb(4), &cesymb(1), 4, 3);
|
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(0), &cesymb(4), &cesymb(1), 4, 3);
|
||||||
|
@ -261,6 +278,7 @@ static void interpolate_pilots(srslte_chest_dl_t *q, cf_t *pilot_estimates, cf_t
|
||||||
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(7), &cesymb(8), 6, 4);
|
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(7), &cesymb(8), 6, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void srslte_chest_dl_set_smooth_filter(srslte_chest_dl_t *q, float *filter, uint32_t filter_len) {
|
void srslte_chest_dl_set_smooth_filter(srslte_chest_dl_t *q, float *filter, uint32_t filter_len) {
|
||||||
|
@ -293,9 +311,17 @@ static void average_pilots(srslte_chest_dl_t *q, cf_t *input, cf_t *output, uint
|
||||||
uint32_t nsymbols = srslte_refsignal_cs_nof_symbols(port_id);
|
uint32_t nsymbols = srslte_refsignal_cs_nof_symbols(port_id);
|
||||||
uint32_t nref = 2*q->cell.nof_prb;
|
uint32_t nref = 2*q->cell.nof_prb;
|
||||||
|
|
||||||
for (int l=0;l<nsymbols;l++) {
|
memcpy(output, input, nref*sizeof(cf_t));
|
||||||
|
for (int l=1;l<nsymbols;l++) {
|
||||||
|
#ifdef AVERAGE_SUBFRAME
|
||||||
|
srslte_vec_sum_ccc(output, &input[l*nref], output, nref);
|
||||||
|
#else
|
||||||
srslte_conv_same_cf(&input[l*nref], q->smooth_filter, &output[l*nref], nref, q->smooth_filter_len);
|
srslte_conv_same_cf(&input[l*nref], q->smooth_filter, &output[l*nref], nref, q->smooth_filter_len);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
#ifdef AVERAGE_SUBFRAME
|
||||||
|
srslte_vec_sc_prod_cfc(output, (float) 1.0/nsymbols, output, nref);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
float srslte_chest_dl_rssi(srslte_chest_dl_t *q, cf_t *input, uint32_t port_id) {
|
float srslte_chest_dl_rssi(srslte_chest_dl_t *q, cf_t *input, uint32_t port_id) {
|
||||||
|
|
|
@ -44,7 +44,7 @@ cf_t dummy[MAX_TIME_OFFSET];
|
||||||
#define TRACK_MAX_LOST 4
|
#define TRACK_MAX_LOST 4
|
||||||
#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 5
|
#define DEFAULT_SAMPLE_OFFSET_CORRECT_PERIOD 0
|
||||||
#define DEFAULT_SFO_EMA_COEFF 0.1
|
#define DEFAULT_SFO_EMA_COEFF 0.1
|
||||||
|
|
||||||
cf_t dummy_offset_buffer[1024*1024];
|
cf_t dummy_offset_buffer[1024*1024];
|
||||||
|
@ -358,7 +358,6 @@ static int track_peak_ok(srslte_ue_sync_t *q, uint32_t track_idx) {
|
||||||
{
|
{
|
||||||
INFO("Warning: Expected SF idx %d but got %d! (%d frames)\n",
|
INFO("Warning: Expected SF idx %d but got %d! (%d frames)\n",
|
||||||
q->sf_idx, srslte_sync_get_sf_idx(&q->strack), q->frame_no_cnt);
|
q->sf_idx, srslte_sync_get_sf_idx(&q->strack), q->frame_no_cnt);
|
||||||
q->sf_idx = srslte_sync_get_sf_idx(&q->strack);
|
|
||||||
q->frame_no_cnt++;
|
q->frame_no_cnt++;
|
||||||
if (q->frame_no_cnt >= TRACK_MAX_LOST) {
|
if (q->frame_no_cnt >= TRACK_MAX_LOST) {
|
||||||
INFO("\n%d frames lost. Going back to FIND\n", (int) q->frame_no_cnt);
|
INFO("\n%d frames lost. Going back to FIND\n", (int) q->frame_no_cnt);
|
||||||
|
@ -382,18 +381,19 @@ static int track_peak_ok(srslte_ue_sync_t *q, uint32_t track_idx) {
|
||||||
|
|
||||||
// Compute cumulative moving average time offset */
|
// Compute cumulative moving average time offset */
|
||||||
if (!frame_idx) {
|
if (!frame_idx) {
|
||||||
// Adjust RF sampling time based on the mean sampling 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) {
|
if (q->sample_offset_correct_period) {
|
||||||
|
// Adjust RF sampling time based on the mean sampling 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
|
||||||
q->mean_sample_offset /= q->sample_offset_correct_period;
|
q->mean_sample_offset /= q->sample_offset_correct_period;
|
||||||
|
} else {
|
||||||
|
q->next_rf_sample_offset = q->last_sample_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
q->mean_sfo = SRSLTE_VEC_EMA(q->mean_sample_offset, q->mean_sfo, q->sfo_ema);
|
q->mean_sfo = SRSLTE_VEC_EMA(q->mean_sample_offset, q->mean_sfo, q->sfo_ema);
|
||||||
|
|
||||||
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, %.5f samples/5-sf, ema=%f, length=%d\n",
|
||||||
|
|
Loading…
Reference in New Issue