mirror of https://github.com/PentHertz/srsLTE.git
Added initial time to delay channel simulator
This commit is contained in:
parent
368690ea6b
commit
dedf0f2f78
|
@ -27,6 +27,7 @@
|
|||
#include "hst.h"
|
||||
#include "rlf.h"
|
||||
#include <memory>
|
||||
#include <srslte/common/log_filter.h>
|
||||
#include <srslte/config.h>
|
||||
#include <srslte/srslte.h>
|
||||
#include <string>
|
||||
|
@ -48,13 +49,14 @@ public:
|
|||
bool hst_enable = false;
|
||||
float hst_fd_hz = 750.0f;
|
||||
float hst_period_s = 7.2f;
|
||||
float hst_init_time_s = 7.2f;
|
||||
float hst_init_time_s = 0.0f;
|
||||
|
||||
// Delay options
|
||||
bool delay_enable = false;
|
||||
float delay_min_us = 10;
|
||||
float delay_max_us = 100;
|
||||
uint32_t delay_period_s = 3600;
|
||||
bool delay_enable = false;
|
||||
float delay_min_us = 10;
|
||||
float delay_max_us = 100;
|
||||
float delay_period_s = 3600;
|
||||
float delay_init_time_s = 0;
|
||||
|
||||
// RLF options
|
||||
bool rlf_enable = false;
|
||||
|
@ -64,6 +66,7 @@ public:
|
|||
|
||||
channel(const args_t& channel_args, uint32_t _nof_ports);
|
||||
~channel();
|
||||
void set_logger(log_filter* _log_h);
|
||||
void set_srate(uint32_t srate);
|
||||
void run(cf_t* in[SRSLTE_MAX_PORTS], cf_t* out[SRSLTE_MAX_PORTS], uint32_t len, const srslte_timestamp_t& t);
|
||||
|
||||
|
@ -74,6 +77,7 @@ private:
|
|||
srslte_channel_rlf_t* rlf = nullptr; // RLF has no buffers / no multiple instance is required
|
||||
cf_t* buffer_in = nullptr;
|
||||
cf_t* buffer_out = nullptr;
|
||||
log_filter* log_h = nullptr;
|
||||
uint32_t nof_ports = 0;
|
||||
uint32_t current_srate = 0;
|
||||
args_t args = {};
|
||||
|
|
|
@ -29,9 +29,12 @@
|
|||
typedef struct {
|
||||
float delay_min_us;
|
||||
float delay_max_us;
|
||||
uint32_t period_s;
|
||||
float period_s;
|
||||
float init_time_s;
|
||||
uint32_t srate_max_hz;
|
||||
uint32_t srate_hz;
|
||||
float delay_us;
|
||||
float delay_nsamples;
|
||||
|
||||
srslte_ringbuffer_t rb;
|
||||
cf_t* zero_buffer;
|
||||
|
@ -41,8 +44,12 @@ typedef struct {
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
SRSLTE_API int srslte_channel_delay_init(
|
||||
srslte_channel_delay_t* q, float delay_min_ns, float delay_max_ns, uint32_t period_s, uint32_t srate_max_hz);
|
||||
SRSLTE_API int srslte_channel_delay_init(srslte_channel_delay_t* q,
|
||||
float delay_min_us,
|
||||
float delay_max_us,
|
||||
float period_s,
|
||||
float init_time_s,
|
||||
uint32_t srate_max_hz);
|
||||
|
||||
SRSLTE_API void srslte_channel_delay_update_srate(srslte_channel_delay_t* q, uint32_t srate_hz);
|
||||
|
||||
|
|
|
@ -55,8 +55,12 @@ channel::channel(const channel::args_t& channel_args, uint32_t _nof_ports)
|
|||
// Create delay
|
||||
if (channel_args.delay_enable && ret == SRSLTE_SUCCESS) {
|
||||
delay[i] = (srslte_channel_delay_t*)calloc(sizeof(srslte_channel_delay_t), 1);
|
||||
ret = srslte_channel_delay_init(
|
||||
delay[i], channel_args.delay_min_us, channel_args.delay_max_us, channel_args.delay_period_s, srate_max);
|
||||
ret = srslte_channel_delay_init(delay[i],
|
||||
channel_args.delay_min_us,
|
||||
channel_args.delay_max_us,
|
||||
channel_args.delay_period_s,
|
||||
channel_args.delay_init_time_s,
|
||||
srate_max);
|
||||
} else {
|
||||
delay[i] = nullptr;
|
||||
}
|
||||
|
@ -112,6 +116,11 @@ channel::~channel()
|
|||
}
|
||||
}
|
||||
|
||||
void channel::set_logger(log_filter* _log_h)
|
||||
{
|
||||
log_h = _log_h;
|
||||
}
|
||||
|
||||
void channel::run(cf_t* in[SRSLTE_MAX_PORTS], cf_t* out[SRSLTE_MAX_PORTS], uint32_t len, const srslte_timestamp_t& t)
|
||||
{
|
||||
// check input pointers
|
||||
|
@ -147,6 +156,24 @@ void channel::run(cf_t* in[SRSLTE_MAX_PORTS], cf_t* out[SRSLTE_MAX_PORTS], uint3
|
|||
memcpy(out[i], buffer_in, sizeof(cf_t) * len);
|
||||
}
|
||||
}
|
||||
|
||||
if (log_h) {
|
||||
// Logging
|
||||
std::stringstream str;
|
||||
|
||||
str << "t=" << t.full_secs + t.frac_secs << "s; ";
|
||||
|
||||
if (delay[0]) {
|
||||
str << "delay=" << delay[0]->delay_us << "us; ";
|
||||
}
|
||||
|
||||
if (hst) {
|
||||
str << "hst=" << hst->fs_hz << "Hz; ";
|
||||
}
|
||||
|
||||
log_h->debug("%s\n", str.str().c_str());
|
||||
}
|
||||
|
||||
} else {
|
||||
for (uint32_t i = 0; i < nof_ports; i++) {
|
||||
// Check buffers are not null
|
||||
|
|
|
@ -23,18 +23,27 @@
|
|||
#include <srslte/phy/channel/delay.h>
|
||||
#include <srslte/srslte.h>
|
||||
|
||||
static inline double caulculate_delay_us(srslte_channel_delay_t* q, const srslte_timestamp_t* ts)
|
||||
static inline double calculate_delay_us(srslte_channel_delay_t* q, const srslte_timestamp_t* ts)
|
||||
{
|
||||
uint32_t mod_secs = (uint32_t)(ts->full_secs % q->period_s);
|
||||
double arg = 2.0 * M_PI * ((double)mod_secs + ts->frac_secs) / (double)q->period_s;
|
||||
// Convert period from seconds to samples
|
||||
uint64_t period_nsamples = (uint64_t)roundf(q->period_s * q->srate_hz);
|
||||
|
||||
// Convert timestamp to samples
|
||||
uint64_t ts_nsamples = srslte_timestamp_uint64(ts, q->srate_hz) + (uint64_t)q->init_time_s * q->srate_hz;
|
||||
|
||||
// Calculate time modulus in period
|
||||
uint64_t mod_t_nsamples = ts_nsamples - period_nsamples * (ts_nsamples / period_nsamples);
|
||||
double t = (double)mod_t_nsamples / (double)q->srate_hz;
|
||||
|
||||
double arg = 2.0 * M_PI * t / (double)q->period_s;
|
||||
double delay_us = q->delay_min_us + (q->delay_max_us - q->delay_min_us) * (1.0 + sin(arg)) / 2.0;
|
||||
|
||||
return delay_us;
|
||||
}
|
||||
|
||||
static inline uint32_t caulculate_delay_nsamples(srslte_channel_delay_t* q, double delay_us)
|
||||
static inline uint32_t calculate_delay_nsamples(srslte_channel_delay_t* q)
|
||||
{
|
||||
return (uint32_t)round(delay_us * (double)q->srate_hz / 1e6);
|
||||
return (uint32_t)round(q->delay_us * (double)q->srate_hz / 1e6);
|
||||
}
|
||||
|
||||
static inline uint32_t ringbuffer_available_nsamples(srslte_channel_delay_t* q)
|
||||
|
@ -42,8 +51,12 @@ static inline uint32_t ringbuffer_available_nsamples(srslte_channel_delay_t* q)
|
|||
return srslte_ringbuffer_status(&q->rb) / sizeof(cf_t);
|
||||
}
|
||||
|
||||
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)
|
||||
int srslte_channel_delay_init(srslte_channel_delay_t* q,
|
||||
float delay_min_us,
|
||||
float delay_max_us,
|
||||
float period_s,
|
||||
float init_time_s,
|
||||
uint32_t srate_max_hz)
|
||||
{
|
||||
// Calculate buffer size
|
||||
uint32_t buff_size = (uint32_t)ceilf(delay_max_us * (float)srate_max_hz / 1e6f);
|
||||
|
@ -63,6 +76,7 @@ int srslte_channel_delay_init(
|
|||
q->srate_max_hz = srate_max_hz;
|
||||
q->srate_hz = srate_max_hz;
|
||||
q->period_s = period_s;
|
||||
q->init_time_s = init_time_s;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -85,18 +99,18 @@ void srslte_channel_delay_free(srslte_channel_delay_t* q)
|
|||
void srslte_channel_delay_execute(
|
||||
srslte_channel_delay_t* q, const cf_t* in, cf_t* out, uint32_t len, const srslte_timestamp_t* ts)
|
||||
{
|
||||
double delay_us = caulculate_delay_us(q, ts);
|
||||
uint32_t delay_nsamples = caulculate_delay_nsamples(q, delay_us);
|
||||
q->delay_us = calculate_delay_us(q, ts);
|
||||
q->delay_nsamples = calculate_delay_nsamples(q);
|
||||
uint32_t available_nsamples = ringbuffer_available_nsamples(q);
|
||||
uint32_t read_nsamples = SRSLTE_MIN(delay_nsamples, len);
|
||||
uint32_t read_nsamples = SRSLTE_MIN(q->delay_nsamples, len);
|
||||
uint32_t copy_nsamples = (len > read_nsamples) ? (len - read_nsamples) : 0;
|
||||
|
||||
if (available_nsamples < delay_nsamples) {
|
||||
uint32_t nzeros = delay_nsamples - available_nsamples;
|
||||
if (available_nsamples < q->delay_nsamples) {
|
||||
uint32_t nzeros = q->delay_nsamples - available_nsamples;
|
||||
bzero(q->zero_buffer, sizeof(cf_t) * nzeros);
|
||||
srslte_ringbuffer_write(&q->rb, q->zero_buffer, sizeof(cf_t) * nzeros);
|
||||
} else if (available_nsamples > delay_nsamples) {
|
||||
srslte_ringbuffer_read(&q->rb, q->zero_buffer, sizeof(cf_t) * (available_nsamples - delay_nsamples));
|
||||
} else if (available_nsamples > q->delay_nsamples) {
|
||||
srslte_ringbuffer_read(&q->rb, q->zero_buffer, sizeof(cf_t) * (available_nsamples - q->delay_nsamples));
|
||||
}
|
||||
|
||||
// Read buffered samples
|
||||
|
|
|
@ -29,7 +29,8 @@ 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 float delay_period_s = 1;
|
||||
static float delay_init_time_s = 0;
|
||||
static uint32_t srate_hz = 1920000;
|
||||
static uint32_t sim_time_periods = 1;
|
||||
|
||||
|
@ -40,7 +41,7 @@ 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-t Delay period in seconds: [Default %.1f]\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);
|
||||
}
|
||||
|
@ -98,7 +99,7 @@ int main(int argc, char** argv)
|
|||
|
||||
// Initialise delay channel
|
||||
if (ret == SRSLTE_SUCCESS) {
|
||||
ret = srslte_channel_delay_init(&delay, delay_min_us, delay_max_us, delay_period_s, srate_hz);
|
||||
ret = srslte_channel_delay_init(&delay, delay_min_us, delay_max_us, delay_period_s, delay_init_time_s, srate_hz);
|
||||
}
|
||||
|
||||
// Run actual test
|
||||
|
@ -131,7 +132,7 @@ int main(int argc, char** argv)
|
|||
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",
|
||||
printf("Test delay_min_us=%d; delay_max_us=%d; delay_period_s=%.1f; srate_hz=%d; periods=%d; %s ... %.1f MSps\n",
|
||||
delay_min_us,
|
||||
delay_max_us,
|
||||
delay_period_s,
|
||||
|
|
|
@ -162,24 +162,34 @@ static int parse_args(all_args_t* args, int argc, char* argv[])
|
|||
("channel.dl.fading.enable", bpo::value<bool>(&args->phy.dl_channel_args.fading_enable)->default_value(false), "Enable/Disable Fading model")
|
||||
("channel.dl.fading.model", bpo::value<std::string>(&args->phy.dl_channel_args.fading_model)->default_value("none"), "Fading model + maximum doppler (E.g. none, epa5, eva70, etu300, etc)")
|
||||
("channel.dl.delay.enable", bpo::value<bool>(&args->phy.dl_channel_args.delay_enable)->default_value(false), "Enable/Disable Delay simulator")
|
||||
("channel.dl.delay.period", bpo::value<uint32_t>(&args->phy.dl_channel_args.delay_period_s)->default_value(3600), "Delay period in seconds (integer)")
|
||||
("channel.dl.delay.period_s", bpo::value<float>(&args->phy.dl_channel_args.delay_period_s)->default_value(3600), "Delay period in seconds (integer)")
|
||||
("channel.dl.delay.init_time_s", bpo::value<float>(&args->phy.dl_channel_args.delay_init_time_s)->default_value(0), "Initial time in seconds")
|
||||
("channel.dl.delay.maximum_us", bpo::value<float>(&args->phy.dl_channel_args.delay_max_us)->default_value(100.0f), "Maximum delay in microseconds")
|
||||
("channel.dl.delay.minimum_us", bpo::value<float>(&args->phy.dl_channel_args.delay_min_us)->default_value(10.0f), "Minimum delay in microseconds")
|
||||
("channel.dl.rlf.enable", bpo::value<bool>(&args->phy.dl_channel_args.rlf_enable)->default_value(false), "Enable/Disable Radio-Link Failure simulator")
|
||||
("channel.dl.rlf.t_on_ms", bpo::value<uint32_t >(&args->phy.dl_channel_args.rlf_t_on_ms)->default_value(10000), "Time for On state of the channel (ms)")
|
||||
("channel.dl.rlf.t_off_ms", bpo::value<uint32_t >(&args->phy.dl_channel_args.rlf_t_off_ms)->default_value(2000), "Time for Off state of the channel (ms)")
|
||||
("channel.dl.hst.enable", bpo::value<bool>(&args->phy.dl_channel_args.hst_enable)->default_value(false), "Enable/Disable HST simulator")
|
||||
("channel.dl.hst.period_s", bpo::value<float>(&args->phy.dl_channel_args.hst_period_s)->default_value(7.2f), "HST simulation period in seconds")
|
||||
("channel.dl.hst.fd_hz", bpo::value<float>(&args->phy.dl_channel_args.hst_fd_hz)->default_value(+750.0f), "Doppler frequency in Hz")
|
||||
("channel.dl.hst.init_time_s", bpo::value<float>(&args->phy.dl_channel_args.hst_init_time_s)->default_value(0), "Initial time in seconds")
|
||||
|
||||
/* Uplink Channel emulator section */
|
||||
("channel.ul.enable", bpo::value<bool>(&args->phy.ul_channel_args.enable)->default_value(false), "Enable/Disable internal Uplink channel emulator")
|
||||
("channel.ul.fading.enable", bpo::value<bool>(&args->phy.ul_channel_args.fading_enable)->default_value(false), "Enable/Disable Fading model")
|
||||
("channel.ul.fading.model", bpo::value<std::string>(&args->phy.ul_channel_args.fading_model)->default_value("none"), "Fading model + maximum doppler (E.g. none, epa5, eva70, etu300, etc)")
|
||||
("channel.ul.delay.enable", bpo::value<bool>(&args->phy.ul_channel_args.delay_enable)->default_value(false), "Enable/Disable Delay simulator")
|
||||
("channel.ul.delay.period", bpo::value<uint32_t>(&args->phy.ul_channel_args.delay_period_s)->default_value(3600), "Delay period in seconds (integer)")
|
||||
("channel.ul.delay.period_s", bpo::value<float>(&args->phy.ul_channel_args.delay_period_s)->default_value(3600), "Delay period in seconds (integer)")
|
||||
("channel.ul.delay.init_time_s", bpo::value<float>(&args->phy.ul_channel_args.delay_init_time_s)->default_value(0), "Initial time in seconds")
|
||||
("channel.ul.delay.maximum_us", bpo::value<float>(&args->phy.ul_channel_args.delay_max_us)->default_value(100.0f), "Maximum delay in microseconds")
|
||||
("channel.ul.delay.minimum_us", bpo::value<float>(&args->phy.ul_channel_args.delay_min_us)->default_value(10.0f), "Minimum delay in microseconds")
|
||||
("channel.ul.rlf.enable", bpo::value<bool>(&args->phy.ul_channel_args.rlf_enable)->default_value(false), "Enable/Disable Radio-Link Failure simulator")
|
||||
("channel.ul.rlf.t_on_ms", bpo::value<uint32_t >(&args->phy.ul_channel_args.rlf_t_on_ms)->default_value(10000), "Time for On state of the channel (ms)")
|
||||
("channel.ul.rlf.t_off_ms", bpo::value<uint32_t >(&args->phy.ul_channel_args.rlf_t_off_ms)->default_value(2000), "Time for Off state of the channel (ms)")
|
||||
("channel.ul.hst.enable", bpo::value<bool>(&args->phy.ul_channel_args.hst_enable)->default_value(false), "Enable/Disable HST simulator")
|
||||
("channel.ul.hst.period_s", bpo::value<float>(&args->phy.ul_channel_args.hst_period_s)->default_value(7.2f), "HST simulation period in seconds")
|
||||
("channel.ul.hst.fd_hz", bpo::value<float>(&args->phy.ul_channel_args.hst_fd_hz)->default_value(-750.0f), "Doppler frequency in Hz")
|
||||
("channel.ul.hst.init_time_s", bpo::value<float>(&args->phy.ul_channel_args.hst_init_time_s)->default_value(0), "Initial time in seconds")
|
||||
|
||||
/* PHY section */
|
||||
("phy.worker_cpu_mask",
|
||||
|
|
|
@ -183,45 +183,80 @@ enable = false
|
|||
|
||||
#####################################################################
|
||||
# Channel emulator options:
|
||||
# dl.enable: Enable/Disable internal Downlink channel emulator
|
||||
# enable: Enable/Disable internal Downlink/Uplink channel emulator
|
||||
#
|
||||
# -- Fading emulator
|
||||
# dl.fading.enable: Enable/disable fading simulator
|
||||
# dl.fading.model: Fading model + maximum doppler (E.g. none, epa5, eva70, etu300, etc)
|
||||
# fading.enable: Enable/disable fading simulator
|
||||
# fading.model: Fading model + maximum doppler (E.g. none, epa5, eva70, etu300, etc)
|
||||
#
|
||||
# -- Delay Emulator delay(t) = delay_min + (delay_max - delay_min) * (1 + sin(2pi*t/period)) / 2
|
||||
# Maximum speed [m/s]: (delay_max - delay_min) * pi * 300 / period
|
||||
# dl.delay.enable: Enable/disable delay simulator
|
||||
# dl.delay.period: Delay period in seconds (integer).
|
||||
# dl.delay.maximum_us: Maximum delay in microseconds
|
||||
# dl.delay.minumum_us: Minimum delay in microseconds
|
||||
# delay.enable: Enable/disable delay simulator
|
||||
# delay.period_s: Delay period in seconds.
|
||||
# delay.init_time_s: Delay initial time in seconds.
|
||||
# delay.maximum_us: Maximum delay in microseconds
|
||||
# delay.minumum_us: Minimum delay in microseconds
|
||||
#
|
||||
# -- Radio-Link Failure (RLF) Emulator
|
||||
# dl.rlf.enable: Enable/disable RLF simulator
|
||||
# dl.rlf.t_on_ms: Time for On state of the channel (ms)
|
||||
# dl.rlf.t_off_ms: Time for Off state of the channel (ms)
|
||||
# rlf.enable: Enable/disable RLF simulator
|
||||
# rlf.t_on_ms: Time for On state of the channel (ms)
|
||||
# rlf.t_off_ms: Time for Off state of the channel (ms)
|
||||
#
|
||||
# -- High Speed Train Doppler model simulator
|
||||
# hst.enable: Enable/Disable HST simulator
|
||||
# hst.period_s: HST simulation period in seconds
|
||||
# hst.fd_hz: Doppler frequency in Hz
|
||||
# hst.init_time_s: Initial time in seconds
|
||||
#####################################################################
|
||||
[channel]
|
||||
#dl.enable = false
|
||||
#dl.fading.enable = false
|
||||
#dl.fading.model = none
|
||||
#dl.delay.enable = false
|
||||
#dl.delay.period = 3600
|
||||
#dl.delay.maximum_us = 100
|
||||
#dl.delay.minimum_us = 10
|
||||
#dl.rlf.enable = false
|
||||
#dl.rlf.t_on_ms = 10000
|
||||
#dl.rlf.t_off_ms = 2000
|
||||
#ul.enable = false
|
||||
#ul.fading.enable = false
|
||||
#ul.fading.model = none
|
||||
#ul.delay.enable = false
|
||||
#ul.delay.period = 3600
|
||||
#ul.delay.maximum_us = 100
|
||||
#ul.delay.minimum_us = 10
|
||||
#ul.rlf.enable = false
|
||||
#ul.rlf.t_on_ms = 10000
|
||||
#ul.rlf.t_off_ms = 2000
|
||||
[channel.dl]
|
||||
#enable = false
|
||||
|
||||
[channel.dl.fading]
|
||||
#enable = false
|
||||
#model = none
|
||||
|
||||
[channel.dl.delay]
|
||||
#enable = false
|
||||
#period_s = 3600
|
||||
#init_time_s = 0
|
||||
#maximum_us = 100
|
||||
#minimum_us = 10
|
||||
|
||||
[channel.dl.rlf]
|
||||
#enable = false
|
||||
#t_on_ms = 10000
|
||||
#t_off_ms = 2000
|
||||
|
||||
[channel.dl.hst]
|
||||
#enable = false
|
||||
#period_s = 7.2
|
||||
#fd_hz = 750.0
|
||||
#init_time_s = 0.0
|
||||
|
||||
[channel.ul]
|
||||
#enable = false
|
||||
|
||||
[channel.ul.fading]
|
||||
#enable = false
|
||||
#model = none
|
||||
|
||||
[channel.ul.delay]
|
||||
#enable = false
|
||||
#period_s = 3600
|
||||
#init_time_s = 0
|
||||
#maximum_us = 100
|
||||
#minimum_us = 10
|
||||
|
||||
[channel.ul.rlf]
|
||||
#enable = false
|
||||
#t_on_ms = 10000
|
||||
#t_off_ms = 2000
|
||||
|
||||
[channel.ul.hst]
|
||||
#enable = false
|
||||
#period_s = 7.2
|
||||
#fd_hz = -750.0
|
||||
#init_time_s = 0.0
|
||||
|
||||
#####################################################################
|
||||
# PHY configuration options
|
||||
|
|
Loading…
Reference in New Issue