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;
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_appendNewData(plot_waterfall_t *h, float *data,
int num_points);

@ -394,8 +394,8 @@ int update_control() {
}
}
#define DATA_BUFF_SZ 10000
uint8_t data[DATA_BUFF_SZ], data_unpacked[DATA_BUFF_SZ];
#define DATA_BUFF_SZ 1000
uint8_t data[8*DATA_BUFF_SZ], data_unpacked[DATA_BUFF_SZ];
uint8_t data_tmp[DATA_BUFF_SZ];
/** 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
sem_wait(&net_sem);
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;
wpm += nbytes;
net_packet_ready = true;

@ -40,9 +40,12 @@
#include "liblte/phy/phy.h"
#include "liblte/cuhd/cuhd.h"
#include "cuhd_utils.h"
#include "liblte/graphics/plot/plot_waterfall.h"
#define STDOUT_COMPACT
#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);
#endif
@ -72,6 +75,8 @@ typedef struct {
float uhd_gain;
int net_port;
char *net_address;
int net_port_signal;
char *net_address_signal;
}prog_args_t;
void args_default(prog_args_t *args) {
@ -83,6 +88,8 @@ void args_default(prog_args_t *args) {
args->uhd_gain = 60.0;
args->net_port = -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) {
@ -97,6 +104,8 @@ void usage(prog_args_t *args, char *prog) {
printf("\t plots are disabled. Graphics library not available\n");
#endif
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 address to send data [Default %s]\n", args->net_address);
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) {
int opt;
args_default(args);
while ((opt = getopt(argc, argv, "agldnvrfuU")) != -1) {
while ((opt = getopt(argc, argv, "agldnvrfuUsS")) != -1) {
switch (opt) {
case 'a':
args->uhd_args = argv[optind];
@ -131,6 +140,12 @@ void parse_args(prog_args_t *args, int argc, char **argv) {
case 'U':
args->net_address = argv[optind];
break;
case 's':
args->net_port_signal = atoi(argv[optind]);
break;
case 'S':
args->net_address_signal = argv[optind];
break;
case 'd':
args->disable_plots = true;
break;
@ -186,7 +201,7 @@ int main(int argc, char **argv) {
int n;
uint8_t bch_payload[BCH_PAYLOAD_LEN], bch_payload_unpacked[BCH_PAYLOAD_LEN];
uint32_t sfn_offset;
netsink_t net_sink;
netsink_t net_sink, net_sink_signal;
parse_args(&prog_args, argc, argv);
@ -196,7 +211,12 @@ int main(int argc, char **argv) {
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");
if (cuhd_open(prog_args.uhd_args, &uhd)) {
fprintf(stderr, "Error opening uhd\n");
@ -256,7 +276,7 @@ int main(int argc, char **argv) {
#ifndef DISABLE_GRAPHICS
if (!prog_args.disable_plots) {
init_plots();
init_plots(cell);
}
#endif
@ -274,6 +294,13 @@ int main(int argc, char **argv) {
if (ret < 0) {
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 */
if (ret == 1) {
@ -314,7 +341,6 @@ int main(int argc, char **argv) {
}
if (n < 0) {
fprintf(stderr, "Error decoding UE DL\n");fflush(stdout);
exit(-1);
} else if (n > 0) {
/* Send data if socket active */
if (prog_args.net_port > 0) {
@ -337,6 +363,11 @@ int main(int argc, char **argv) {
// Plot and Printf
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, "
"RSRP: %+5.1f dBm, RSRQ: %5.1f dB, SNR: %4.1f dB, "
"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),
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);
#endif
}
break;
}
@ -355,8 +388,8 @@ int main(int argc, char **argv) {
}
}
#ifndef DISABLE_GRAPHICS
if (!prog_args.disable_plots && ue_sync_get_sfidx(&ue_sync) == 5) {
do_plots(&ue_dl, 5, &ue_sync);
if (!prog_args.disable_plots) {
do_plots(&ue_dl, ue_sync_get_sfidx(&ue_sync), &ue_sync);
}
#endif
} else if (ret == 0) {
@ -390,20 +423,20 @@ int main(int argc, char **argv) {
#include "liblte/graphics/plot.h"
plot_real_t poutfft, p_sync;
plot_real_t pce;
plot_waterfall_t poutfft;
plot_real_t p_sync, pce;
plot_scatter_t pscatequal, pscatequal_pdcch;
float tmp_plot[SLOT_LEN_RE(MAX_PRB, CPNORM)];
float tmp_plot2[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_real_init(&poutfft);
plot_real_setTitle(&poutfft, "Output FFT - Magnitude");
plot_real_setLabels(&poutfft, "Index", "dB");
plot_real_setYAxisScale(&poutfft, -40, 40);
plot_waterfall_init(&poutfft, RE_X_RB * cell.nof_prb, 5000);
plot_waterfall_setTitle(&poutfft, "Output FFT - Magnitude");
plot_waterfall_setPlotYAxisScale(&poutfft, -40, 40);
plot_real_init(&pce);
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) {
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];
for (i = 0; i < nof_re; 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;
}
}
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));
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,

