SRSLTE: Added Uniform Random vector generator; Delay channel test; Fixed Delay channel SEGFAULT; SRSUE channel unique pointer;

This commit is contained in:
Xavier Arteaga 2019-05-28 18:28:56 +02:00 committed by Andre Puschmann
parent cdc5706245
commit 9c84f8e3fd
8 changed files with 166 additions and 10 deletions

View File

@ -25,6 +25,7 @@
#include "delay.h"
#include "fading.h"
#include "rlf.h"
#include <memory>
#include <srslte/config.h>
#include <srslte/srslte.h>
#include <string>
@ -70,6 +71,8 @@ private:
args_t args;
};
typedef std::unique_ptr<channel> channel_ptr;
} // namespace srslte
#endif // SRSLTE_CHANNEL_H

View File

@ -40,6 +40,9 @@ SRSLTE_API float srslte_random_uniform_real_dist(srslte_random_t q, float min, f
SRSLTE_API cf_t srslte_random_uniform_complex_dist(srslte_random_t q, float min, float max);
SRSLTE_API void
srslte_random_uniform_complex_dist_vector(srslte_random_t q, cf_t* vector, uint32_t nsamples, float min, float max);
SRSLTE_API float srslte_random_gauss_dist(srslte_random_t q, float std_dev);
SRSLTE_API void srslte_random_free(srslte_random_t q);

View File

@ -46,7 +46,7 @@ int srslte_channel_delay_init(
srslte_channel_delay_t* q, float delay_min_us, float delay_max_us, uint32_t period_s, uint32_t srate_max_hz)
{
// Calculate buffer size
uint32_t buff_size = (uint32_t)ceilf(delay_max_us * (float)srate_max_hz);
uint32_t buff_size = (uint32_t)ceilf(delay_max_us * (float)srate_max_hz / 1e6f);
// Create ring buffer
int ret = srslte_ringbuffer_init(&q->rb, sizeof(cf_t) * buff_size);

View File

@ -27,4 +27,9 @@ endif(SRSGUI_FOUND)
target_link_libraries(fading_channel_test srslte_phy srslte_common srslte_phy ${SEC_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
add_test(fading_channel_test_epa5 fading_channel_test -m epa5 -s 26.04e6 -t 100)
add_test(fading_channel_test_eva70 fading_channel_test -m eva70 -s 23.04e6 -t 100)
add_test(fading_channel_test_etu300 fading_channel_test -m etu70 -s 23.04e6 -t 100)
add_test(fading_channel_test_etu300 fading_channel_test -m etu70 -s 23.04e6 -t 100)
add_executable(delay_channel_test delay_channel_test.c)
target_link_libraries(delay_channel_test srslte_phy srslte_common srslte_phy ${SEC_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
add_test(delay_channel_test delay_channel_test -m 10 -M 100 -t 1000 -T 1 -s 1.92e6)

View File

@ -0,0 +1,143 @@
/*
* Copyright 2013-2019 Software Radio Systems Limited
*
* This file is part of srsLTE.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#include "srslte/phy/utils/vector.h"
#include <srslte/phy/channel/delay.h>
#include <srslte/phy/utils/debug.h>
#include <srslte/phy/utils/random.h>
#include <unistd.h>
static srslte_channel_delay_t delay = {};
static uint32_t delay_min_us = 10;
static uint32_t delay_max_us = 3333;
static uint32_t delay_period_s = 1;
static uint32_t srate_hz = 1920000;
static uint32_t sim_time_periods = 1;
#define INPUT_TYPE 0 /* 0: Dirac Delta; Otherwise: Random*/
static void usage(char* prog)
{
printf("Usage: %s [mMtsT]\n", prog);
printf("\t-m Minimum delay in microseconds [Default %d]\n", delay_min_us);
printf("\t-M Maximum delay in microseconds [Default %d]\n", delay_max_us);
printf("\t-t Delay period in seconds: [Default %d]\n", delay_period_s);
printf("\t-s Sampling rate in Hz: [Default %d]\n", srate_hz);
printf("\t-T Simulation Time in periods: [Default %d]\n", sim_time_periods);
}
static void parse_args(int argc, char** argv)
{
int opt;
while ((opt = getopt(argc, argv, "mMtsT")) != -1) {
switch (opt) {
case 'm':
delay_min_us = (uint32_t)strtol(argv[optind], NULL, 10);
break;
case 'M':
delay_max_us = (uint32_t)strtol(argv[optind], NULL, 10);
break;
case 't':
delay_period_s = (uint32_t)strtol(argv[optind], NULL, 10);
break;
case 's':
srate_hz = (uint32_t)strtof(argv[optind], NULL);
break;
case 'T':
sim_time_periods = (uint32_t)strtol(argv[optind], NULL, 10);
break;
default:
usage(argv[0]);
exit(-1);
}
}
}
int main(int argc, char** argv)
{
int ret = SRSLTE_SUCCESS;
cf_t* input_buffer = NULL;
cf_t* output_buffer = NULL;
srslte_timestamp_t ts = {}; // Initialised to zero
srslte_random_t random_gen = srslte_random_init(0x1234);
struct timeval t[3] = {};
// Parse arguments
parse_args(argc, argv);
// Initialise buffers
uint32_t size = srate_hz / 1000;
input_buffer = srslte_vec_malloc(sizeof(cf_t) * size);
output_buffer = srslte_vec_malloc(sizeof(cf_t) * size);
if (!input_buffer || !output_buffer) {
fprintf(stderr, "Error: Allocating memory\n");
ret = SRSLTE_ERROR;
}
// Generate random samples
srslte_random_uniform_complex_dist_vector(random_gen, input_buffer, size, -1.0f, +1.0f);
// Initialise delay channel
if (ret == SRSLTE_SUCCESS) {
ret = srslte_channel_delay_init(&delay, delay_min_us, delay_max_us, delay_period_s, srate_hz);
}
// Run actual test
gettimeofday(&t[1], NULL);
for (int i = 0; i < sim_time_periods && ret == SRSLTE_SUCCESS; i++) {
for (int j = 0; j < 1000 * delay_period_s; j++) {
// Run delay channel
srslte_channel_delay_execute(&delay, input_buffer, output_buffer, size, &ts);
// Increment timestamp 1ms
srslte_timestamp_add(&ts, 0, 0.001);
}
}
gettimeofday(&t[2], NULL);
get_time_interval(t);
// Free
srslte_random_free(random_gen);
srslte_channel_delay_free(&delay);
if (input_buffer) {
free(input_buffer);
}
if (output_buffer) {
free(output_buffer);
}
uint64_t nof_samples = sim_time_periods * 1000 * delay_period_s * size;
double elapsed_us = t[0].tv_sec * 1e6 + t[0].tv_usec;
// Print result and exit
printf("Test delay_min_us=%d; delay_max_us=%d; delay_period_s=%d; srate_hz=%d; periods=%d; %s ... %.1f MSps\n",
delay_min_us,
delay_max_us,
delay_period_s,
srate_hz,
sim_time_periods,
(ret == SRSLTE_SUCCESS) ? "Passed" : "Failed",
(double)nof_samples / elapsed_us);
exit(ret);
}

View File

@ -98,6 +98,13 @@ cf_t srslte_random_uniform_complex_dist(srslte_random_t q, float min, float max)
return ret;
}
void srslte_random_uniform_complex_dist_vector(srslte_random_t q, cf_t* vector, uint32_t nsamples, float min, float max)
{
for (int i = 0; i < nsamples; i++) {
vector[i] = srslte_random_uniform_complex_dist(q, min, max);
}
}
float srslte_random_gauss_dist(srslte_random_t q, float std_dev)
{
float ret = NAN;

View File

@ -282,7 +282,7 @@ private:
phy_common* worker_com;
prach* prach_buffer;
async_scell_recv_vector* scell_sync;
srslte::channel* channel_emulator = nullptr;
srslte::channel_ptr channel_emulator = nullptr;
// Object for synchronization of the primary cell
srslte_ue_sync_t ue_sync;

View File

@ -93,8 +93,8 @@ void sync::init(radio_interface_phy* _radio,
}
if (worker_com->args->dl_channel_args.enable) {
channel_emulator = new srslte::channel(worker_com->args->dl_channel_args,
worker_com->args->nof_rx_ant * worker_com->args->nof_rx_ant);
channel_emulator = srslte::channel_ptr(new srslte::channel(
worker_com->args->dl_channel_args, worker_com->args->nof_rx_ant * worker_com->args->nof_rx_ant));
}
nof_workers = workers_pool->get_nof_workers();
@ -134,11 +134,6 @@ sync::~sync()
}
pthread_mutex_destroy(&rrc_mutex);
srslte_ue_sync_free(&ue_sync);
// Destroy channel emulator if created
if (channel_emulator) {
delete channel_emulator;
}
}
}