Added waterfall plot to pdsch_ue

master
ismagom 10 years ago
parent 94305004f1
commit 359b8dcd72

@ -38,7 +38,7 @@ extern "C" {
typedef void* plot_waterfall_t; typedef void* plot_waterfall_t;
LIBLTE_API int plot_waterfall_init(plot_waterfall_t *h); LIBLTE_API int plot_waterfall_init(plot_waterfall_t *h, int numDataPoints, int numRows);
LIBLTE_API void plot_waterfall_setTitle(plot_waterfall_t *h, char *title); LIBLTE_API void plot_waterfall_setTitle(plot_waterfall_t *h, char *title);
LIBLTE_API void plot_waterfall_appendNewData(plot_waterfall_t *h, float *data, LIBLTE_API void plot_waterfall_appendNewData(plot_waterfall_t *h, float *data,
int num_points); int num_points);

@ -394,8 +394,8 @@ int update_control() {
} }
} }
#define DATA_BUFF_SZ 10000 #define DATA_BUFF_SZ 1000
uint8_t data[DATA_BUFF_SZ], data_unpacked[DATA_BUFF_SZ]; uint8_t data[8*DATA_BUFF_SZ], data_unpacked[DATA_BUFF_SZ];
uint8_t data_tmp[DATA_BUFF_SZ]; uint8_t data_tmp[DATA_BUFF_SZ];
/** Function run in a separate thread to receive UDP data */ /** Function run in a separate thread to receive UDP data */
@ -414,7 +414,7 @@ void *net_thread_fnc(void *arg) {
// wait for packet to be transmitted // wait for packet to be transmitted
sem_wait(&net_sem); sem_wait(&net_sem);
bit_pack_vector(&data_unpacked[wpm], data, nbytes*8); bit_pack_vector(&data_unpacked[wpm], data, nbytes*8);
printf("Sent %d/%d bytes ready\n", nbytes, rpm); INFO("Sent %d/%d bytes ready\n", nbytes, rpm);
rpm -= nbytes; rpm -= nbytes;
wpm += nbytes; wpm += nbytes;
net_packet_ready = true; net_packet_ready = true;

@ -40,9 +40,12 @@
#include "liblte/phy/phy.h" #include "liblte/phy/phy.h"
#include "liblte/cuhd/cuhd.h" #include "liblte/cuhd/cuhd.h"
#include "cuhd_utils.h" #include "cuhd_utils.h"
#include "liblte/graphics/plot/plot_waterfall.h"
#define STDOUT_COMPACT
#ifndef DISABLE_GRAPHICS #ifndef DISABLE_GRAPHICS
void init_plots(); void init_plots(lte_cell_t cell);
void do_plots(ue_dl_t *q, uint32_t sf_idx, ue_sync_t *qs); void do_plots(ue_dl_t *q, uint32_t sf_idx, ue_sync_t *qs);
#endif #endif
@ -72,6 +75,8 @@ typedef struct {
float uhd_gain; float uhd_gain;
int net_port; int net_port;
char *net_address; char *net_address;
int net_port_signal;
char *net_address_signal;
}prog_args_t; }prog_args_t;
void args_default(prog_args_t *args) { void args_default(prog_args_t *args) {
@ -83,6 +88,8 @@ void args_default(prog_args_t *args) {
args->uhd_gain = 60.0; args->uhd_gain = 60.0;
args->net_port = -1; args->net_port = -1;
args->net_address = "127.0.0.1"; args->net_address = "127.0.0.1";
args->net_port_signal = -1;
args->net_address_signal = "127.0.0.1";
} }
void usage(prog_args_t *args, char *prog) { void usage(prog_args_t *args, char *prog) {
@ -97,6 +104,8 @@ void usage(prog_args_t *args, char *prog) {
printf("\t plots are disabled. Graphics library not available\n"); printf("\t plots are disabled. Graphics library not available\n");
#endif #endif
printf("\t-n nof_subframes [Default %d]\n", args->nof_subframes); printf("\t-n nof_subframes [Default %d]\n", args->nof_subframes);
printf("\t-s remote UDP port to send input signal (-1 does nothing with it) [Default %d]\n", args->net_port_signal);
printf("\t-S remote UDP address to send input signal [Default %s]\n", args->net_address_signal);
printf("\t-u remote UDP port to send data (-1 does nothing with it) [Default %d]\n", args->net_port); printf("\t-u remote UDP port to send data (-1 does nothing with it) [Default %d]\n", args->net_port);
printf("\t-U remote UDP address to send data [Default %s]\n", args->net_address); printf("\t-U remote UDP address to send data [Default %s]\n", args->net_address);
printf("\t-v [set verbose to debug, default none]\n"); printf("\t-v [set verbose to debug, default none]\n");
@ -105,7 +114,7 @@ void usage(prog_args_t *args, char *prog) {
void parse_args(prog_args_t *args, int argc, char **argv) { void parse_args(prog_args_t *args, int argc, char **argv) {
int opt; int opt;
args_default(args); args_default(args);
while ((opt = getopt(argc, argv, "agldnvrfuU")) != -1) { while ((opt = getopt(argc, argv, "agldnvrfuUsS")) != -1) {
switch (opt) { switch (opt) {
case 'a': case 'a':
args->uhd_args = argv[optind]; args->uhd_args = argv[optind];
@ -131,6 +140,12 @@ void parse_args(prog_args_t *args, int argc, char **argv) {
case 'U': case 'U':
args->net_address = argv[optind]; args->net_address = argv[optind];
break; break;
case 's':
args->net_port_signal = atoi(argv[optind]);
break;
case 'S':
args->net_address_signal = argv[optind];
break;
case 'd': case 'd':
args->disable_plots = true; args->disable_plots = true;
break; break;
@ -186,7 +201,7 @@ int main(int argc, char **argv) {
int n; int n;
uint8_t bch_payload[BCH_PAYLOAD_LEN], bch_payload_unpacked[BCH_PAYLOAD_LEN]; uint8_t bch_payload[BCH_PAYLOAD_LEN], bch_payload_unpacked[BCH_PAYLOAD_LEN];
uint32_t sfn_offset; uint32_t sfn_offset;
netsink_t net_sink; netsink_t net_sink, net_sink_signal;
parse_args(&prog_args, argc, argv); parse_args(&prog_args, argc, argv);
@ -196,7 +211,12 @@ int main(int argc, char **argv) {
exit(-1); exit(-1);
} }
} }
if (prog_args.net_port_signal > 0) {
if (netsink_init(&net_sink_signal, prog_args.net_address_signal, prog_args.net_port_signal, NETSINK_UDP)) {
fprintf(stderr, "Error initiating UDP socket to %s:%d\n", prog_args.net_address_signal, prog_args.net_port_signal);
exit(-1);
}
}
printf("Opening UHD device...\n"); printf("Opening UHD device...\n");
if (cuhd_open(prog_args.uhd_args, &uhd)) { if (cuhd_open(prog_args.uhd_args, &uhd)) {
fprintf(stderr, "Error opening uhd\n"); fprintf(stderr, "Error opening uhd\n");
@ -256,7 +276,7 @@ int main(int argc, char **argv) {
#ifndef DISABLE_GRAPHICS #ifndef DISABLE_GRAPHICS
if (!prog_args.disable_plots) { if (!prog_args.disable_plots) {
init_plots(); init_plots(cell);
} }
#endif #endif
@ -274,6 +294,13 @@ int main(int argc, char **argv) {
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "Error calling ue_sync_work()\n"); fprintf(stderr, "Error calling ue_sync_work()\n");
} }
if (prog_args.net_port_signal > 0) {
if (netsink_write(&net_sink_signal, sf_buffer, ue_sync_sf_len(&ue_sync)) < 0) {
fprintf(stderr, "Error sending data through UDP socket\n");
perror("write");
}
}
/* ue_sync_get_buffer returns 1 if successfully read 1 aligned subframe */ /* ue_sync_get_buffer returns 1 if successfully read 1 aligned subframe */
if (ret == 1) { if (ret == 1) {
@ -314,7 +341,6 @@ int main(int argc, char **argv) {
} }
if (n < 0) { if (n < 0) {
fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); fprintf(stderr, "Error decoding UE DL\n");fflush(stdout);
exit(-1);
} else if (n > 0) { } else if (n > 0) {
/* Send data if socket active */ /* Send data if socket active */
if (prog_args.net_port > 0) { if (prog_args.net_port > 0) {
@ -337,6 +363,11 @@ int main(int argc, char **argv) {
// Plot and Printf // Plot and Printf
if (ue_sync_get_sfidx(&ue_sync) == 5) { if (ue_sync_get_sfidx(&ue_sync) == 5) {
#ifdef STDOUT_COMPACT
printf("PDCCH-Miss: %5.2f%%, PDSCH-BLER: %5.2f%% (%d blocks)\r",
100*(1-(float) ue_dl.nof_pdcch_detected/nof_trials),
(float) 100*ue_dl.pkt_errors/ue_dl.pkts_total,nof_trials, ue_dl.pkts_total);
#else
printf("CFO: %+8.4f KHz, SFO: %+8.4f Khz, " printf("CFO: %+8.4f KHz, SFO: %+8.4f Khz, "
"RSRP: %+5.1f dBm, RSRQ: %5.1f dB, SNR: %4.1f dB, " "RSRP: %+5.1f dBm, RSRQ: %5.1f dB, SNR: %4.1f dB, "
"PDCCH-Miss: %5.2f%%, PDSCH-BLER: %5.2f%% (%d blocks)\r", "PDCCH-Miss: %5.2f%%, PDSCH-BLER: %5.2f%% (%d blocks)\r",
@ -345,6 +376,8 @@ int main(int argc, char **argv) {
10*log10(rsrq), 10*log10(snr), 10*log10(rsrq), 10*log10(snr),
100*(1-(float) ue_dl.nof_pdcch_detected/nof_trials), 100*(1-(float) ue_dl.nof_pdcch_detected/nof_trials),
(float) 100*ue_dl.pkt_errors/ue_dl.pkts_total,nof_trials, ue_dl.pkts_total); (float) 100*ue_dl.pkt_errors/ue_dl.pkts_total,nof_trials, ue_dl.pkts_total);
#endif
} }
break; break;
} }
@ -355,8 +388,8 @@ int main(int argc, char **argv) {
} }
} }
#ifndef DISABLE_GRAPHICS #ifndef DISABLE_GRAPHICS
if (!prog_args.disable_plots && ue_sync_get_sfidx(&ue_sync) == 5) { if (!prog_args.disable_plots) {
do_plots(&ue_dl, 5, &ue_sync); do_plots(&ue_dl, ue_sync_get_sfidx(&ue_sync), &ue_sync);
} }
#endif #endif
} else if (ret == 0) { } else if (ret == 0) {
@ -390,20 +423,20 @@ int main(int argc, char **argv) {
#include "liblte/graphics/plot.h" #include "liblte/graphics/plot.h"
plot_real_t poutfft, p_sync; plot_waterfall_t poutfft;
plot_real_t pce; plot_real_t p_sync, pce;
plot_scatter_t pscatequal, pscatequal_pdcch; plot_scatter_t pscatequal, pscatequal_pdcch;
float tmp_plot[SLOT_LEN_RE(MAX_PRB, CPNORM)]; float tmp_plot[SLOT_LEN_RE(MAX_PRB, CPNORM)];
float tmp_plot2[SLOT_LEN_RE(MAX_PRB, CPNORM)]; float tmp_plot2[SLOT_LEN_RE(MAX_PRB, CPNORM)];
float tmp_plot3[SLOT_LEN_RE(MAX_PRB, CPNORM)]; float tmp_plot3[SLOT_LEN_RE(MAX_PRB, CPNORM)];
void init_plots() { void init_plots(lte_cell_t cell) {
plot_init(); plot_init();
plot_real_init(&poutfft);
plot_real_setTitle(&poutfft, "Output FFT - Magnitude"); plot_waterfall_init(&poutfft, RE_X_RB * cell.nof_prb, 5000);
plot_real_setLabels(&poutfft, "Index", "dB"); plot_waterfall_setTitle(&poutfft, "Output FFT - Magnitude");
plot_real_setYAxisScale(&poutfft, -40, 40); plot_waterfall_setPlotYAxisScale(&poutfft, -40, 40);
plot_real_init(&pce); plot_real_init(&pce);
plot_real_setTitle(&pce, "Channel Response - Magnitude"); plot_real_setTitle(&pce, "Channel Response - Magnitude");
@ -428,7 +461,7 @@ void init_plots() {
void do_plots(ue_dl_t *q, uint32_t sf_idx, ue_sync_t *qs) { void do_plots(ue_dl_t *q, uint32_t sf_idx, ue_sync_t *qs) {
int i; int i;
uint32_t nof_re = SLOT_LEN_RE(q->cell.nof_prb, q->cell.cp); uint32_t nof_re = SF_LEN_RE(q->cell.nof_prb, q->cell.cp);
uint32_t nof_symbols = q->harq_process[0].prb_alloc.re_sf[sf_idx]; uint32_t nof_symbols = q->harq_process[0].prb_alloc.re_sf[sf_idx];
for (i = 0; i < nof_re; i++) { for (i = 0; i < nof_re; i++) {
tmp_plot[i] = 20 * log10f(cabsf(q->sf_symbols[i])); tmp_plot[i] = 20 * log10f(cabsf(q->sf_symbols[i]));
@ -442,7 +475,9 @@ void do_plots(ue_dl_t *q, uint32_t sf_idx, ue_sync_t *qs) {
tmp_plot2[i] = -80; tmp_plot2[i] = -80;
} }
} }
plot_real_setNewData(&poutfft, tmp_plot, nof_re); for (i=0;i<CP_NSYMB(q->cell.cp);i++) {
plot_waterfall_appendNewData(&poutfft, &tmp_plot[i*RE_X_RB*q->cell.nof_prb], RE_X_RB*q->cell.nof_prb);
}
plot_real_setNewData(&pce, tmp_plot2, REFSIGNAL_NUM_SF(q->cell.nof_prb,0)); plot_real_setNewData(&pce, tmp_plot2, REFSIGNAL_NUM_SF(q->cell.nof_prb,0));
int max = vec_max_fi(qs->strack.pss.conv_output_avg, qs->strack.pss.frame_size+qs->strack.pss.fft_size-1); int max = vec_max_fi(qs->strack.pss.conv_output_avg, qs->strack.pss.frame_size+qs->strack.pss.fft_size-1);
vec_sc_prod_fff(qs->strack.pss.conv_output_avg, vec_sc_prod_fff(qs->strack.pss.conv_output_avg,

@ -115,14 +115,15 @@ int chest_dl_init(chest_dl_t *q, lte_cell_t cell)
} }
/* Set default time/freq filters */ /* Set default time/freq filters */
//float f[3]={0.1, 0.8, 0.1}; float f[3]={0.1, 0.8, 0.1};
//chest_dl_set_filter_freq(q, f, 3); chest_dl_set_filter_freq(q, f, 3);
float f[5]={0.05, 0.15, 0.6, 0.15, 0.05}; //float f[5]={0.05, 0.15, 0.6, 0.15, 0.05};
chest_dl_set_filter_freq(q, f, 5); //chest_dl_set_filter_freq(q, f, 5);
float t[2]={0.1, 0.9}; //float t[2]={0.1, 0.9};
chest_dl_set_filter_time(q, t, 2); float t[1] = {1.0};
chest_dl_set_filter_time(q, t, 1);
q->cell = cell; q->cell = cell;
} }

@ -250,10 +250,12 @@ int track_peak_ok(ue_sync_t *q, uint32_t track_idx) {
/* If the PSS peak is beyond the frame (we sample too slowly), /* If the PSS peak is beyond the frame (we sample too slowly),
discard the offseted samples to align next frame */ discard the offseted samples to align next frame */
if (q->time_offset > 0 && q->time_offset < MAX_TIME_OFFSET) { if (q->time_offset > 0 && q->time_offset < MAX_TIME_OFFSET) {
INFO("Positive time offset %d samples. Adjusting now.\n", q->time_offset);
if (q->recv_callback(q->stream, dummy, (uint32_t) q->time_offset) < 0) { if (q->recv_callback(q->stream, dummy, (uint32_t) q->time_offset) < 0) {
fprintf(stderr, "Error receiving from USRP\n"); fprintf(stderr, "Error receiving from USRP\n");
return LIBLTE_ERROR; return LIBLTE_ERROR;
} }
q->time_offset = 0;
} }
/* compute cumulative moving average time offset */ /* compute cumulative moving average time offset */
@ -291,6 +293,7 @@ static int receive_samples(ue_sync_t *q) {
q->time_offset = -q->time_offset; q->time_offset = -q->time_offset;
} }
INFO("Receiving %d samples\n", q->frame_len - q->time_offset);
/* Get N subframes from the USRP getting more samples and keeping the previous samples, if any */ /* Get N subframes from the USRP getting more samples and keeping the previous samples, if any */
if (q->recv_callback(q->stream, &q->input_buffer[q->time_offset], q->frame_len - q->time_offset) < 0) { if (q->recv_callback(q->stream, &q->input_buffer[q->time_offset], q->frame_len - q->time_offset) < 0) {
return LIBLTE_ERROR; return LIBLTE_ERROR;

@ -2,16 +2,28 @@
%% Cell-Wide Settings %% Cell-Wide Settings
% A structure |enbConfig| is used to configure the eNodeB. % A structure |enbConfig| is used to configure the eNodeB.
clear %clear
Npackets = 10; Npackets = 4;
SNR_values = linspace(2,6,4); SNR_values = 1;%linspace(2,6,4);
%% Choose RMC %% Choose RMC
[waveform,rgrid,rmccFgOut] = lteRMCDLTool('R.11',[1;0;0;1]); [waveform,rgrid,rmccFgOut] = lteRMCDLTool('R.11',[1;0;0;1]);
waveform = sum(waveform,2); waveform = sum(waveform,2);
Nsf = 8; rmccFgOut = struct('NCellID',1,'CellRefP',1,'CFI',1,'NDLRB',15,'SamplingRate',3.84e6,'Nfft',256,'DuplexMode','FDD','CyclicPrefix','Normal');
rmccFgOut.PDSCH.RNTI = 1234;
rmccFgOut.PDSCH.PRBSet = repmat(transpose(0:rmccFgOut.NDLRB-1),1,2);
rmccFgOut.PDSCH.TxScheme = 'Port0';
rmccFgOut.PDSCH.NLayers = 1;
rmccFgOut.PDSCH.NTurboDecIts = 5;
rmccFgOut.PDSCH.Modulation = {'64QAM'};
rmccFgOut.PDSCH.TrBlkSizes = [0 5992*ones(1,4) 0 5992*ones(1,4)];
rmccFgOut.PDSCH.RV = 0;
flen=rmccFgOut.SamplingRate/1000;
Nsf = 9;
%% Setup Fading channel model %% Setup Fading channel model
cfg.Seed = 8; % Random channel seed cfg.Seed = 8; % Random channel seed
@ -52,12 +64,13 @@ for snr_idx=1:length(SNR_values)
%% Noise Addition %% Noise Addition
noise = N0*complex(randn(size(rxWaveform)), randn(size(rxWaveform))); % Generate noise noise = N0*complex(randn(size(rxWaveform)), randn(size(rxWaveform))); % Generate noise
rxWaveform = rxWaveform + noise; rxWaveform = rxWaveform + noise;
rxWaveform = x;
%% Demodulate %% Demodulate
frame_rx = lteOFDMDemodulate(rmccFgOut, rxWaveform); frame_rx = lteOFDMDemodulate(rmccFgOut, rxWaveform);
for sf_idx=0:Nsf for sf_idx=0:Nsf
flen=length(rxWaveform)/10;
subframe_waveform = rxWaveform(sf_idx*flen+1:(sf_idx+1)*flen); subframe_waveform = rxWaveform(sf_idx*flen+1:(sf_idx+1)*flen);
subframe_rx=frame_rx(:,sf_idx*14+1:(sf_idx+1)*14); subframe_rx=frame_rx(:,sf_idx*14+1:(sf_idx+1)*14);
rmccFgOut.NSubframe=sf_idx; rmccFgOut.NSubframe=sf_idx;
@ -83,6 +96,8 @@ for snr_idx=1:length(SNR_values)
end end
decoded_liblte(snr_idx) = decoded_liblte(snr_idx)+dec2; decoded_liblte(snr_idx) = decoded_liblte(snr_idx)+dec2;
end end
x = x(flen*10+1:end);
end end
fprintf('SNR: %.1f\n',SNRdB) fprintf('SNR: %.1f\n',SNRdB)
end end

Loading…
Cancel
Save