@ -115,14 +115,15 @@ int chest_dl_init(chest_dl_t *q, lte_cell_t cell)
}
/* Set default time/freq filters */
//float f[3]={0.1, 0.8, 0.1};
//chest_dl_set_filter_freq(q, f, 3);
float f[3]={0.1, 0.8, 0.1};
chest_dl_set_filter_freq(q, f, 3);
float f[5]={0.05, 0.15, 0.6, 0.15, 0.05};
chest_dl_set_filter_freq(q, f, 5);
//float f[5]={0.05, 0.15, 0.6, 0.15, 0.05};
//chest_dl_set_filter_freq(q, f, 5);
float t[2]={0.1, 0.9};
chest_dl_set_filter_time(q, t, 2);
//float t[2]={0.1, 0.9};
float t[1] = {1.0};
chest_dl_set_filter_time(q, t, 1);
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),
discard the offseted samples to align next frame */
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) {
fprintf(stderr, "Error receiving from USRP\n");
return LIBLTE_ERROR;
}
q->time_offset = 0;
}
/* compute cumulative moving average time offset */
@ -291,6 +293,7 @@ static int receive_samples(ue_sync_t *q) {
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 */
if (q->recv_callback(q->stream, &q->input_buffer[q->time_offset], q->frame_len - q->time_offset) < 0) {
return LIBLTE_ERROR;

@ -2,16 +2,28 @@
%% Cell-Wide Settings
% A structure |enbConfig| is used to configure the eNodeB.
clear
%clear
Npackets = 10;
SNR_values = linspace(2,6,4);
Npackets = 4;
SNR_values = 1;%linspace(2,6,4);
%% Choose RMC
[waveform,rgrid,rmccFgOut] = lteRMCDLTool('R.11',[1;0;0;1]);
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
cfg.Seed = 8; % Random channel seed
@ -52,12 +64,13 @@ for snr_idx=1:length(SNR_values)
%% Noise Addition
noise = N0*complex(randn(size(rxWaveform)), randn(size(rxWaveform))); % Generate noise
rxWaveform = rxWaveform + noise;
rxWaveform = x;
%% Demodulate
frame_rx = lteOFDMDemodulate(rmccFgOut, rxWaveform);
for sf_idx=0:Nsf
flen=length(rxWaveform)/10;
subframe_waveform = rxWaveform(sf_idx*flen+1:(sf_idx+1)*flen);
subframe_rx=frame_rx(:,sf_idx*14+1:(sf_idx+1)*14);
rmccFgOut.NSubframe=sf_idx;
@ -83,6 +96,8 @@ for snr_idx=1:length(SNR_values)
end
decoded_liblte(snr_idx) = decoded_liblte(snr_idx)+dec2;
end
x = x(flen*10+1:end);
end
fprintf('SNR: %.1f\n',SNRdB)
end

Loading…
Cancel
Save