Merge remote-tracking branch 'origin/develop-chModels-Doppler' into integration_2022_wk49
This commit is contained in:
@@ -1190,8 +1190,10 @@ int main(int argc, char **argv) {
|
||||
UE->frame_parms.nb_antennas_rx,
|
||||
channel_model,
|
||||
N_RB2sampling_rate(eNB->frame_parms.N_RB_DL),
|
||||
0,
|
||||
N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
|
||||
DS_TDL,
|
||||
0.0,
|
||||
CORR_LEVEL_LOW,
|
||||
forgetting_factor,
|
||||
rx_sample_offset,
|
||||
@@ -1206,8 +1208,10 @@ int main(int argc, char **argv) {
|
||||
UE->frame_parms.nb_antennas_rx,
|
||||
channel_model,
|
||||
N_RB2sampling_rate(eNB->frame_parms.N_RB_DL),
|
||||
0,
|
||||
N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
|
||||
DS_TDL,
|
||||
0.0,
|
||||
CORR_LEVEL_LOW,
|
||||
forgetting_factor,
|
||||
rx_sample_offset,
|
||||
|
||||
@@ -739,15 +739,15 @@ int main(int argc, char **argv) {
|
||||
n_rx,
|
||||
channel_model,
|
||||
N_RB2sampling_rate(eNB->frame_parms.N_RB_UL),
|
||||
0,
|
||||
N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL),
|
||||
30e-9,
|
||||
maxDoppler,
|
||||
CORR_LEVEL_LOW,
|
||||
forgetting_factor,
|
||||
delay,
|
||||
0,
|
||||
0);
|
||||
// set Doppler
|
||||
UE2eNB->max_Doppler = maxDoppler;
|
||||
|
||||
// NN: N_RB_UL has to be defined in ulsim
|
||||
for (int k=0; k<NUMBER_OF_ULSCH_MAX; k++) eNB->ulsch[k] = new_eNB_ulsch(max_turbo_iterations,N_RB_DL,0);
|
||||
|
||||
@@ -334,10 +334,14 @@ int main(int argc, char **argv)
|
||||
if (ouput_vcd)
|
||||
vcd_signal_dumper_init("/tmp/openair_dump_nr_dlschsim.vcd");
|
||||
|
||||
gNB2UE = new_channel_desc_scm(n_tx, n_rx, channel_model,
|
||||
gNB2UE = new_channel_desc_scm(n_tx,
|
||||
n_rx,
|
||||
channel_model,
|
||||
61.44e6, //N_RB2sampling_rate(N_RB_DL),
|
||||
0,
|
||||
40e6, //N_RB2channel_bandwidth(N_RB_DL),
|
||||
DS_TDL,
|
||||
0.0,
|
||||
CORR_LEVEL_LOW,
|
||||
0,
|
||||
0,
|
||||
|
||||
@@ -901,8 +901,10 @@ int main(int argc, char **argv)
|
||||
n_rx,
|
||||
channel_model,
|
||||
fs/1e6,//sampling frequency in MHz
|
||||
0,
|
||||
txbw,
|
||||
30e-9,
|
||||
0.0,
|
||||
CORR_LEVEL_LOW,
|
||||
0,
|
||||
0,
|
||||
|
||||
@@ -532,8 +532,10 @@ int main(int argc, char **argv)
|
||||
n_rx,
|
||||
channel_model,
|
||||
fs,
|
||||
0,
|
||||
bw,
|
||||
300e-9,
|
||||
0.0,
|
||||
CORR_LEVEL_LOW,
|
||||
0,
|
||||
0,
|
||||
|
||||
@@ -729,8 +729,10 @@ int main(int argc, char **argv){
|
||||
gNB->frame_parms.nb_antennas_rx,
|
||||
channel_model,
|
||||
fs,
|
||||
0,
|
||||
bw,
|
||||
DS_TDL,
|
||||
0.0,
|
||||
CORR_LEVEL_LOW,
|
||||
0.0,
|
||||
delay,
|
||||
|
||||
@@ -421,7 +421,7 @@ int main(int argc, char **argv)
|
||||
&txbw,
|
||||
&rxbw);
|
||||
|
||||
UE2gNB = new_channel_desc_scm(n_tx, n_rx, channel_model, fs, txbw, DS_TDL, CORR_LEVEL_LOW, 0, 0, 0, 0);
|
||||
UE2gNB = new_channel_desc_scm(n_tx, n_rx, channel_model, fs, 0, txbw, DS_TDL, 0.0, CORR_LEVEL_LOW, 0, 0, 0, 0);
|
||||
|
||||
if (UE2gNB==NULL) {
|
||||
printf("Problem generating channel model. Exiting.\n");
|
||||
|
||||
@@ -381,8 +381,10 @@ int main(int argc, char **argv)
|
||||
n_rx,
|
||||
channel_model,
|
||||
61.44e6, //N_RB2sampling_rate(N_RB_DL),
|
||||
0,
|
||||
40e6, //N_RB2channel_bandwidth(N_RB_DL),
|
||||
DS_TDL,
|
||||
0.0,
|
||||
CORR_LEVEL_LOW,
|
||||
0,
|
||||
0,
|
||||
|
||||
@@ -435,6 +435,10 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (optarg[3] == ',') {
|
||||
maxDoppler = atoi(&optarg[4]);
|
||||
printf("Maximum Doppler Frequency: %.0f Hz\n", maxDoppler);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
@@ -621,7 +625,7 @@ int main(int argc, char **argv)
|
||||
//printf("-d Use TDD\n");
|
||||
printf("-d Introduce delay in terms of number of samples\n");
|
||||
printf("-f Number of frames to simulate\n");
|
||||
printf("-g Channel model configuration. Arguments list: Number of arguments = 2, {Channel model: [A] TDLA30, [B] TDLB100, [C] TDLC300}, {Correlation: [l] Low, [m] Medium, [h] High}, e.g. -g A,l\n");
|
||||
printf("-g Channel model configuration. Arguments list: Number of arguments = 3, {Channel model: [A] TDLA30, [B] TDLB100, [C] TDLC300}, {Correlation: [l] Low, [m] Medium, [h] High}, {Maximum Doppler shift} e.g. -g A,l,10\n");
|
||||
printf("-h This message\n");
|
||||
printf("-i Change channel estimation technique. Arguments list: Number of arguments=2, Frequency domain {0:Linear interpolation, 1:PRB based averaging}, Time domain {0:Estimates of last DMRS symbol, 1:Average of DMRS symbols}. e.g. -i 1,0\n");
|
||||
//printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n");
|
||||
@@ -683,26 +687,6 @@ int main(int argc, char **argv)
|
||||
&tx_bandwidth,
|
||||
&rx_bandwidth);
|
||||
|
||||
LOG_I( PHY,"++++++++++++++++++++++++++++++++++++++++++++++%i+++++++++++++++++++++++++++++++++++++++++",loglvl);
|
||||
|
||||
UE2gNB = new_channel_desc_scm(n_tx,
|
||||
n_rx, channel_model,
|
||||
sampling_frequency/1e6,
|
||||
tx_bandwidth,
|
||||
DS_TDL,
|
||||
corr_level,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
|
||||
if (UE2gNB == NULL) {
|
||||
printf("Problem generating channel model. Exiting.\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
UE2gNB->max_Doppler = maxDoppler;
|
||||
|
||||
RC.gNB = (PHY_VARS_gNB **) malloc(sizeof(PHY_VARS_gNB *));
|
||||
RC.gNB[0] = calloc(1,sizeof(PHY_VARS_gNB));
|
||||
gNB = RC.gNB[0];
|
||||
@@ -809,8 +793,27 @@ int main(int argc, char **argv)
|
||||
|
||||
NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[0];
|
||||
|
||||
// Configure channel model
|
||||
UE2gNB = new_channel_desc_scm(n_tx,
|
||||
n_rx,
|
||||
channel_model,
|
||||
sampling_frequency / 1e6,
|
||||
frame_parms->ul_CarrierFreq,
|
||||
tx_bandwidth,
|
||||
DS_TDL,
|
||||
maxDoppler,
|
||||
corr_level,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
|
||||
//configure UE
|
||||
if (UE2gNB == NULL) {
|
||||
printf("Problem generating channel model. Exiting.\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// Configure UE
|
||||
UE = malloc(sizeof(PHY_VARS_NR_UE));
|
||||
memset((void*)UE,0,sizeof(PHY_VARS_NR_UE));
|
||||
PHY_vars_UE_g = malloc(sizeof(PHY_VARS_NR_UE**));
|
||||
@@ -1290,11 +1293,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (UE2gNB->max_Doppler == 0) {
|
||||
multipath_channel(UE2gNB, s_re, s_im, r_re, r_im, slot_length, 0, (n_trials==1)?1:0);
|
||||
} else {
|
||||
multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, 2*slot_length, 0);
|
||||
}
|
||||
multipath_channel(UE2gNB, s_re, s_im, r_re, r_im, slot_length, 0, (n_trials == 1) ? 1 : 0);
|
||||
add_noise(rxdata, (const double **) r_re, (const double **) r_im, sigma, slot_length, slot_offset, ts, delay, pdu_bit_map, frame_parms->nb_antennas_rx);
|
||||
|
||||
} /*End input_fd */
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "sim.h"
|
||||
|
||||
//#define DEBUG_CH
|
||||
//#define DOPPLER_DEBUG
|
||||
|
||||
uint8_t multipath_channel_nosigconv(channel_desc_t *desc)
|
||||
{
|
||||
@@ -201,11 +202,16 @@ void __attribute__ ((no_sanitize_address)) multipath_channel(channel_desc_t *des
|
||||
}
|
||||
#endif
|
||||
|
||||
struct complexd cexp_doppler[length];
|
||||
if (desc->max_Doppler != 0.0) {
|
||||
get_cexp_doppler(cexp_doppler, desc, length);
|
||||
}
|
||||
|
||||
for (int i=0; i<((int)length-dd); i++) {
|
||||
for (int ii=0; ii<desc->nb_rx; ii++) {
|
||||
struct complexd rx_tmp={0};
|
||||
for (int j=0; j<desc->nb_tx; j++) {
|
||||
struct complexd *chan=desc->ch[ii+(j*desc->nb_rx)];
|
||||
struct complexd *chan=desc->ch[ii+(j*desc->nb_rx)];
|
||||
for (int l = 0; l<(int)desc->channel_length; l++) {
|
||||
if ((i>=0) && (i-l)>=0) {
|
||||
struct complexd tx;
|
||||
@@ -215,14 +221,23 @@ void __attribute__ ((no_sanitize_address)) multipath_channel(channel_desc_t *des
|
||||
rx_tmp.i += (tx.i * chan[l].r) + (tx.r * chan[l].i);
|
||||
}
|
||||
if (i==0 && log_channel == 1) {
|
||||
printf("channel[%d][%d][%d] = %f dB \t(%e, %e)\n",
|
||||
ii, j, l, 10*log10(pow(chan[l].r,2.0)+pow(chan[l].i,2.0)),
|
||||
chan[l].r,
|
||||
chan[l].i);
|
||||
printf("channel[%d][%d][%d] = %f dB \t(%e, %e)\n",
|
||||
ii, j, l, 10 * log10(pow(chan[l].r, 2.0) + pow(chan[l].i, 2.0)), chan[l].r, chan[l].i);
|
||||
}
|
||||
} //l
|
||||
} // j
|
||||
|
||||
if (desc->max_Doppler != 0.0)
|
||||
rx_tmp = cdMul(rx_tmp, cexp_doppler[i]);
|
||||
|
||||
#ifdef DOPPLER_DEBUG
|
||||
printf("[k %2i] cexp_doppler = (%7.4f, %7.4f), abs(cexp_doppler) = %.4f\n",
|
||||
i,
|
||||
cexp_doppler[i].r,
|
||||
cexp_doppler[i].i,
|
||||
sqrt(cexp_doppler[i].r * cexp_doppler[i].r + cexp_doppler[i].i * cexp_doppler[i].i));
|
||||
#endif
|
||||
|
||||
rx_sig_re[ii][i+dd] = rx_tmp.r*path_loss;
|
||||
rx_sig_im[ii][i+dd] = rx_tmp.i*path_loss;
|
||||
#ifdef DEBUG_CH
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <complex.h>
|
||||
|
||||
|
||||
#include "PHY/TOOLS/tools_defs.h"
|
||||
@@ -37,6 +38,7 @@
|
||||
|
||||
//#define DEBUG_CH
|
||||
//#define DEBUG_CH_POWER
|
||||
//#define DOPPLER_DEBUG
|
||||
|
||||
#include "assertions.h"
|
||||
|
||||
@@ -451,6 +453,43 @@ void tdlModel(int tdl_paths, double *tdl_delays, double *tdl_amps_dB, double DS
|
||||
}
|
||||
}
|
||||
|
||||
void get_cexp_doppler(struct complexd *cexp_doppler, channel_desc_t *chan_desc, const uint32_t length)
|
||||
{
|
||||
// TS 38.104 - Table G.3-1
|
||||
uint16_t Dmin = 2;
|
||||
uint16_t Ds = 300;
|
||||
double c = 299792458;
|
||||
double v = chan_desc->max_Doppler * (c / (double)chan_desc->center_freq);
|
||||
|
||||
#ifdef DOPPLER_DEBUG
|
||||
printf("v = %f\n", v);
|
||||
#endif
|
||||
|
||||
double phase0 = 2 * M_PI * uniformrandom();
|
||||
double cos_theta[length];
|
||||
double fs[length];
|
||||
|
||||
for (uint32_t t_idx = 0; t_idx < length; t_idx++) {
|
||||
double t = t_idx / (chan_desc->sampling_rate * 1e6);
|
||||
if (t >= 0 && t <= Ds / v) {
|
||||
cos_theta[t_idx] = (Ds / 2 - v * t) / sqrt(Dmin * Dmin + (Ds / 2 - v * t) * (Ds / 2 - v * t));
|
||||
} else if (t > Ds / v && t <= 2 * Ds / v) {
|
||||
cos_theta[t_idx] = (-1.5 * Ds + v * t) / sqrt(Dmin * Dmin + (-1.5 * Ds + v * t) * (-1.5 * Ds + v * t));
|
||||
} else {
|
||||
cos_theta[t_idx] = cos(fmod(t, 2 * Ds / v));
|
||||
}
|
||||
fs[t_idx] = chan_desc->max_Doppler * cos_theta[t_idx];
|
||||
|
||||
double complex tmp_cexp_doppler = cexp(I * (2 * M_PI * fs[t_idx] * t + phase0));
|
||||
cexp_doppler[t_idx].r = creal(tmp_cexp_doppler);
|
||||
cexp_doppler[t_idx].i = cimag(tmp_cexp_doppler);
|
||||
|
||||
#ifdef DOPPLER_DEBUG
|
||||
printf("(%2i) t_us = %f, cos_theta = %f, fs = %f, cexp_doppler = (%f, %f)\n", t_idx, t * 1e6, cos_theta[t_idx], fs[t_idx], cexp_doppler[t_idx].r, cexp_doppler[t_idx].i);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
double get_normalization_ch_factor(channel_desc_t *desc)
|
||||
{
|
||||
if (!(desc->channel_length > 1 && desc->modelid >= TDL_A && desc->modelid <= TDL_E)) {
|
||||
@@ -521,18 +560,20 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
|
||||
uint8_t nb_rx,
|
||||
SCM_t channel_model,
|
||||
double sampling_rate,
|
||||
uint64_t center_freq,
|
||||
double channel_bandwidth,
|
||||
double DS_TDL,
|
||||
double maxDoppler,
|
||||
const corr_level_t corr_level,
|
||||
double forgetting_factor,
|
||||
int32_t channel_offset,
|
||||
double path_loss_dB,
|
||||
float noise_power_dB) {
|
||||
|
||||
float noise_power_dB)
|
||||
{
|
||||
// To create tables for normal distribution
|
||||
struct timespec t;
|
||||
clock_gettime(CLOCK_MONOTONIC, &t);
|
||||
tableNor((long)(t.tv_nsec%INT_MAX));
|
||||
tableNor((long) (t.tv_nsec % INT_MAX));
|
||||
|
||||
channel_desc_t *chan_desc = (channel_desc_t *)calloc(1,sizeof(channel_desc_t));
|
||||
|
||||
@@ -549,14 +590,16 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
|
||||
|
||||
uint16_t i,j;
|
||||
double sum_amps;
|
||||
double aoa,ricean_factor,Td,maxDoppler;
|
||||
double aoa, ricean_factor, Td;
|
||||
int channel_length,nb_taps;
|
||||
struct complexd *R_sqrt_ptr2;
|
||||
chan_desc->modelid = channel_model;
|
||||
chan_desc->nb_tx = nb_tx;
|
||||
chan_desc->nb_rx = nb_rx;
|
||||
chan_desc->sampling_rate = sampling_rate;
|
||||
chan_desc->center_freq = center_freq;
|
||||
chan_desc->channel_bandwidth = channel_bandwidth;
|
||||
chan_desc->max_Doppler = maxDoppler;
|
||||
chan_desc->corr_level = corr_level;
|
||||
chan_desc->forgetting_factor = forgetting_factor;
|
||||
chan_desc->channel_offset = channel_offset;
|
||||
@@ -1856,6 +1899,7 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
|
||||
#ifdef DEBUG_CH
|
||||
printf("(%d,%d,%d)->(%e,%e)\n",k,aarx,aatx,desc->ch[aarx+(aatx*desc->nb_rx)][k].r,desc->ch[aarx+(aatx*desc->nb_rx)][k].i);
|
||||
#endif
|
||||
|
||||
} //channel_length
|
||||
#ifdef DEBUG_CH_POWER
|
||||
ch_power_count++;
|
||||
@@ -2123,8 +2167,10 @@ int load_channellist(uint8_t nb_tx, uint8_t nb_rx, double sampling_rate, double
|
||||
nb_rx,
|
||||
modid,
|
||||
sampling_rate,
|
||||
0,
|
||||
channel_bandwidth,
|
||||
*(channel_list.paramarray[i][pindex_DT].dblptr),
|
||||
0.0,
|
||||
CORR_LEVEL_LOW,
|
||||
*(channel_list.paramarray[i][pindex_FF].dblptr),
|
||||
*(channel_list.paramarray[i][pindex_CO].iptr),
|
||||
|
||||
@@ -80,6 +80,8 @@ typedef struct {
|
||||
struct complexd **chF;
|
||||
///Maximum path delay in mus.
|
||||
double Td;
|
||||
///Carrier center frequency
|
||||
uint64_t center_freq;
|
||||
///Channel bandwidth in MHz.
|
||||
double channel_bandwidth;
|
||||
///System sampling rate in Msps.
|
||||
@@ -315,8 +317,10 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
|
||||
uint8_t nb_rx,
|
||||
SCM_t channel_model,
|
||||
double sampling_rate,
|
||||
uint64_t center_freq,
|
||||
double channel_bandwidth,
|
||||
double DS_TDL,
|
||||
double maxDoppler,
|
||||
const corr_level_t corr_level,
|
||||
double forgetting_factor,
|
||||
int32_t channel_offset,
|
||||
@@ -344,6 +348,15 @@ void set_channeldesc_owner(channel_desc_t *cdesc, channelmod_moduleid_t module_i
|
||||
\param module_name is the C string to use as model name for the channel pointed by cdesc
|
||||
*/
|
||||
void set_channeldesc_name(channel_desc_t *cdesc,char *modelname);
|
||||
|
||||
/** \fn void get_cexp_doppler(struct complexd *cexp_doppler, channel_desc_t *chan_desc, const uint32_t length)
|
||||
\brief This routine generates the complex exponential to apply the Doppler shift
|
||||
\param cexp_doppler Output with the complex exponential of Doppler shift
|
||||
\param desc Pointer to the channel descriptor
|
||||
\param length Size of complex exponential of Doppler shift
|
||||
*/
|
||||
void get_cexp_doppler(struct complexd *cexp_doppler, channel_desc_t *chan_desc, const uint32_t length);
|
||||
|
||||
/** \fn void random_channel(channel_desc_t *desc)
|
||||
\brief This routine generates a random channel response (time domain) according to a tapped delay line model.
|
||||
\param desc Pointer to the channel descriptor
|
||||
|
||||
Reference in New Issue
Block a user