Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lizhongxiao
OpenXG-RAN
Commits
34c2f0be
Commit
34c2f0be
authored
Oct 13, 2022
by
Thomas Schlichter
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'fhg-KPI-GUI'
parents
4be8cb64
044be0d1
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
3110 additions
and
26 deletions
+3110
-26
CMakeLists.txt
CMakeLists.txt
+18
-0
cmake_targets/build_oai
cmake_targets/build_oai
+18
-5
executables/nr-softmodem.c
executables/nr-softmodem.c
+10
-0
executables/nr-uesoftmodem.c
executables/nr-uesoftmodem.c
+4
-0
executables/softmodem-common.c
executables/softmodem-common.c
+5
-1
executables/softmodem-common.h
executables/softmodem-common.h
+5
-0
openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h
openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h
+2
-1
openair1/PHY/NR_TRANSPORT/pucch_rx.c
openair1/PHY/NR_TRANSPORT/pucch_rx.c
+3
-0
openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
+6
-2
openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
+11
-3
openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
+48
-0
openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
+11
-2
openair1/PHY/TOOLS/nr_phy_qt_scope.cpp
openair1/PHY/TOOLS/nr_phy_qt_scope.cpp
+2719
-0
openair1/PHY/TOOLS/nr_phy_qt_scope.h
openair1/PHY/TOOLS/nr_phy_qt_scope.h
+218
-0
openair1/PHY/TOOLS/nr_phy_scope.c
openair1/PHY/TOOLS/nr_phy_scope.c
+11
-2
openair1/PHY/TOOLS/phy_scope_interface.h
openair1/PHY/TOOLS/phy_scope_interface.h
+18
-5
openair1/PHY/defs_nr_UE.h
openair1/PHY/defs_nr_UE.h
+0
-2
openair1/PHY/impl_defs_nr.h
openair1/PHY/impl_defs_nr.h
+2
-2
openair1/SCHED_NR/phy_frame_config_nr.c
openair1/SCHED_NR/phy_frame_config_nr.c
+1
-1
No files found.
CMakeLists.txt
View file @
34c2f0be
...
@@ -2484,6 +2484,24 @@ set (SIMUSRC
...
@@ -2484,6 +2484,24 @@ set (SIMUSRC
##########################
##########################
add_library
(
SIMU SHARED
${
SIMUSRC
}
)
add_library
(
SIMU SHARED
${
SIMUSRC
}
)
# Qt-based scope
set
(
QTSCOPE_SOURCE_NR
${
OPENAIR1_DIR
}
/PHY/TOOLS/nr_phy_qt_scope.cpp
)
find_package
(
Qt5 COMPONENTS Widgets Charts
)
if
(
Qt5_FOUND
)
message
(
"Qt5 Packages found."
)
# Creates rules for calling the Meta-Object Compiler (moc) on the given source files
qt5_wrap_cpp
(
QTSCOPE_SOURCE_NR
${
OPENAIR1_DIR
}
/PHY/TOOLS/nr_phy_qt_scope.h
)
add_library
(
nrqtscope MODULE
${
QTSCOPE_SOURCE_NR
}
)
# Use the Widgets module from Qt5.
target_link_libraries
(
nrqtscope Qt5::Widgets Qt5::Charts
)
else
(
Qt5_FOUND
)
message
(
"WARNING: Qt5 Packages NOT found, so qt scope can NOT be displayed."
)
endif
()
add_library
(
SIMU_ETH
add_library
(
SIMU_ETH
${
OPENAIR1_DIR
}
/SIMULATION/ETH_TRANSPORT/netlink_init.c
${
OPENAIR1_DIR
}
/SIMULATION/ETH_TRANSPORT/netlink_init.c
${
OPENAIR1_DIR
}
/SIMULATION/ETH_TRANSPORT/multicast_link.c
${
OPENAIR1_DIR
}
/SIMULATION/ETH_TRANSPORT/multicast_link.c
...
...
cmake_targets/build_oai
View file @
34c2f0be
...
@@ -58,7 +58,7 @@ CMAKE_CMD="$CMAKE"
...
@@ -58,7 +58,7 @@ CMAKE_CMD="$CMAKE"
NOAVX512
=
"False"
NOAVX512
=
"False"
BUILD_ECLIPSE
=
0
BUILD_ECLIPSE
=
0
NR
=
"False"
NR
=
"False"
OPTIONAL_LIBRARIES
=
"telnetsrv enbscope uescope nrscope"
OPTIONAL_LIBRARIES
=
"telnetsrv enbscope uescope nrscope
nrqtscope
"
RU
=
0
RU
=
0
CMAKE_C_FLAGS
=()
CMAKE_C_FLAGS
=()
CMAKE_CXX_FLAGS
=()
CMAKE_CXX_FLAGS
=()
...
@@ -752,11 +752,24 @@ function main() {
...
@@ -752,11 +752,24 @@ function main() {
######################
######################
# Optional libraries #
# Optional libraries #
######################
######################
if
[
!
-z
"
$BUILD_OPTLIB
"
]
;
then
if
[
!
-z
"
$BUILD_OPTLIB
"
]
;
then
for
oklib
in
$BUILD_OPTLIB
;
do
for
oklib
in
$BUILD_OPTLIB
;
do
compilations
\
if
[
"
$oklib
"
!=
"nrqtscope"
]
;
then
$BUILD_DIR
$oklib
\
compilations
\
lib
${
oklib
}
.so
$dbin
/lib
${
oklib
}
.so
$BUILD_DIR
$oklib
\
lib
${
oklib
}
.so
$dbin
/lib
${
oklib
}
.so
fi
if
[
"
$oklib
"
=
"nrqtscope"
]
;
then
HEAD_PATH
=
"
$(
find /usr/
-iname
qwidget.h
)
"
if
[
"
$HEAD_PATH
"
!=
""
]
;
then
compilations
\
$BUILD_DIR
$oklib
\
lib
${
oklib
}
.so
$dbin
/lib
${
oklib
}
.so
else
echo_warning
"qt scope could not compile; make sure to install the Qt packages!"
fi
fi
done
done
fi
fi
...
...
executables/nr-softmodem.c
View file @
34c2f0be
...
@@ -764,6 +764,16 @@ int main( int argc, char **argv ) {
...
@@ -764,6 +764,16 @@ int main( int argc, char **argv ) {
load_softscope
(
"nr"
,
&
p
);
load_softscope
(
"nr"
,
&
p
);
}
}
if
(
IS_SOFTMODEM_DOSCOPE_QT
)
{
sleep
(
1
);
scopeParms_t
p
;
p
.
argc
=&
argc
;
p
.
argv
=
argv
;
p
.
gNB
=
RC
.
gNB
[
0
];
p
.
ru
=
RC
.
ru
[
0
];
load_softscope
(
"nrqt"
,
&
p
);
}
if
(
NFAPI_MODE
!=
NFAPI_MODE_PNF
&&
NFAPI_MODE
!=
NFAPI_MODE_VNF
)
{
if
(
NFAPI_MODE
!=
NFAPI_MODE_PNF
&&
NFAPI_MODE
!=
NFAPI_MODE_VNF
)
{
printf
(
"Not NFAPI mode - call init_eNB_afterRU()
\n
"
);
printf
(
"Not NFAPI mode - call init_eNB_afterRU()
\n
"
);
init_eNB_afterRU
();
init_eNB_afterRU
();
...
...
executables/nr-uesoftmodem.c
View file @
34c2f0be
...
@@ -518,6 +518,10 @@ int main( int argc, char **argv ) {
...
@@ -518,6 +518,10 @@ int main( int argc, char **argv ) {
set_latency_target
();
set_latency_target
();
mlockall
(
MCL_CURRENT
|
MCL_FUTURE
);
mlockall
(
MCL_CURRENT
|
MCL_FUTURE
);
if
(
IS_SOFTMODEM_DOSCOPE_QT
)
{
load_softscope
(
"nrqt"
,
PHY_vars_UE_g
[
0
][
0
]);
}
if
(
IS_SOFTMODEM_DOSCOPE
)
{
if
(
IS_SOFTMODEM_DOSCOPE
)
{
load_softscope
(
"nr"
,
PHY_vars_UE_g
[
0
][
0
]);
load_softscope
(
"nr"
,
PHY_vars_UE_g
[
0
][
0
]);
}
}
...
...
executables/softmodem-common.c
View file @
34c2f0be
...
@@ -90,7 +90,7 @@ void get_common_options(uint32_t execmask) {
...
@@ -90,7 +90,7 @@ void get_common_options(uint32_t execmask) {
uint32_t
glog_level
=
0
;
uint32_t
glog_level
=
0
;
uint32_t
start_telnetsrv
=
0
,
start_telnetclt
=
0
;
uint32_t
start_telnetsrv
=
0
,
start_telnetclt
=
0
;
uint32_t
noS1
=
0
,
nokrnmod
=
1
,
nonbiot
=
0
;
uint32_t
noS1
=
0
,
nokrnmod
=
1
,
nonbiot
=
0
;
uint32_t
rfsim
=
0
,
do_forms
=
0
;
uint32_t
rfsim
=
0
,
do_forms
=
0
,
do_forms_qt
=
0
;
char
*
logmem_filename
=
NULL
;
char
*
logmem_filename
=
NULL
;
paramdef_t
cmdline_params
[]
=
CMDLINE_PARAMS_DESC
;
paramdef_t
cmdline_params
[]
=
CMDLINE_PARAMS_DESC
;
paramdef_t
cmdline_logparams
[]
=
CMDLINE_LOGPARAMS_DESC
;
paramdef_t
cmdline_logparams
[]
=
CMDLINE_LOGPARAMS_DESC
;
...
@@ -146,6 +146,10 @@ void get_common_options(uint32_t execmask) {
...
@@ -146,6 +146,10 @@ void get_common_options(uint32_t execmask) {
set_softmodem_optmask
(
SOFTMODEM_DOSCOPE_BIT
);
set_softmodem_optmask
(
SOFTMODEM_DOSCOPE_BIT
);
}
}
if
(
do_forms_qt
)
{
set_softmodem_optmask
(
SOFTMODEM_DOSCOPE_QT_BIT
);
}
if
(
parallel_config
!=
NULL
)
set_parallel_conf
(
parallel_config
);
if
(
parallel_config
!=
NULL
)
set_parallel_conf
(
parallel_config
);
if
(
worker_config
!=
NULL
)
set_worker_conf
(
worker_config
);
if
(
worker_config
!=
NULL
)
set_worker_conf
(
worker_config
);
...
...
executables/softmodem-common.h
View file @
34c2f0be
...
@@ -68,6 +68,7 @@ extern "C"
...
@@ -68,6 +68,7 @@ extern "C"
#define CONFIG_HLP_ULF "Set the uplink frequency offset for all component carriers\n"
#define CONFIG_HLP_ULF "Set the uplink frequency offset for all component carriers\n"
#define CONFIG_HLP_CHOFF "Channel id offset\n"
#define CONFIG_HLP_CHOFF "Channel id offset\n"
#define CONFIG_HLP_SOFTS "Enable soft scope and L1 and L2 stats (Xforms)\n"
#define CONFIG_HLP_SOFTS "Enable soft scope and L1 and L2 stats (Xforms)\n"
#define CONFIG_HLP_SOFTS_QT "Enable soft scope and L1 and L2 stats (QT)\n"
#define CONFIG_HLP_EXMCAL "Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n"
#define CONFIG_HLP_EXMCAL "Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n"
#define CONFIG_HLP_ITTIL "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n"
#define CONFIG_HLP_ITTIL "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n"
#define CONFIG_HLP_DLMCS "Set the maximum downlink MCS\n"
#define CONFIG_HLP_DLMCS "Set the maximum downlink MCS\n"
...
@@ -166,6 +167,7 @@ extern int usrp_tx_thread;
...
@@ -166,6 +167,7 @@ extern int usrp_tx_thread;
{"CO" , CONFIG_HLP_ULF, 0, iptr:&(uplink_frequency_offset[0][0]), defintval:0, TYPE_INT, 0}, \
{"CO" , CONFIG_HLP_ULF, 0, iptr:&(uplink_frequency_offset[0][0]), defintval:0, TYPE_INT, 0}, \
{"a" , CONFIG_HLP_CHOFF, 0, iptr:&CHAIN_OFFSET, defintval:0, TYPE_INT, 0}, \
{"a" , CONFIG_HLP_CHOFF, 0, iptr:&CHAIN_OFFSET, defintval:0, TYPE_INT, 0}, \
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \
{"dqt" , CONFIG_HLP_SOFTS_QT, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms_qt, defintval:0, TYPE_INT8, 0}, \
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \
{"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&NUMEROLOGY, defintval:1, TYPE_INT, 0}, \
{"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&NUMEROLOGY, defintval:1, TYPE_INT, 0}, \
{"band" , CONFIG_HLP_BAND, PARAMFLAG_BOOL, iptr:&BAND, defintval:78, TYPE_INT, 0}, \
{"band" , CONFIG_HLP_BAND, PARAMFLAG_BOOL, iptr:&BAND, defintval:78, TYPE_INT, 0}, \
...
@@ -238,6 +240,8 @@ extern int usrp_tx_thread;
...
@@ -238,6 +240,8 @@ extern int usrp_tx_thread;
#define SOFTMODEM_4GUE_BIT (1<<22)
#define SOFTMODEM_4GUE_BIT (1<<22)
#define SOFTMODEM_5GUE_BIT (1<<23)
#define SOFTMODEM_5GUE_BIT (1<<23)
#define SOFTMODEM_NOSTATS_BIT (1<<24)
#define SOFTMODEM_NOSTATS_BIT (1<<24)
#define SOFTMODEM_DOSCOPE_QT_BIT (1<<25)
#define SOFTMODEM_FUNC_BITS (SOFTMODEM_ENB_BIT | SOFTMODEM_GNB_BIT | SOFTMODEM_5GUE_BIT | SOFTMODEM_4GUE_BIT)
#define SOFTMODEM_FUNC_BITS (SOFTMODEM_ENB_BIT | SOFTMODEM_GNB_BIT | SOFTMODEM_5GUE_BIT | SOFTMODEM_4GUE_BIT)
#define MAPPING_SOFTMODEM_FUNCTIONS {{"enb",SOFTMODEM_ENB_BIT},{"gnb",SOFTMODEM_GNB_BIT},{"4Gue",SOFTMODEM_4GUE_BIT},{"5Gue",SOFTMODEM_5GUE_BIT}}
#define MAPPING_SOFTMODEM_FUNCTIONS {{"enb",SOFTMODEM_ENB_BIT},{"gnb",SOFTMODEM_GNB_BIT},{"4Gue",SOFTMODEM_4GUE_BIT},{"5Gue",SOFTMODEM_5GUE_BIT}}
...
@@ -249,6 +253,7 @@ extern int usrp_tx_thread;
...
@@ -249,6 +253,7 @@ extern int usrp_tx_thread;
#define IS_SOFTMODEM_SIML1 ( get_softmodem_optmask() & SOFTMODEM_SIML1_BIT)
#define IS_SOFTMODEM_SIML1 ( get_softmodem_optmask() & SOFTMODEM_SIML1_BIT)
#define IS_SOFTMODEM_DLSIM ( get_softmodem_optmask() & SOFTMODEM_DLSIM_BIT)
#define IS_SOFTMODEM_DLSIM ( get_softmodem_optmask() & SOFTMODEM_DLSIM_BIT)
#define IS_SOFTMODEM_DOSCOPE ( get_softmodem_optmask() & SOFTMODEM_DOSCOPE_BIT)
#define IS_SOFTMODEM_DOSCOPE ( get_softmodem_optmask() & SOFTMODEM_DOSCOPE_BIT)
#define IS_SOFTMODEM_DOSCOPE_QT ( get_softmodem_optmask() & SOFTMODEM_DOSCOPE_QT_BIT)
#define IS_SOFTMODEM_IQPLAYER ( get_softmodem_optmask() & SOFTMODEM_RECPLAY_BIT)
#define IS_SOFTMODEM_IQPLAYER ( get_softmodem_optmask() & SOFTMODEM_RECPLAY_BIT)
#define IS_SOFTMODEM_TELNETCLT_BIT ( get_softmodem_optmask() & SOFTMODEM_TELNETCLT_BIT)
#define IS_SOFTMODEM_TELNETCLT_BIT ( get_softmodem_optmask() & SOFTMODEM_TELNETCLT_BIT)
#define IS_SOFTMODEM_ENB_BIT ( get_softmodem_optmask() & SOFTMODEM_ENB_BIT)
#define IS_SOFTMODEM_ENB_BIT ( get_softmodem_optmask() & SOFTMODEM_ENB_BIT)
...
...
openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h
View file @
34c2f0be
...
@@ -300,6 +300,7 @@ void nr_sort_asc_int16_1D_array_ind(int32_t *matrix,
...
@@ -300,6 +300,7 @@ void nr_sort_asc_int16_1D_array_ind(int32_t *matrix,
void
nr_free_double_2D_array
(
double
**
input
,
uint16_t
xlen
);
void
nr_free_double_2D_array
(
double
**
input
,
uint16_t
xlen
);
#ifndef __cplusplus
void
updateLLR
(
uint8_t
listSize
,
void
updateLLR
(
uint8_t
listSize
,
uint16_t
row
,
uint16_t
row
,
uint16_t
col
,
uint16_t
col
,
...
@@ -327,7 +328,7 @@ void updatePathMetric2(double *pathMetric,
...
@@ -327,7 +328,7 @@ void updatePathMetric2(double *pathMetric,
int
ylen
,
int
ylen
,
int
zlen
,
int
zlen
,
double
llr
[
xlen
][
ylen
][
zlen
]);
double
llr
[
xlen
][
ylen
][
zlen
]);
#endif
//Also nr_polar_rate_matcher
//Also nr_polar_rate_matcher
static
inline
void
nr_polar_interleaver
(
uint8_t
*
input
,
static
inline
void
nr_polar_interleaver
(
uint8_t
*
input
,
uint8_t
*
output
,
uint8_t
*
output
,
...
...
openair1/PHY/NR_TRANSPORT/pucch_rx.c
View file @
34c2f0be
...
@@ -51,6 +51,8 @@
...
@@ -51,6 +51,8 @@
#include "nfapi/oai_integration/vendor_ext.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include "PHY/TOOLS/phy_scope_interface.h"
#include "T.h"
#include "T.h"
//#define DEBUG_NR_PUCCH_RX 1
//#define DEBUG_NR_PUCCH_RX 1
...
@@ -1688,6 +1690,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
...
@@ -1688,6 +1690,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
((
int16_t
*
)
&
llrs
[
half_prb
])[
7
]);
((
int16_t
*
)
&
llrs
[
half_prb
])[
7
]);
}
// half_prb
}
// half_prb
}
// symb
}
// symb
// run polar decoder on llrs
// run polar decoder on llrs
decoderState
=
polar_decoder_int16
((
int16_t
*
)
llrs
,
decodedPayload
,
0
,
2
,
nb_bit
,
pucch_pdu
->
prb_size
);
decoderState
=
polar_decoder_int16
((
int16_t
*
)
llrs
,
decodedPayload
,
0
,
2
,
nb_bit
,
pucch_pdu
->
prb_size
);
LOG_D
(
PHY
,
"UCI decoderState %d, payload[0] %llu
\n
"
,
decoderState
,(
unsigned
long
long
)
decodedPayload
[
0
]);
LOG_D
(
PHY
,
"UCI decoderState %d, payload[0] %llu
\n
"
,
decoderState
,(
unsigned
long
long
)
decodedPayload
[
0
]);
...
...
openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
View file @
34c2f0be
...
@@ -459,8 +459,12 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
...
@@ -459,8 +459,12 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
}
}
}
}
if
(
dmrss
==
2
)
scopeData_t
*
scope
=
(
scopeData_t
*
)
ue
->
scopeData
;
UEscopeCopy
(
ue
,
pbchDlChEstimateTime
,
(
void
*
)
dl_ch_estimates_time
,
sizeof
(
struct
complex16
),
ue
->
frame_parms
.
nb_antennas_rx
,
ue
->
frame_parms
.
ofdm_symbol_size
);
if
((
scope
)
&&
(
dmrss
==
2
)){
int
istreamingFlag
=
scope
->
flag_streaming
[
pbchDlChEstimateTime
];
if
(
istreamingFlag
==
1
)
UEscopeCopy
(
ue
,
pbchDlChEstimateTime
,
(
void
*
)
dl_ch_estimates_time
,
sizeof
(
struct
complex16
),
ue
->
frame_parms
.
nb_antennas_rx
,
ue
->
frame_parms
.
ofdm_symbol_size
);
}
return
(
0
);
return
(
0
);
}
}
...
...
openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
View file @
34c2f0be
...
@@ -749,8 +749,12 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
...
@@ -749,8 +749,12 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
log2_maxh
,
log2_maxh
,
n_rb
);
// log2_maxh+I0_shift
n_rb
);
// log2_maxh+I0_shift
UEscopeCopy
(
ue
,
pdcchRxdataF_comp
,
rxdataF_comp
,
sizeof
(
struct
complex16
),
frame_parms
->
nb_antennas_rx
,
rx_size
);
scopeData_t
*
scope
=
(
scopeData_t
*
)
ue
->
scopeData
;
if
(
scope
){
int
istreamingFlag
=
scope
->
flag_streaming
[
pdcchRxdataF_comp
];
if
(
istreamingFlag
==
1
)
UEscopeCopy
(
ue
,
pdcchRxdataF_comp
,
rxdataF_comp
,
sizeof
(
struct
complex16
),
frame_parms
->
nb_antennas_rx
,
rx_size
);
}
if
(
frame_parms
->
nb_antennas_rx
>
1
)
{
if
(
frame_parms
->
nb_antennas_rx
>
1
)
{
LOG_D
(
PHY
,
"we enter nr_pdcch_detection_mrc(frame_parms->nb_antennas_rx=%d)
\n
"
,
frame_parms
->
nb_antennas_rx
);
LOG_D
(
PHY
,
"we enter nr_pdcch_detection_mrc(frame_parms->nb_antennas_rx=%d)
\n
"
,
frame_parms
->
nb_antennas_rx
);
nr_pdcch_detection_mrc
(
frame_parms
,
rx_size
,
rxdataF_comp
,
s
);
nr_pdcch_detection_mrc
(
frame_parms
,
rx_size
,
rxdataF_comp
,
s
);
...
@@ -765,7 +769,11 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
...
@@ -765,7 +769,11 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
s
,
s
,
n_rb
);
n_rb
);
UEscopeCopy
(
ue
,
pdcchLlr
,
llr
,
sizeof
(
int16_t
),
1
,
llr_size
);
if
(
scope
){
int
istreamingFlag
=
scope
->
flag_streaming
[
pdcchLlr
];
if
(
istreamingFlag
==
1
)
UEscopeCopy
(
ue
,
pdcchLlr
,
llr
,
sizeof
(
int16_t
),
1
,
llr_size
);
}
#if T_TRACER
#if T_TRACER
...
...
openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
View file @
34c2f0be
...
@@ -44,6 +44,7 @@
...
@@ -44,6 +44,7 @@
#include "executables/nr-uesoftmodem.h"
#include "executables/nr-uesoftmodem.h"
#include "PHY/CODING/nrLDPC_extern.h"
#include "PHY/CODING/nrLDPC_extern.h"
#include "common/utils/nr/nr_common.h"
#include "common/utils/nr/nr_common.h"
#include "openair1/PHY/TOOLS/phy_scope_interface.h"
//#define ENABLE_PHY_PAYLOAD_DEBUG 1
//#define ENABLE_PHY_PAYLOAD_DEBUG 1
...
@@ -53,10 +54,51 @@
...
@@ -53,10 +54,51 @@
static
uint64_t
nb_total_decod
=
0
;
static
uint64_t
nb_total_decod
=
0
;
static
uint64_t
nb_error_decod
=
0
;
static
uint64_t
nb_error_decod
=
0
;
static
int
nb_ack
=
0
;
static
int
nb_nack
=
0
;
static
uint32_t
blockSize
=
0
;
static
uint8_t
dl_mcs
=
0
;
static
uint16_t
nofRBs
=
0
;
notifiedFIFO_t
freeBlocks_dl
;
notifiedFIFO_t
freeBlocks_dl
;
notifiedFIFO_elt_t
*
msgToPush_dl
;
notifiedFIFO_elt_t
*
msgToPush_dl
;
int
nbDlProcessing
=
0
;
int
nbDlProcessing
=
0
;
static
tpool_t
pool_dl
;
//extern double cpuf;
void
getKPIUE
(
extended_kpi_ue
*
kpiStructure
)
{
float
dl_bler
=
1
.
0
;
if
(
nb_ack
>
0
){
dl_bler
=
(
float
)
nb_nack
/
(
float
)
nb_ack
;
}
kpiStructure
->
DL_BLER
=
dl_bler
;
kpiStructure
->
blockSize
=
blockSize
;
kpiStructure
->
dl_mcs
=
dl_mcs
;
kpiStructure
->
nofRBs
=
nofRBs
;
}
void
init_dlsch_tpool
(
uint8_t
num_dlsch_threads
)
{
char
*
params
=
NULL
;
if
(
num_dlsch_threads
==
0
)
{
params
=
calloc
(
1
,
2
);
memcpy
(
params
,
"N"
,
1
);
}
else
{
params
=
calloc
(
1
,(
num_dlsch_threads
*
3
)
+
1
);
for
(
int
i
=
0
;
i
<
num_dlsch_threads
;
i
++
)
{
memcpy
(
params
+
(
i
*
3
),
"-1,"
,
3
);
}
}
initNamedTpool
(
params
,
&
pool_dl
,
false
,
"dlsch"
);
free
(
params
);
}
void
free_nr_ue_dlsch
(
NR_UE_DLSCH_t
**
dlschptr
,
uint16_t
N_RB_DL
)
{
void
free_nr_ue_dlsch
(
NR_UE_DLSCH_t
**
dlschptr
,
uint16_t
N_RB_DL
)
{
uint16_t
a_segments
=
MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER
*
NR_MAX_NB_LAYERS
;
uint16_t
a_segments
=
MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER
*
NR_MAX_NB_LAYERS
;
...
@@ -194,6 +236,11 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool
...
@@ -194,6 +236,11 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool
// if all segments are done
// if all segments are done
if
(
last
)
{
if
(
last
)
{
nb_ack
++
;
blockSize
=
harq_process
->
TBS
;
dl_mcs
=
harq_process
->
mcs
;
nofRBs
=
harq_process
->
nb_rb
;
if
(
decodeSuccess
)
{
if
(
decodeSuccess
)
{
//LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n",
//LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n",
// phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round);
// phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round);
...
@@ -209,6 +256,7 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool
...
@@ -209,6 +256,7 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool
dlsch
->
last_iteration_cnt
=
rdata
->
decodeIterations
;
dlsch
->
last_iteration_cnt
=
rdata
->
decodeIterations
;
LOG_D
(
PHY
,
"DLSCH received ok
\n
"
);
LOG_D
(
PHY
,
"DLSCH received ok
\n
"
);
}
else
{
}
else
{
nb_nack
++
;
//LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
//LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
// phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
// phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
harq_process
->
ack
=
0
;
harq_process
->
ack
=
0
;
...
...
openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
View file @
34c2f0be
...
@@ -487,8 +487,17 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
...
@@ -487,8 +487,17 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
}
}
// legacy code use int16, but it is complex16
// legacy code use int16, but it is complex16
UEscopeCopy
(
ue
,
pbchRxdataF_comp
,
pbch_unClipped
,
sizeof
(
struct
complex16
),
frame_parms
->
nb_antennas_rx
,
pbch_e_rx_idx
/
2
);
scopeData_t
*
scope
=
(
scopeData_t
*
)
ue
->
scopeData
;
UEscopeCopy
(
ue
,
pbchLlr
,
pbch_e_rx
,
sizeof
(
int16_t
),
frame_parms
->
nb_antennas_rx
,
pbch_e_rx_idx
);
if
(
scope
)
{
int
istreamingFlag
=
scope
->
flag_streaming
[
pbchRxdataF_comp
];
if
(
istreamingFlag
==
1
)
UEscopeCopy
(
ue
,
pbchRxdataF_comp
,
pbch_unClipped
,
sizeof
(
struct
complex16
),
frame_parms
->
nb_antennas_rx
,
pbch_e_rx_idx
/
2
);
istreamingFlag
=
scope
->
flag_streaming
[
pbchLlr
];
if
(
istreamingFlag
==
1
)
UEscopeCopy
(
ue
,
pbchLlr
,
pbch_e_rx
,
sizeof
(
int16_t
),
frame_parms
->
nb_antennas_rx
,
pbch_e_rx_idx
);
}
#ifdef DEBUG_PBCH
#ifdef DEBUG_PBCH
write_output
(
"rxdataF_comp.m"
,
"rxFcomp"
,
rxdataF_comp
[
0
],
240
*
3
,
1
,
1
);
write_output
(
"rxdataF_comp.m"
,
"rxFcomp"
,
rxdataF_comp
[
0
],
240
*
3
,
1
,
1
);
short
*
p
=
(
short
*
)
rxdataF_comp
[
0
]);
short
*
p
=
(
short
*
)
rxdataF_comp
[
0
]);
...
...
openair1/PHY/TOOLS/nr_phy_qt_scope.cpp
0 → 100644
View file @
34c2f0be
#include <QApplication>
#include <QtWidgets>
#include <QPainter>
#include <QtGui>
#include "nr_phy_qt_scope.h"
#include <iostream>
#include <string.h>
#include <unistd.h>
#include <cassert>
#include <cmath>
#include <QtCharts>
#include <qchart.h>
#include <QValueAxis>
extern
"C"
{
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
#include <openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h>
}
typedef
struct
complex16
scopeSample_t
;
#define ScaleZone 4;
#define SquaredNorm(VaR) ((VaR).r*(VaR).r+(VaR).i*(VaR).i)
const
float
Limits_KPI_gNB
[
4
][
2
]
=
{
// {lower Limit, Upper Limit}
{
0.02
,
0.8
},
// UL BLER
{
0.2
,
10
},
// UL Throughput in Mbs
{
0.02
,
0.8
},
// DL BLER
{
0.2
,
10
}
// DL Throughput in Mbs
};
const
float
Limits_KPI_ue
[
2
][
2
]
=
{
// {lower Limit, Upper Limit}
{
0.02
,
0.8
},
// DL BLER
{
0.2
,
10
}
// Throughput in Mbs
};
typedef
struct
{
int
dataSize
;
int
elementSz
;
int
colSz
;
int
lineSz
;
}
scopeGraphData_t
;
KPIListSelect
::
KPIListSelect
(
QWidget
*
parent
)
:
QComboBox
(
parent
)
{
this
->
addItem
(
"I/Q PBCH"
,
0
);
this
->
addItem
(
"LLR PBCH"
,
1
);
this
->
addItem
(
"I/Q PDSCH"
,
2
);
this
->
addItem
(
"LLR PDSCH"
,
3
);
this
->
addItem
(
"I/Q PDCCH"
,
4
);
this
->
addItem
(
"LLR PDCCH"
,
5
);
this
->
addItem
(
"RX Signal-Time"
,
6
);
this
->
addItem
(
"Channel Response"
,
7
);
this
->
addItem
(
"DL BLER"
,
8
);
this
->
addItem
(
"Throughput"
,
9
);
this
->
addItem
(
"DL MCS"
,
10
);
this
->
addItem
(
"Nof Sched. RBs"
,
11
);
}
KPIListSelect
::~
KPIListSelect
()
{
}
KPIListSelectgNB
::
KPIListSelectgNB
(
QWidget
*
parent
)
:
QComboBox
(
parent
)
{
this
->
addItem
(
"I/Q PUSCH"
,
0
);
this
->
addItem
(
"LLR PUSCH"
,
1
);
this
->
addItem
(
"Channel Response"
,
2
);
this
->
addItem
(
"UL BLER"
,
3
);
this
->
addItem
(
"DL BLER"
,
4
);
this
->
addItem
(
"DL MCS"
,
5
);
this
->
addItem
(
"UL MCS"
,
6
);
this
->
addItem
(
"UL Throughput"
,
7
);
this
->
addItem
(
"DL Throughput"
,
8
);
this
->
addItem
(
"Nof Sched. RBs"
,
9
);
this
->
addItem
(
"UL SNR"
,
10
);
this
->
addItem
(
"DL SNR (CQI)"
,
11
);
this
->
addItem
(
"UL Retrans."
,
12
);
this
->
addItem
(
"DL Retrans."
,
13
);
}
KPIListSelectgNB
::~
KPIListSelectgNB
()
{
}
PainterWidgetgNB
::
PainterWidgetgNB
(
QComboBox
*
parent
,
scopeData_t
*
p
)
{
timer
=
new
QTimer
(
this
);
timerRetrans
=
new
QTimer
(
this
);
this
->
chartHight
=
300
;
this
->
chartWidth
=
300
;
this
->
pix
=
new
QPixmap
(
this
->
chartWidth
,
this
->
chartHight
);
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
this
->
parentWindow
=
parent
;
this
->
p
=
p
;
this
->
nb_UEs
=
1
;
this
->
indexToPlot
=
this
->
parentWindow
->
currentIndex
();
this
->
previousIndex
=
this
->
parentWindow
->
currentIndex
();
// UL BLER
this
->
ULBLER
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
ULBLER
);
// UL MCS
this
->
ULMCS
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
ULMCS
);
resetKPIValues
(
&
this
->
ULMCS
);
// DL BLER
this
->
DLBLER
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
DLBLER
);
// DL MCS
this
->
DLMCS
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
DLMCS
);
resetKPIValues
(
&
this
->
DLMCS
);
// UL Throughput
this
->
ULThrou
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
ULThrou
);
resetKPIValues
(
&
this
->
ULThrou
);
// DL Throughput
this
->
DLThrou
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
DLThrou
);
resetKPIValues
(
&
this
->
DLThrou
);
// nof scheduled RBs
this
->
nofRBs
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
nofRBs
);
resetKPIValues
(
&
this
->
nofRBs
);
// UL SNR
this
->
ULSNR
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
ULSNR
);
resetKPIValues
(
&
this
->
ULSNR
);
// DL SNR
this
->
DLSNR
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
DLSNR
);
resetKPIValues
(
&
this
->
DLSNR
);
// UL Retrans
this
->
ULRetrans
[
0
].
plot_idx
=
0
;
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
resetKPIPlot
(
&
this
->
ULRetrans
[
i
]);
resetKPIValues
(
&
this
->
ULRetrans
[
i
]);
}
this
->
ULRetrans
[
0
].
series
->
setName
(
"R. 1"
);
this
->
ULRetrans
[
1
].
series
->
setName
(
"R. 2"
);
this
->
ULRetrans
[
2
].
series
->
setName
(
"R. 3"
);
this
->
ULRetrans
[
3
].
series
->
setName
(
"R. 4"
);
// DL Retrans
this
->
DLRetrans
[
0
].
plot_idx
=
0
;
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
resetKPIPlot
(
&
this
->
DLRetrans
[
i
]);
resetKPIValues
(
&
this
->
DLRetrans
[
i
]);
}
this
->
DLRetrans
[
0
].
series
->
setName
(
"R. 1"
);
this
->
DLRetrans
[
1
].
series
->
setName
(
"R. 2"
);
this
->
DLRetrans
[
2
].
series
->
setName
(
"R. 3"
);
this
->
DLRetrans
[
3
].
series
->
setName
(
"R. 4"
);
makeConnections
();
}
void
PainterWidgetgNB
::
resetKPIPlot
(
KPI_elements
*
inputStruct
)
{
inputStruct
->
series
=
new
QLineSeries
();
inputStruct
->
series
->
setColor
(
QColor
(
0
,
0
,
0
));
inputStruct
->
seriesMin
=
new
QLineSeries
();
inputStruct
->
seriesMin
->
setColor
(
QColor
(
255
,
0
,
0
));
inputStruct
->
seriesMin
->
setName
(
"Min."
);
inputStruct
->
seriesMax
=
new
QLineSeries
();
inputStruct
->
seriesMax
->
setColor
(
QColor
(
0
,
255
,
0
));
inputStruct
->
seriesMax
->
setName
(
"Max."
);
inputStruct
->
seriesAvg
=
new
QLineSeries
();
inputStruct
->
seriesAvg
->
setColor
(
QColor
(
0
,
0
,
255
));
inputStruct
->
seriesAvg
->
setName
(
"Avg."
);
}
void
PainterWidgetgNB
::
resetKPIValues
(
KPI_elements
*
inputStruct
)
{
inputStruct
->
max_value
=
0.0
;
inputStruct
->
min_value
=
0.0
;
inputStruct
->
avg_value
=
0.0
;
inputStruct
->
avg_idx
=
0
;
inputStruct
->
nof_retrans
=
0
;
}
void
PainterWidgetgNB
::
resizeEvent
(
QResizeEvent
*
event
)
{
if
((
width
()
!=
this
->
chartWidth
)
||
(
height
()
!=
this
->
chartHight
))
{
this
->
chartHight
=
height
();
this
->
chartWidth
=
width
();
update
();
}
QWidget
::
resizeEvent
(
event
);
}
void
PainterWidgetgNB
::
paintEvent
(
QPaintEvent
*
)
{
QPainter
painter
(
this
);
painter
.
drawPixmap
(
(
this
->
width
()
-
this
->
pix
->
width
())
/
2
,
(
this
->
height
()
-
this
->
pix
->
height
())
/
2
,
*
this
->
pix
);
// paint pixmap on widget
this
->
indexToPlot
=
this
->
parentWindow
->
currentIndex
();
makeConnections
();
}
void
PainterWidgetgNB
::
makeConnections
()
{
disconnect
(
timer
,
nullptr
,
nullptr
,
nullptr
);
if
(
this
->
indexToPlot
==
0
)
{
connect
(
timer
,
&
QTimer
::
timeout
,
this
,
&
PainterWidgetgNB
::
KPI_PuschIQ
);
}
else
if
(
this
->
indexToPlot
==
1
)
{
connect
(
timer
,
&
QTimer
::
timeout
,
this
,
&
PainterWidgetgNB
::
KPI_PuschLLR
);
// paintPixmap_uePbchIQ
}
else
if
(
this
->
indexToPlot
==
2
)
{
connect
(
timer
,
&
QTimer
::
timeout
,
this
,
&
PainterWidgetgNB
::
KPI_ChannelResponse
);
}
else
if
(
this
->
indexToPlot
==
3
)
{
connect
(
timer
,
&
QTimer
::
timeout
,
this
,
&
PainterWidgetgNB
::
KPI_UL_BLER
);
}
else
if
(
this
->
indexToPlot
==
4
)
{
connect
(
timer
,
&
QTimer
::
timeout
,
this
,
&
PainterWidgetgNB
::
KPI_DL_BLER
);
}
else
if
(
this
->
indexToPlot
==
5
)
{
connect
(
timer
,
&
QTimer
::
timeout
,
this
,
&
PainterWidgetgNB
::
KPI_DL_MCS
);
}
else
if
(
this
->
indexToPlot
==
6
)
{
connect
(
timer
,
&
QTimer
::
timeout
,
this
,
&
PainterWidgetgNB
::
KPI_UL_MCS
);
}
else
if
(
this
->
indexToPlot
==
7
)
{
connect
(
timer
,
&
QTimer
::
timeout
,
this
,
&
PainterWidgetgNB
::
KPI_UL_Throu
);
}
else
if
(
this
->
indexToPlot
==
8
)
{
connect
(
timer
,
&
QTimer
::
timeout
,
this
,
&
PainterWidgetgNB
::
KPI_DL_Throu
);
}
else
if
(
this
->
indexToPlot
==
9
)
{
connect
(
timer
,
&
QTimer
::
timeout
,
this
,
&
PainterWidgetgNB
::
KPI_Nof_RBs
);
}
else
if
(
this
->
indexToPlot
==
10
)
{
connect
(
timer
,
&
QTimer
::
timeout
,
this
,
&
PainterWidgetgNB
::
KPI_UL_SNR
);
}
else
if
(
this
->
indexToPlot
==
11
)
{
connect
(
timer
,
&
QTimer
::
timeout
,
this
,
&
PainterWidgetgNB
::
KPI_DL_SNR
);
}
else
if
(
this
->
indexToPlot
==
12
)
{
connect
(
timerRetrans
,
&
QTimer
::
timeout
,
this
,
&
PainterWidgetgNB
::
KPI_UL_Retrans
);
}
else
if
(
this
->
indexToPlot
==
13
)
{
connect
(
timerRetrans
,
&
QTimer
::
timeout
,
this
,
&
PainterWidgetgNB
::
KPI_DL_Retrans
);
}
timer
->
start
(
200
);
timerRetrans
->
start
(
1000
);
}
void
PainterWidgetgNB
::
KPI_DL_Retrans
()
{
// erase the previous paint
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
gNB_MAC_INST
*
gNBMac
=
(
gNB_MAC_INST
*
)
RC
.
nrmac
[
0
];
NR_UE_info_t
*
targetUE
=
gNBMac
->
UE_info
.
list
[
0
];
if
((
this
->
DLRetrans
[
0
].
plot_idx
>
this
->
chartWidth
)
||
(
this
->
indexToPlot
!=
this
->
previousIndex
))
{
this
->
DLRetrans
[
0
].
plot_idx
=
0
;
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
resetKPIPlot
(
&
this
->
DLRetrans
[
i
]);
resetKPIValues
(
&
this
->
DLRetrans
[
i
]);
}
this
->
DLRetrans
[
0
].
series
->
setName
(
"R. 1"
);
this
->
DLRetrans
[
1
].
series
->
setName
(
"R. 2"
);
this
->
DLRetrans
[
2
].
series
->
setName
(
"R. 3"
);
this
->
DLRetrans
[
3
].
series
->
setName
(
"R. 4"
);
}
float
Xpaint
=
this
->
DLRetrans
[
0
].
plot_idx
;
float
Ypaint
[
4
];
uint64_t
nrRetrans
;
for
(
int
i
=
0
;
i
<
4
;
i
++
){
nrRetrans
=
targetUE
->
mac_stats
.
dl
.
rounds
[
i
]
-
this
->
DLRetrans
[
i
].
nof_retrans
;
Ypaint
[
i
]
=
(
float
)
nrRetrans
;
this
->
DLRetrans
[
i
].
nof_retrans
=
targetUE
->
mac_stats
.
dl
.
rounds
[
i
];
}
if
(
this
->
DLRetrans
[
0
].
plot_idx
!=
0
)
{
this
->
DLRetrans
[
0
].
max_value
=
std
::
max
(
this
->
DLRetrans
[
0
].
max_value
,
Ypaint
[
0
]);
for
(
int
i
=
0
;
i
<
4
;
i
++
){
this
->
DLRetrans
[
i
].
series
->
append
(
Xpaint
,
Ypaint
[
i
]);
}
}
QChart
*
chart
=
new
QChart
();
chart
->
legend
()
->
setVisible
(
true
);
chart
->
legend
()
->
setAlignment
(
Qt
::
AlignBottom
);
int
nofTicks
=
6
;
QValueAxis
*
axisX
=
new
QValueAxis
;
axisX
->
setTickCount
(
nofTicks
);
axisX
->
setRange
(
0
,
this
->
chartWidth
);
axisX
->
setTitleText
(
"Time Index"
);
chart
->
addAxis
(
axisX
,
Qt
::
AlignBottom
);
QValueAxis
*
axisY
=
new
QValueAxis
;
axisY
->
setTickCount
(
nofTicks
);
axisY
->
setRange
(
-
1
,
this
->
DLRetrans
[
0
].
max_value
+
5
);
axisY
->
setTitleText
(
"Nof Retrans."
);
chart
->
addAxis
(
axisY
,
Qt
::
AlignLeft
);
if
(
this
->
DLRetrans
[
0
].
plot_idx
!=
0
)
{
for
(
int
i
=
0
;
i
<
4
;
i
++
){
chart
->
addSeries
(
this
->
DLRetrans
[
i
].
series
);
this
->
DLRetrans
[
i
].
series
->
attachAxis
(
axisX
);
this
->
DLRetrans
[
i
].
series
->
attachAxis
(
axisY
);
}
}
QChartView
*
chartView
=
new
QChartView
(
chart
);
chartView
->
resize
(
this
->
chartWidth
,
this
->
chartHight
);
QPixmap
p
=
chartView
->
grab
();
*
this
->
pix
=
p
;
this
->
previousIndex
=
this
->
parentWindow
->
currentIndex
();
this
->
DLRetrans
[
0
].
plot_idx
++
;
update
();
}
void
PainterWidgetgNB
::
KPI_UL_Retrans
()
{
// erase the previous paint
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
gNB_MAC_INST
*
gNBMac
=
(
gNB_MAC_INST
*
)
RC
.
nrmac
[
0
];
NR_UE_info_t
*
targetUE
=
gNBMac
->
UE_info
.
list
[
0
];
if
((
this
->
ULRetrans
[
0
].
plot_idx
>
this
->
chartWidth
)
||
(
this
->
indexToPlot
!=
this
->
previousIndex
))
{
this
->
ULRetrans
[
0
].
plot_idx
=
0
;
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
resetKPIPlot
(
&
this
->
ULRetrans
[
i
]);
resetKPIValues
(
&
this
->
ULRetrans
[
i
]);
}
this
->
ULRetrans
[
0
].
series
->
setName
(
"R. 1"
);
this
->
ULRetrans
[
1
].
series
->
setName
(
"R. 2"
);
this
->
ULRetrans
[
2
].
series
->
setName
(
"R. 3"
);
this
->
ULRetrans
[
3
].
series
->
setName
(
"R. 4"
);
}
float
Xpaint
=
this
->
ULRetrans
[
0
].
plot_idx
;
float
Ypaint
[
4
];
uint64_t
nrRetrans
;
for
(
int
i
=
0
;
i
<
4
;
i
++
){
nrRetrans
=
targetUE
->
mac_stats
.
ul
.
rounds
[
i
]
-
this
->
ULRetrans
[
i
].
nof_retrans
;
Ypaint
[
i
]
=
(
float
)
nrRetrans
;
this
->
ULRetrans
[
i
].
nof_retrans
=
targetUE
->
mac_stats
.
ul
.
rounds
[
i
];
}
if
(
this
->
ULRetrans
[
0
].
plot_idx
!=
0
)
{
this
->
ULRetrans
[
0
].
max_value
=
std
::
max
(
this
->
ULRetrans
[
0
].
max_value
,
Ypaint
[
0
]);
for
(
int
i
=
0
;
i
<
4
;
i
++
){
this
->
ULRetrans
[
i
].
series
->
append
(
Xpaint
,
Ypaint
[
i
]);
}
}
QChart
*
chart
=
new
QChart
();
chart
->
legend
()
->
setVisible
(
true
);
chart
->
legend
()
->
setAlignment
(
Qt
::
AlignBottom
);
int
nofTicks
=
6
;
QValueAxis
*
axisX
=
new
QValueAxis
;
axisX
->
setTickCount
(
nofTicks
);
axisX
->
setRange
(
0
,
this
->
chartWidth
);
axisX
->
setTitleText
(
"Time Index"
);
chart
->
addAxis
(
axisX
,
Qt
::
AlignBottom
);
QValueAxis
*
axisY
=
new
QValueAxis
;
axisY
->
setTickCount
(
nofTicks
);
axisY
->
setRange
(
-
1
,
this
->
ULRetrans
[
0
].
max_value
+
5
);
axisY
->
setTitleText
(
"Nof Retrans."
);
chart
->
addAxis
(
axisY
,
Qt
::
AlignLeft
);
if
(
this
->
ULRetrans
[
0
].
plot_idx
!=
0
)
{
for
(
int
i
=
0
;
i
<
4
;
i
++
){
chart
->
addSeries
(
this
->
ULRetrans
[
i
].
series
);
this
->
ULRetrans
[
i
].
series
->
attachAxis
(
axisX
);
this
->
ULRetrans
[
i
].
series
->
attachAxis
(
axisY
);
}
}
QChartView
*
chartView
=
new
QChartView
(
chart
);
chartView
->
resize
(
this
->
chartWidth
,
this
->
chartHight
);
QPixmap
p
=
chartView
->
grab
();
*
this
->
pix
=
p
;
this
->
previousIndex
=
this
->
parentWindow
->
currentIndex
();
this
->
ULRetrans
[
0
].
plot_idx
++
;
update
();
}
void
PainterWidgetgNB
::
KPI_DL_SNR
()
{
// erase the previous paint
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
gNB_MAC_INST
*
gNBMac
=
(
gNB_MAC_INST
*
)
RC
.
nrmac
[
0
];
NR_UE_info_t
*
targetUE
=
gNBMac
->
UE_info
.
list
[
0
];
NR_UE_sched_ctrl_t
*
sched_ctrl
=
&
targetUE
->
UE_sched_ctrl
;
if
((
this
->
DLSNR
.
plot_idx
>
this
->
chartWidth
)
||
(
this
->
indexToPlot
!=
this
->
previousIndex
))
{
this
->
DLSNR
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
DLSNR
);
}
float
Xpaint
,
Ypaint
;
Xpaint
=
this
->
DLSNR
.
plot_idx
;
Ypaint
=
(
float
)
sched_ctrl
->
CSI_report
.
cri_ri_li_pmi_cqi_report
.
wb_cqi_1tb
;
this
->
DLSNR
.
max_value
=
std
::
max
(
this
->
DLSNR
.
max_value
,
Ypaint
);
this
->
DLSNR
.
series
->
append
(
Xpaint
,
Ypaint
);
QChart
*
chart
=
new
QChart
();
chart
->
legend
()
->
hide
();
int
nofTicks
=
6
;
QValueAxis
*
axisX
=
new
QValueAxis
;
axisX
->
setTickCount
(
nofTicks
);
axisX
->
setRange
(
0
,
this
->
chartWidth
);
axisX
->
setTitleText
(
"Time Index"
);
chart
->
addAxis
(
axisX
,
Qt
::
AlignBottom
);
QValueAxis
*
axisY
=
new
QValueAxis
;
axisY
->
setTickCount
(
nofTicks
);
axisY
->
setRange
(
-
1
,
this
->
DLSNR
.
max_value
+
2
);
axisY
->
setTitleText
(
"DL SNR (CQI)"
);
chart
->
addAxis
(
axisY
,
Qt
::
AlignLeft
);
chart
->
addSeries
(
this
->
DLSNR
.
series
);
this
->
DLSNR
.
series
->
attachAxis
(
axisX
);
this
->
DLSNR
.
series
->
attachAxis
(
axisY
);
QChartView
*
chartView
=
new
QChartView
(
chart
);
chartView
->
resize
(
this
->
chartWidth
,
this
->
chartHight
);
QPixmap
p
=
chartView
->
grab
();
*
this
->
pix
=
p
;
this
->
previousIndex
=
this
->
parentWindow
->
currentIndex
();
this
->
DLSNR
.
plot_idx
++
;
update
();
}
void
PainterWidgetgNB
::
KPI_UL_SNR
()
{
// erase the previous paint
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
gNB_MAC_INST
*
gNBMac
=
(
gNB_MAC_INST
*
)
RC
.
nrmac
[
0
];
NR_UE_info_t
*
targetUE
=
gNBMac
->
UE_info
.
list
[
0
];
NR_UE_sched_ctrl_t
*
sched_ctrl
=
&
targetUE
->
UE_sched_ctrl
;
if
((
this
->
ULSNR
.
plot_idx
>
this
->
chartWidth
)
||
(
this
->
indexToPlot
!=
this
->
previousIndex
))
{
this
->
ULSNR
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
ULSNR
);
}
float
Xpaint
,
Ypaint
;
Xpaint
=
this
->
ULSNR
.
plot_idx
;
Ypaint
=
(
float
)
sched_ctrl
->
pusch_snrx10
/
10.0
;
this
->
ULSNR
.
max_value
=
std
::
max
(
this
->
ULSNR
.
max_value
,
Ypaint
);
this
->
ULSNR
.
series
->
append
(
Xpaint
,
Ypaint
);
QChart
*
chart
=
new
QChart
();
chart
->
legend
()
->
hide
();
int
nofTicks
=
6
;
QValueAxis
*
axisX
=
new
QValueAxis
;
axisX
->
setTickCount
(
nofTicks
);
axisX
->
setRange
(
0
,
this
->
chartWidth
);
axisX
->
setTitleText
(
"Time Index"
);
chart
->
addAxis
(
axisX
,
Qt
::
AlignBottom
);
QValueAxis
*
axisY
=
new
QValueAxis
;
axisY
->
setTickCount
(
nofTicks
);
axisY
->
setRange
(
-
1
,
1.2
*
this
->
ULSNR
.
max_value
);
axisY
->
setTitleText
(
"PUSCH SNR dB"
);
chart
->
addAxis
(
axisY
,
Qt
::
AlignLeft
);
chart
->
addSeries
(
this
->
ULSNR
.
series
);
this
->
ULSNR
.
series
->
attachAxis
(
axisX
);
this
->
ULSNR
.
series
->
attachAxis
(
axisY
);
QChartView
*
chartView
=
new
QChartView
(
chart
);
chartView
->
resize
(
this
->
chartWidth
,
this
->
chartHight
);
QPixmap
p
=
chartView
->
grab
();
*
this
->
pix
=
p
;
this
->
previousIndex
=
this
->
parentWindow
->
currentIndex
();
this
->
ULSNR
.
plot_idx
++
;
update
();
}
void
PainterWidgetgNB
::
KPI_Nof_RBs
()
{
// erase the previous paint
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
gNB_MAC_INST
*
gNBMac
=
(
gNB_MAC_INST
*
)
RC
.
nrmac
[
0
];
NR_UE_info_t
*
targetUE
=
gNBMac
->
UE_info
.
list
[
0
];
NR_UE_sched_ctrl_t
*
sched_ctrl
=
&
targetUE
->
UE_sched_ctrl
;
NR_sched_pdsch_t
*
sched_pdsch
=
&
sched_ctrl
->
sched_pdsch
;
int
current_harq_pid
=
(
int
)
sched_pdsch
->
dl_harq_pid
;
uint16_t
rbSize
=
(
uint16_t
)
sched_ctrl
->
harq_processes
[
current_harq_pid
].
sched_pdsch
.
rbSize
;
if
((
this
->
nofRBs
.
plot_idx
>
this
->
chartWidth
)
||
(
this
->
indexToPlot
!=
this
->
previousIndex
))
{
this
->
nofRBs
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
nofRBs
);
}
float
Xpaint
,
Ypaint
;
Xpaint
=
this
->
nofRBs
.
plot_idx
;
Ypaint
=
(
float
)
rbSize
;
this
->
nofRBs
.
max_value
=
std
::
max
(
this
->
nofRBs
.
max_value
,
Ypaint
);
this
->
nofRBs
.
series
->
append
(
Xpaint
,
Ypaint
);
QChart
*
chart
=
new
QChart
();
chart
->
legend
()
->
hide
();
int
nofTicks
=
6
;
QValueAxis
*
axisX
=
new
QValueAxis
;
axisX
->
setTickCount
(
nofTicks
);
axisX
->
setRange
(
0
,
this
->
chartWidth
);
axisX
->
setTitleText
(
"Time Index"
);
chart
->
addAxis
(
axisX
,
Qt
::
AlignBottom
);
QValueAxis
*
axisY
=
new
QValueAxis
;
axisY
->
setTickCount
(
nofTicks
);
axisY
->
setRange
(
-
1
,
this
->
nofRBs
.
max_value
+
10
);
axisY
->
setTitleText
(
"Nof Scheduled RBs"
);
chart
->
addAxis
(
axisY
,
Qt
::
AlignLeft
);
chart
->
addSeries
(
this
->
nofRBs
.
series
);
this
->
nofRBs
.
series
->
attachAxis
(
axisX
);
this
->
nofRBs
.
series
->
attachAxis
(
axisY
);
QChartView
*
chartView
=
new
QChartView
(
chart
);
chartView
->
resize
(
this
->
chartWidth
,
this
->
chartHight
);
QPixmap
p
=
chartView
->
grab
();
*
this
->
pix
=
p
;
this
->
previousIndex
=
this
->
parentWindow
->
currentIndex
();
this
->
nofRBs
.
plot_idx
++
;
update
();
}
void
PainterWidgetgNB
::
KPI_DL_Throu
()
{
// erase the previous paint
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
gNB_MAC_INST
*
gNBMac
=
(
gNB_MAC_INST
*
)
RC
.
nrmac
[
0
];
NR_UE_info_t
*
targetUE
=
gNBMac
->
UE_info
.
list
[
0
];
NR_UE_sched_ctrl_t
*
sched_ctrl
=
&
targetUE
->
UE_sched_ctrl
;
uint32_t
blockSize
=
(
uint32_t
)
targetUE
->
mac_stats
.
dl
.
current_bytes
;
float
bler_dl
=
(
float
)
sched_ctrl
->
dl_bler_stats
.
bler
;
NR_DL_FRAME_PARMS
*
frame_parms
=
&
this
->
p
->
gNB
->
frame_parms
;
uint16_t
slots_per_frame
=
frame_parms
->
slots_per_frame
;
float
slotDuration
=
10.0
/
(
float
)
slots_per_frame
;
// slot duration in msec
double
blerTerm
=
1.0
-
(
double
)
bler_dl
;
double
blockSizeBits
=
(
double
)(
blockSize
<<
3
);
double
ThrouputKBitSec
=
blerTerm
*
blockSizeBits
/
(
double
)
slotDuration
;
if
((
this
->
DLThrou
.
plot_idx
>
this
->
chartWidth
)
||
(
this
->
indexToPlot
!=
this
->
previousIndex
))
{
this
->
DLThrou
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
DLThrou
);
}
float
Xpaint
,
Ypaint
;
Xpaint
=
this
->
DLThrou
.
plot_idx
;
Ypaint
=
(
float
)(
ThrouputKBitSec
/
1000
);
// Throughput in MBit/sec
this
->
DLThrou
.
max_value
=
std
::
max
(
this
->
DLThrou
.
max_value
,
Ypaint
);
this
->
DLThrou
.
series
->
append
(
Xpaint
,
Ypaint
);
QLineSeries
*
series_LowLim
=
new
QLineSeries
();
series_LowLim
->
append
(
0
,
Limits_KPI_gNB
[
3
][
0
]);
series_LowLim
->
append
(
this
->
chartWidth
,
Limits_KPI_gNB
[
3
][
0
]);
series_LowLim
->
setColor
(
QColor
(
0
,
255
,
0
));
QLineSeries
*
series_UppLim
=
new
QLineSeries
();
series_UppLim
->
append
(
0
,
Limits_KPI_gNB
[
3
][
1
]);
series_UppLim
->
append
(
this
->
chartWidth
,
Limits_KPI_gNB
[
3
][
1
]);
series_UppLim
->
setColor
(
QColor
(
255
,
0
,
0
));
QChart
*
chart
=
new
QChart
();
chart
->
legend
()
->
hide
();
int
nofTicks
=
6
;
QValueAxis
*
axisX
=
new
QValueAxis
;
axisX
->
setTickCount
(
nofTicks
);
axisX
->
setRange
(
0
,
this
->
chartWidth
);
axisX
->
setTitleText
(
"Time Index"
);
chart
->
addAxis
(
axisX
,
Qt
::
AlignBottom
);
QValueAxis
*
axisY
=
new
QValueAxis
;
axisY
->
setTickCount
(
nofTicks
);
axisY
->
setRange
(
-
1
,
1.2
*
this
->
DLThrou
.
max_value
);
axisY
->
setTitleText
(
"UL Throughput Mbit/sec"
);
chart
->
addAxis
(
axisY
,
Qt
::
AlignLeft
);
chart
->
addSeries
(
this
->
DLThrou
.
series
);
this
->
DLThrou
.
series
->
attachAxis
(
axisX
);
this
->
DLThrou
.
series
->
attachAxis
(
axisY
);
chart
->
addSeries
(
series_LowLim
);
series_LowLim
->
attachAxis
(
axisX
);
series_LowLim
->
attachAxis
(
axisY
);
chart
->
addSeries
(
series_UppLim
);
series_UppLim
->
attachAxis
(
axisX
);
series_UppLim
->
attachAxis
(
axisY
);
QChartView
*
chartView
=
new
QChartView
(
chart
);
chartView
->
resize
(
this
->
chartWidth
,
this
->
chartHight
);
QPixmap
p
=
chartView
->
grab
();
*
this
->
pix
=
p
;
this
->
previousIndex
=
this
->
parentWindow
->
currentIndex
();
this
->
DLThrou
.
plot_idx
++
;
update
();
}
void
PainterWidgetgNB
::
KPI_UL_Throu
()
{
// erase the previous paint
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
gNB_MAC_INST
*
gNBMac
=
(
gNB_MAC_INST
*
)
RC
.
nrmac
[
0
];
NR_UE_info_t
*
targetUE
=
gNBMac
->
UE_info
.
list
[
0
];
NR_UE_sched_ctrl_t
*
sched_ctrl
=
&
targetUE
->
UE_sched_ctrl
;
uint32_t
blockSize
=
(
uint32_t
)
targetUE
->
mac_stats
.
ul
.
current_bytes
;
float
bler_ul
=
(
float
)
sched_ctrl
->
ul_bler_stats
.
bler
;
NR_DL_FRAME_PARMS
*
frame_parms
=
&
this
->
p
->
gNB
->
frame_parms
;
uint16_t
slots_per_frame
=
frame_parms
->
slots_per_frame
;
float
slotDuration
=
10.0
/
(
float
)
slots_per_frame
;
// slot duration in msec
double
blerTerm
=
1.0
-
(
double
)
bler_ul
;
double
blockSizeBits
=
(
double
)(
blockSize
<<
3
);
double
ThrouputKBitSec
=
blerTerm
*
blockSizeBits
/
(
double
)
slotDuration
;
if
((
this
->
ULThrou
.
plot_idx
>
this
->
chartWidth
)
||
(
this
->
indexToPlot
!=
this
->
previousIndex
))
{
this
->
ULThrou
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
ULThrou
);
}
float
Xpaint
,
Ypaint
;
Xpaint
=
this
->
ULThrou
.
plot_idx
;
Ypaint
=
(
float
)(
ThrouputKBitSec
/
1000
);
// Throughput in MBit/sec
this
->
ULThrou
.
max_value
=
std
::
max
(
this
->
ULThrou
.
max_value
,
Ypaint
);
this
->
ULThrou
.
series
->
append
(
Xpaint
,
Ypaint
);
QLineSeries
*
series_LowLim
=
new
QLineSeries
();
series_LowLim
->
append
(
0
,
Limits_KPI_gNB
[
1
][
0
]);
series_LowLim
->
append
(
this
->
chartWidth
,
Limits_KPI_gNB
[
1
][
0
]);
series_LowLim
->
setColor
(
QColor
(
0
,
255
,
0
));
QLineSeries
*
series_UppLim
=
new
QLineSeries
();
series_UppLim
->
append
(
0
,
Limits_KPI_gNB
[
1
][
1
]);
series_UppLim
->
append
(
this
->
chartWidth
,
Limits_KPI_gNB
[
1
][
1
]);
series_UppLim
->
setColor
(
QColor
(
255
,
0
,
0
));
QChart
*
chart
=
new
QChart
();
chart
->
legend
()
->
hide
();
int
nofTicks
=
6
;
QValueAxis
*
axisX
=
new
QValueAxis
;
axisX
->
setTickCount
(
nofTicks
);
axisX
->
setRange
(
0
,
this
->
chartWidth
);
axisX
->
setTitleText
(
"Time Index"
);
chart
->
addAxis
(
axisX
,
Qt
::
AlignBottom
);
QValueAxis
*
axisY
=
new
QValueAxis
;
axisY
->
setTickCount
(
nofTicks
);
axisY
->
setRange
(
-
1
,
1.2
*
this
->
ULThrou
.
max_value
);
axisY
->
setTitleText
(
"UL Throughput Mbit/sec"
);
chart
->
addAxis
(
axisY
,
Qt
::
AlignLeft
);
chart
->
addSeries
(
this
->
ULThrou
.
series
);
this
->
ULThrou
.
series
->
attachAxis
(
axisX
);
this
->
ULThrou
.
series
->
attachAxis
(
axisY
);
chart
->
addSeries
(
series_LowLim
);
series_LowLim
->
attachAxis
(
axisX
);
series_LowLim
->
attachAxis
(
axisY
);
chart
->
addSeries
(
series_UppLim
);
series_UppLim
->
attachAxis
(
axisX
);
series_UppLim
->
attachAxis
(
axisY
);
QChartView
*
chartView
=
new
QChartView
(
chart
);
chartView
->
resize
(
this
->
chartWidth
,
this
->
chartHight
);
QPixmap
p
=
chartView
->
grab
();
*
this
->
pix
=
p
;
this
->
previousIndex
=
this
->
parentWindow
->
currentIndex
();
this
->
ULThrou
.
plot_idx
++
;
update
();
}
void
PainterWidgetgNB
::
KPI_DL_MCS
()
{
// erase the previous paint
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
gNB_MAC_INST
*
gNBMac
=
(
gNB_MAC_INST
*
)
RC
.
nrmac
[
0
];
NR_UE_info_t
*
targetUE
=
gNBMac
->
UE_info
.
list
[
0
];
NR_UE_sched_ctrl_t
*
sched_ctrl
=
&
targetUE
->
UE_sched_ctrl
;
if
((
this
->
DLMCS
.
plot_idx
>
this
->
chartWidth
)
||
(
this
->
indexToPlot
!=
this
->
previousIndex
))
{
this
->
DLMCS
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
DLMCS
);
if
(
this
->
indexToPlot
!=
this
->
previousIndex
)
resetKPIValues
(
&
this
->
DLMCS
);
}
float
Xpaint
,
Ypaint
;
Xpaint
=
this
->
DLMCS
.
plot_idx
;
Ypaint
=
(
float
)
sched_ctrl
->
dl_bler_stats
.
mcs
;
this
->
DLMCS
.
max_value
=
std
::
max
(
this
->
DLMCS
.
max_value
,
Ypaint
);
this
->
DLMCS
.
min_value
=
std
::
min
(
this
->
DLMCS
.
min_value
,
Ypaint
);
this
->
DLMCS
.
series
->
append
(
Xpaint
,
Ypaint
);
this
->
DLMCS
.
seriesMin
->
append
(
Xpaint
,
this
->
DLMCS
.
min_value
);
this
->
DLMCS
.
seriesMax
->
append
(
Xpaint
,
this
->
DLMCS
.
max_value
);
QChart
*
chart
=
new
QChart
();
chart
->
legend
()
->
show
();
int
nofTicks
=
6
;
QValueAxis
*
axisX
=
new
QValueAxis
;
axisX
->
setTickCount
(
nofTicks
);
axisX
->
setRange
(
0
,
this
->
chartWidth
);
axisX
->
setTitleText
(
"Time Index"
);
chart
->
addAxis
(
axisX
,
Qt
::
AlignBottom
);
QValueAxis
*
axisY
=
new
QValueAxis
;
axisY
->
setTickCount
(
nofTicks
);
axisY
->
setRange
(
-
1
,
this
->
DLMCS
.
max_value
+
2.0
);
axisY
->
setTitleText
(
"DL MCS"
);
chart
->
addAxis
(
axisY
,
Qt
::
AlignLeft
);
chart
->
addSeries
(
this
->
DLMCS
.
series
);
this
->
DLMCS
.
series
->
attachAxis
(
axisX
);
this
->
DLMCS
.
series
->
attachAxis
(
axisY
);
chart
->
addSeries
(
this
->
DLMCS
.
seriesMin
);
this
->
DLMCS
.
seriesMin
->
attachAxis
(
axisX
);
this
->
DLMCS
.
seriesMin
->
attachAxis
(
axisY
);
chart
->
addSeries
(
this
->
DLMCS
.
seriesMax
);
this
->
DLMCS
.
seriesMax
->
attachAxis
(
axisX
);
this
->
DLMCS
.
seriesMax
->
attachAxis
(
axisY
);
QChartView
*
chartView
=
new
QChartView
(
chart
);
chartView
->
resize
(
this
->
chartWidth
,
this
->
chartHight
);
QPixmap
p
=
chartView
->
grab
();
*
this
->
pix
=
p
;
this
->
previousIndex
=
this
->
parentWindow
->
currentIndex
();
this
->
DLMCS
.
plot_idx
++
;
update
();
}
void
PainterWidgetgNB
::
KPI_DL_BLER
()
{
// erase the previous paint
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
gNB_MAC_INST
*
gNBMac
=
(
gNB_MAC_INST
*
)
RC
.
nrmac
[
0
];
NR_UE_info_t
*
targetUE
=
gNBMac
->
UE_info
.
list
[
0
];
NR_UE_sched_ctrl_t
*
sched_ctrl
=
&
targetUE
->
UE_sched_ctrl
;
if
((
this
->
DLBLER
.
plot_idx
>
this
->
chartWidth
)
||
(
this
->
indexToPlot
!=
this
->
previousIndex
))
{
this
->
DLBLER
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
DLBLER
);
}
float
Xpaint
,
Ypaint
;
Xpaint
=
this
->
DLBLER
.
plot_idx
;
Ypaint
=
(
float
)
sched_ctrl
->
dl_bler_stats
.
bler
;
this
->
DLBLER
.
series
->
append
(
Xpaint
,
Ypaint
);
QLineSeries
*
series_LowLim
=
new
QLineSeries
();
series_LowLim
->
append
(
0
,
Limits_KPI_gNB
[
2
][
0
]);
series_LowLim
->
append
(
this
->
chartWidth
,
Limits_KPI_gNB
[
2
][
0
]);
series_LowLim
->
setColor
(
QColor
(
0
,
255
,
0
));
QLineSeries
*
series_UppLim
=
new
QLineSeries
();
series_UppLim
->
append
(
0
,
Limits_KPI_gNB
[
2
][
1
]);
series_UppLim
->
append
(
this
->
chartWidth
,
Limits_KPI_gNB
[
2
][
1
]);
series_UppLim
->
setColor
(
QColor
(
255
,
0
,
0
));
QChart
*
chart
=
new
QChart
();
chart
->
legend
()
->
hide
();
int
nofTicks
=
6
;
QValueAxis
*
axisX
=
new
QValueAxis
;
axisX
->
setTickCount
(
nofTicks
);
axisX
->
setRange
(
0
,
this
->
chartWidth
);
axisX
->
setTitleText
(
"Time Index (calc window: 100 ms)"
);
chart
->
addAxis
(
axisX
,
Qt
::
AlignBottom
);
QValueAxis
*
axisY
=
new
QValueAxis
;
axisY
->
setTickCount
(
nofTicks
);
axisY
->
setRange
(
-
1
,
1.5
);
axisY
->
setTitleText
(
"DL BLER"
);
chart
->
addAxis
(
axisY
,
Qt
::
AlignLeft
);
chart
->
addSeries
(
this
->
DLBLER
.
series
);
this
->
DLBLER
.
series
->
attachAxis
(
axisX
);
this
->
DLBLER
.
series
->
attachAxis
(
axisY
);
chart
->
addSeries
(
series_LowLim
);
series_LowLim
->
attachAxis
(
axisX
);
series_LowLim
->
attachAxis
(
axisY
);
chart
->
addSeries
(
series_UppLim
);
series_UppLim
->
attachAxis
(
axisX
);
series_UppLim
->
attachAxis
(
axisY
);
QChartView
*
chartView
=
new
QChartView
(
chart
);
chartView
->
resize
(
this
->
chartWidth
,
this
->
chartHight
);
QPixmap
p
=
chartView
->
grab
();
*
this
->
pix
=
p
;
this
->
previousIndex
=
this
->
parentWindow
->
currentIndex
();
this
->
DLBLER
.
plot_idx
++
;
update
();
}
void
PainterWidgetgNB
::
KPI_UL_BLER
()
{
// erase the previous paint
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
gNB_MAC_INST
*
gNBMac
=
(
gNB_MAC_INST
*
)
RC
.
nrmac
[
0
];
NR_UE_info_t
*
targetUE
=
gNBMac
->
UE_info
.
list
[
0
];
NR_UE_sched_ctrl_t
*
sched_ctrl
=
&
targetUE
->
UE_sched_ctrl
;
if
((
this
->
ULBLER
.
plot_idx
>
this
->
chartWidth
)
||
(
this
->
indexToPlot
!=
this
->
previousIndex
))
{
this
->
ULBLER
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
ULBLER
);
}
float
Xpaint
,
Ypaint
;
Xpaint
=
this
->
ULBLER
.
plot_idx
;
Ypaint
=
(
float
)
sched_ctrl
->
ul_bler_stats
.
bler
;
this
->
ULBLER
.
series
->
append
(
Xpaint
,
Ypaint
);
QLineSeries
*
series_LowLim
=
new
QLineSeries
();
series_LowLim
->
append
(
0
,
Limits_KPI_gNB
[
0
][
0
]);
series_LowLim
->
append
(
this
->
chartWidth
,
Limits_KPI_gNB
[
0
][
0
]);
series_LowLim
->
setColor
(
QColor
(
0
,
255
,
0
));
QLineSeries
*
series_UppLim
=
new
QLineSeries
();
series_UppLim
->
append
(
0
,
Limits_KPI_gNB
[
0
][
1
]);
series_UppLim
->
append
(
this
->
chartWidth
,
Limits_KPI_gNB
[
0
][
1
]);
series_UppLim
->
setColor
(
QColor
(
255
,
0
,
0
));
QChart
*
chart
=
new
QChart
();
chart
->
legend
()
->
hide
();
int
nofTicks
=
6
;
QValueAxis
*
axisX
=
new
QValueAxis
;
axisX
->
setTickCount
(
nofTicks
);
axisX
->
setRange
(
0
,
this
->
chartWidth
);
axisX
->
setTitleText
(
"Time Index (calc window: 100 ms)"
);
chart
->
addAxis
(
axisX
,
Qt
::
AlignBottom
);
QValueAxis
*
axisY
=
new
QValueAxis
;
axisY
->
setTickCount
(
nofTicks
);
axisY
->
setRange
(
-
1
,
1.5
);
axisY
->
setTitleText
(
"UL BLER"
);
chart
->
addAxis
(
axisY
,
Qt
::
AlignLeft
);
chart
->
addSeries
(
this
->
ULBLER
.
series
);
this
->
ULBLER
.
series
->
attachAxis
(
axisX
);
this
->
ULBLER
.
series
->
attachAxis
(
axisY
);
chart
->
addSeries
(
series_LowLim
);
series_LowLim
->
attachAxis
(
axisX
);
series_LowLim
->
attachAxis
(
axisY
);
chart
->
addSeries
(
series_UppLim
);
series_UppLim
->
attachAxis
(
axisX
);
series_UppLim
->
attachAxis
(
axisY
);
QChartView
*
chartView
=
new
QChartView
(
chart
);
chartView
->
resize
(
this
->
chartWidth
,
this
->
chartHight
);
QPixmap
p
=
chartView
->
grab
();
*
this
->
pix
=
p
;
this
->
previousIndex
=
this
->
parentWindow
->
currentIndex
();
this
->
ULBLER
.
plot_idx
++
;
update
();
}
void
PainterWidgetgNB
::
KPI_UL_MCS
()
{
// erase the previous paint
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
gNB_MAC_INST
*
gNBMac
=
(
gNB_MAC_INST
*
)
RC
.
nrmac
[
0
];
NR_UE_info_t
*
targetUE
=
gNBMac
->
UE_info
.
list
[
0
];
NR_UE_sched_ctrl_t
*
sched_ctrl
=
&
targetUE
->
UE_sched_ctrl
;
if
((
this
->
ULMCS
.
plot_idx
>
this
->
chartWidth
)
||
(
this
->
indexToPlot
!=
this
->
previousIndex
))
{
this
->
ULMCS
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
ULMCS
);
if
(
this
->
indexToPlot
!=
this
->
previousIndex
)
resetKPIValues
(
&
this
->
ULMCS
);
}
float
Xpaint
,
Ypaint
;
Xpaint
=
this
->
ULMCS
.
plot_idx
;
Ypaint
=
(
float
)
sched_ctrl
->
ul_bler_stats
.
mcs
;
this
->
ULMCS
.
max_value
=
std
::
max
(
this
->
ULMCS
.
max_value
,
Ypaint
);
this
->
ULMCS
.
min_value
=
std
::
min
(
this
->
ULMCS
.
min_value
,
Ypaint
);
this
->
ULMCS
.
series
->
append
(
Xpaint
,
Ypaint
);
this
->
ULMCS
.
seriesMin
->
append
(
Xpaint
,
this
->
ULMCS
.
min_value
);
this
->
ULMCS
.
seriesMax
->
append
(
Xpaint
,
this
->
ULMCS
.
max_value
);
QChart
*
chart
=
new
QChart
();
chart
->
legend
()
->
show
();
int
nofTicks
=
6
;
QValueAxis
*
axisX
=
new
QValueAxis
;
axisX
->
setTickCount
(
nofTicks
);
axisX
->
setRange
(
0
,
this
->
chartWidth
);
axisX
->
setTitleText
(
"Time Index"
);
chart
->
addAxis
(
axisX
,
Qt
::
AlignBottom
);
QValueAxis
*
axisY
=
new
QValueAxis
;
axisY
->
setTickCount
(
nofTicks
);
axisY
->
setRange
(
-
1
,
this
->
ULMCS
.
max_value
+
2.0
);
axisY
->
setTitleText
(
"UL MCS"
);
chart
->
addAxis
(
axisY
,
Qt
::
AlignLeft
);
chart
->
addSeries
(
this
->
ULMCS
.
series
);
this
->
ULMCS
.
series
->
attachAxis
(
axisX
);
this
->
ULMCS
.
series
->
attachAxis
(
axisY
);
chart
->
addSeries
(
this
->
ULMCS
.
seriesMin
);
this
->
ULMCS
.
seriesMin
->
attachAxis
(
axisX
);
this
->
ULMCS
.
seriesMin
->
attachAxis
(
axisY
);
chart
->
addSeries
(
this
->
ULMCS
.
seriesMax
);
this
->
ULMCS
.
seriesMax
->
attachAxis
(
axisX
);
this
->
ULMCS
.
seriesMax
->
attachAxis
(
axisY
);
QChartView
*
chartView
=
new
QChartView
(
chart
);
chartView
->
resize
(
this
->
chartWidth
,
this
->
chartHight
);
QPixmap
p
=
chartView
->
grab
();
*
this
->
pix
=
p
;
this
->
previousIndex
=
this
->
parentWindow
->
currentIndex
();
this
->
ULMCS
.
plot_idx
++
;
update
();
}
void
PainterWidgetgNB
::
KPI_PuschIQ
()
{
// erase the previous paint
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
//paint the axis and I/Q samples
NR_DL_FRAME_PARMS
*
frame_parms
=&
this
->
p
->
gNB
->
frame_parms
;
int
sz
=
frame_parms
->
N_RB_UL
*
12
*
frame_parms
->
symbols_per_slot
;
int
ue
=
0
;
float
*
I
,
*
Q
;
float
FIinit
[
sz
]
=
{
0
},
FQinit
[
sz
]
=
{
0
};
I
=
FIinit
;
Q
=
FQinit
;
if
((
this
->
p
->
gNB
->
pusch_vars
)
&&
(
this
->
p
->
gNB
->
pusch_vars
[
ue
])
&&
(
this
->
p
->
gNB
->
pusch_vars
[
ue
]
->
rxdataF_comp
)
&&
(
this
->
p
->
gNB
->
pusch_vars
[
ue
]
->
rxdataF_comp
[
0
]))
{
scopeSample_t
*
pusch_comp
=
(
scopeSample_t
*
)
this
->
p
->
gNB
->
pusch_vars
[
ue
]
->
rxdataF_comp
[
0
];
for
(
int
k
=
0
;
k
<
sz
;
k
++
)
{
I
[
k
]
=
pusch_comp
[
k
].
r
;
Q
[
k
]
=
pusch_comp
[
k
].
i
;
}
}
QColor
MarkerColor
(
0
,
255
,
0
);
const
QString
xLabel
=
QString
(
"Real"
);
const
QString
yLabel
=
QString
(
"Img"
);
createPixMap
(
I
,
Q
,
sz
,
MarkerColor
,
xLabel
,
yLabel
,
true
);
update
();
}
void
PainterWidgetgNB
::
KPI_PuschLLR
()
{
// erase the previous paint
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
//paint the axis LLRs
int
coded_bits_per_codeword
=
3
*
8
*
6144
+
12
;
int
sz
=
coded_bits_per_codeword
;
int
ue
=
0
;
float
*
llr
,
*
bit
;
float
llrBuffer
[
sz
]
=
{
0
},
bitBuffer
[
sz
]
=
{
0
};
llr
=
llrBuffer
;
bit
=
bitBuffer
;
if
((
this
->
p
->
gNB
->
pusch_vars
)
&&
(
this
->
p
->
gNB
->
pusch_vars
[
ue
])
&&
(
this
->
p
->
gNB
->
pusch_vars
[
ue
]
->
llr
))
{
int16_t
*
pusch_llr
=
(
int16_t
*
)
p
->
gNB
->
pusch_vars
[
ue
]
->
llr
;
for
(
int
i
=
0
;
i
<
sz
;
i
++
)
{
llr
[
i
]
=
(
float
)
pusch_llr
[
i
];
bit
[
i
]
=
(
float
)
i
;
}
}
QColor
MarkerColor
(
0
,
255
,
0
);
const
QString
xLabel
=
QString
(
"Sample Index"
);
const
QString
yLabel
=
QString
(
"LLR"
);
createPixMap
(
bit
,
llr
,
sz
,
MarkerColor
,
xLabel
,
yLabel
,
false
);
update
();
}
void
PainterWidgetgNB
::
KPI_ChannelResponse
()
{
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
const
int
len
=
2
*
this
->
p
->
gNB
->
frame_parms
.
ofdm_symbol_size
;
float
*
values
,
*
time
;
float
valuesBuffer
[
len
]
=
{
0
},
timeBuffer
[
len
]
=
{
0
};
values
=
valuesBuffer
;
time
=
timeBuffer
;
const
int
ant
=
0
;
int
ue
=
0
;
if
((
this
->
p
->
gNB
->
pusch_vars
&&
p
->
gNB
->
pusch_vars
[
ue
])
&&
(
this
->
p
->
gNB
->
pusch_vars
[
ue
]
->
ul_ch_estimates_time
)
&&
(
this
->
p
->
gNB
->
pusch_vars
[
ue
]
->
ul_ch_estimates_time
[
ant
]))
{
scopeSample_t
*
data
=
(
scopeSample_t
*
)
this
->
p
->
gNB
->
pusch_vars
[
ue
]
->
ul_ch_estimates_time
[
ant
];
if
(
data
!=
NULL
)
{
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
values
[
i
]
=
SquaredNorm
(
data
[
i
]);
time
[
i
]
=
(
float
)
i
;
}
}
}
float
maxY
=
0
,
minY
=
0
;
for
(
int
k
=
0
;
k
<
len
;
k
++
)
{
maxY
=
std
::
max
(
maxY
,
values
[
k
]);
minY
=
std
::
min
(
minY
,
values
[
k
]);
}
float
maxYAbs
=
std
::
max
(
abs
(
maxY
),
abs
(
minY
));
QLineSeries
*
series
=
new
QLineSeries
();
QColor
MarkerColor
(
255
,
0
,
0
);
series
->
setColor
(
MarkerColor
);
float
Xpaint
,
Ypaint
;
float
minYScaled
=
0
,
maxYScaled
=
0
;
for
(
int
k
=
0
;
k
<
len
;
k
++
)
{
Xpaint
=
time
[
k
];
Ypaint
=
values
[
k
]
/
maxYAbs
*
50
;
series
->
append
(
Xpaint
,
Ypaint
);
maxYScaled
=
std
::
max
(
maxYScaled
,
Ypaint
);
minYScaled
=
std
::
min
(
minYScaled
,
Ypaint
);
}
QChart
*
chart
=
new
QChart
();
chart
->
legend
()
->
hide
();
int
nofTicks
=
6
;
QValueAxis
*
axisX
=
new
QValueAxis
;
axisX
->
setTickCount
(
nofTicks
);
axisX
->
setRange
(
0
,
len
);
axisX
->
setTitleText
(
"Time Index"
);
chart
->
addAxis
(
axisX
,
Qt
::
AlignBottom
);
QValueAxis
*
axisY
=
new
QValueAxis
;
axisY
->
setTickCount
(
nofTicks
);
axisY
->
setRange
((
minYScaled
+
0.4
*
minYScaled
),
(
maxYScaled
+
0.4
*
maxYScaled
));
axisY
->
setTitleText
(
"abs Channel"
);
chart
->
addAxis
(
axisY
,
Qt
::
AlignLeft
);
chart
->
addSeries
(
series
);
series
->
attachAxis
(
axisX
);
series
->
attachAxis
(
axisY
);
QChartView
*
chartView
=
new
QChartView
(
chart
);
chartView
->
resize
(
this
->
chartWidth
,
this
->
chartHight
);
QPixmap
p
=
chartView
->
grab
();
*
this
->
pix
=
p
;
update
();
}
void
PainterWidgetgNB
::
createPixMap
(
float
*
xData
,
float
*
yData
,
int
len
,
QColor
MarkerColor
,
const
QString
xLabel
,
const
QString
yLabel
,
bool
scaleX
)
{
float
maxX
=
0
,
maxY
=
0
,
minX
=
0
,
minY
=
0
;
for
(
int
k
=
0
;
k
<
len
;
k
++
)
{
maxX
=
std
::
max
(
maxX
,
xData
[
k
]);
minX
=
std
::
min
(
minX
,
xData
[
k
]);
maxY
=
std
::
max
(
maxY
,
yData
[
k
]);
minY
=
std
::
min
(
minY
,
yData
[
k
]);
}
float
maxYAbs
=
std
::
max
(
abs
(
maxY
),
abs
(
minY
));
float
maxXAbs
=
std
::
max
(
abs
(
maxX
),
abs
(
minX
));
QScatterSeries
*
series
=
new
QScatterSeries
();
series
->
setUseOpenGL
(
true
);
series
->
setColor
(
MarkerColor
);
series
->
setMarkerSize
(
2
);
series
->
setBorderColor
(
Qt
::
transparent
);
series
->
setMarkerShape
(
QScatterSeries
::
MarkerShapeCircle
);
float
Xpaint
,
Ypaint
;
QVector
<
QPointF
>
points
(
len
);
float
minYScaled
=
0
,
maxYScaled
=
0
,
maxXScaled
=
0
,
minXScaled
=
0
;
for
(
int
k
=
0
;
k
<
len
;
k
++
)
{
if
(
maxYAbs
!=
0
)
Ypaint
=
yData
[
k
]
/
maxYAbs
*
50
;
else
Ypaint
=
yData
[
k
];
if
((
maxXAbs
!=
0
)
&&
(
scaleX
))
Xpaint
=
xData
[
k
]
/
maxXAbs
*
50
;
else
Xpaint
=
xData
[
k
];
points
[
k
]
=
QPointF
(
Xpaint
,
Ypaint
);
//series->append(Xpaint, Ypaint);
maxYScaled
=
std
::
max
(
maxYScaled
,
Ypaint
);
minYScaled
=
std
::
min
(
minYScaled
,
Ypaint
);
maxXScaled
=
std
::
max
(
maxXScaled
,
Xpaint
);
minXScaled
=
std
::
min
(
minXScaled
,
Xpaint
);
}
series
->
replace
(
points
);
QChart
*
chart
=
new
QChart
();
chart
->
legend
()
->
hide
();
int
nofTicks
=
6
;
QValueAxis
*
axisX
=
new
QValueAxis
;
axisX
->
setTickCount
(
nofTicks
);
if
(
!
scaleX
)
axisX
->
setRange
(
0
,
len
);
else
{
if
((
minXScaled
!=
0
)
&&
(
maxXScaled
!=
0
))
axisX
->
setRange
((
minXScaled
+
0.4
*
minXScaled
)
,
(
maxXScaled
+
0.4
*
maxXScaled
));
else
axisX
->
setRange
(
-
10
,
10
);
}
axisX
->
setTitleText
(
xLabel
);
chart
->
addAxis
(
axisX
,
Qt
::
AlignBottom
);
QValueAxis
*
axisY
=
new
QValueAxis
;
axisY
->
setTickCount
(
nofTicks
);
if
((
minYScaled
!=
0
)
&&
(
maxYScaled
!=
0
))
axisY
->
setRange
((
minYScaled
+
0.4
*
minYScaled
),
(
maxYScaled
+
0.4
*
maxYScaled
));
else
axisY
->
setRange
(
-
10
,
10
);
axisY
->
setTitleText
(
yLabel
);
chart
->
addAxis
(
axisY
,
Qt
::
AlignLeft
);
chart
->
addSeries
(
series
);
series
->
attachAxis
(
axisX
);
series
->
attachAxis
(
axisY
);
QChartView
*
chartView
=
new
QChartView
();
chartView
->
resize
(
this
->
chartWidth
,
this
->
chartHight
);
chartView
->
setChart
(
chart
);
QPixmap
pixFromChart
=
chartView
->
grab
();
*
this
->
pix
=
pixFromChart
;
}
void
PainterWidget
::
paintPixmap_ueWaterFallTime
()
{
QPainter
PixPainter
(
this
->
pix
);
PixPainter
.
translate
(
0
,
this
->
pix
->
height
()
/
2
);
scopeSample_t
*
values
=
(
scopeSample_t
*
)
this
->
ue
->
common_vars
.
rxdata
[
0
];
const
int
datasize
=
this
->
ue
->
frame_parms
.
samples_per_frame
;
if
(
values
==
NULL
)
return
;
this
->
waterFallh
=
this
->
chartHight
/
3
-
15
;
const
int
samplesPerPixel
=
datasize
/
this
->
chartWidth
;
int
displayPart
=
this
->
waterFallh
-
ScaleZone
;
int
row
=
this
->
iteration
%
displayPart
;
double
avg
=
0
;
for
(
int
i
=
0
;
i
<
displayPart
;
i
++
)
avg
+=
this
->
waterFallAvg
[
i
];
avg
/=
displayPart
;
this
->
waterFallAvg
[
row
]
=
0
;
for
(
int
pix
=
0
;
pix
<
this
->
chartWidth
;
pix
++
)
{
scopeSample_t
*
end
=
values
+
(
pix
+
1
)
*
samplesPerPixel
;
end
-=
2
;
double
val
=
0
;
for
(
scopeSample_t
*
s
=
values
+
(
pix
)
*
samplesPerPixel
;
s
<
end
;
s
++
)
val
+=
SquaredNorm
(
*
s
);
val
/=
samplesPerPixel
;
this
->
waterFallAvg
[
row
]
+=
val
/
this
->
chartWidth
;
if
(
val
>
avg
*
2
)
{
QColor
IQColor
(
0
,
0
,
255
);
PixPainter
.
setPen
(
IQColor
);
}
if
(
val
>
avg
*
10
){
QColor
IQColor
(
0
,
255
,
0
);
PixPainter
.
setPen
(
IQColor
);
}
if
(
val
>
avg
*
100
){
QColor
IQColor
(
255
,
255
,
0
);
PixPainter
.
setPen
(
IQColor
);
}
PixPainter
.
drawEllipse
(
QPoint
(
pix
,
this
->
iteration
%
displayPart
),
2
,
2
);
}
this
->
iteration
++
;
repaint
();
}
void
PainterWidget
::
resetKPIPlot
(
KPI_elements
*
inputStruct
)
{
inputStruct
->
series
=
new
QLineSeries
();
inputStruct
->
series
->
setColor
(
QColor
(
0
,
0
,
0
));
inputStruct
->
seriesMin
=
new
QLineSeries
();
inputStruct
->
seriesMin
->
setColor
(
QColor
(
255
,
0
,
0
));
inputStruct
->
seriesMin
->
setName
(
"Min."
);
inputStruct
->
seriesMax
=
new
QLineSeries
();
inputStruct
->
seriesMax
->
setColor
(
QColor
(
0
,
255
,
0
));
inputStruct
->
seriesMax
->
setName
(
"Max."
);
inputStruct
->
seriesAvg
=
new
QLineSeries
();
inputStruct
->
seriesAvg
->
setColor
(
QColor
(
0
,
0
,
255
));
inputStruct
->
seriesAvg
->
setName
(
"Avg."
);
}
void
PainterWidget
::
resetKPIValues
(
KPI_elements
*
inputStruct
)
{
inputStruct
->
max_value
=
0.0
;
inputStruct
->
min_value
=
0.0
;
inputStruct
->
avg_value
=
0.0
;
inputStruct
->
avg_idx
=
0
;
inputStruct
->
nof_retrans
=
0
;
}
PainterWidget
::
PainterWidget
(
QComboBox
*
parent
,
PHY_VARS_NR_UE
*
ue
)
{
timer
=
new
QTimer
(
this
);
timerWaterFallTime
=
new
QTimer
(
this
);
this
->
chartHight
=
300
;
this
->
chartWidth
=
300
;
this
->
pix
=
new
QPixmap
(
this
->
chartWidth
,
this
->
chartHight
);
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
this
->
ue
=
ue
;
this
->
parentWindow
=
parent
;
// settings for waterfall graph
this
->
iteration
=
0
;
this
->
waterFallh
=
this
->
chartHight
/
3
-
15
;
this
->
waterFallAvg
=
(
double
*
)
malloc
(
sizeof
(
*
this
->
waterFallAvg
)
*
this
->
waterFallh
);
this
->
isWaterFallTimeActive
=
false
;
for
(
int
i
=
0
;
i
<
this
->
waterFallh
;
i
++
)
this
->
waterFallAvg
[
i
]
=
0
;
this
->
previousIndex
=
this
->
parentWindow
->
currentIndex
();
this
->
indexToPlot
=
this
->
parentWindow
->
currentIndex
();
this
->
extendKPIUE
.
DL_BLER
=
-
1
;
this
->
extendKPIUE
.
blockSize
=
0
;
this
->
extendKPIUE
.
dl_mcs
=
100
;
this
->
extendKPIUE
.
nofRBs
=
34
;
// DL BLER
this
->
DLBLER
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
DLBLER
);
// DL MCS
this
->
DLMCS
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
DLMCS
);
resetKPIValues
(
&
this
->
DLMCS
);
// Throughput
this
->
Throu
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
Throu
);
resetKPIValues
(
&
this
->
Throu
);
// nof scheduled RBs
this
->
nofRBs
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
nofRBs
);
resetKPIValues
(
&
this
->
nofRBs
);
makeConnections
();
}
void
PainterWidget
::
paintEvent
(
QPaintEvent
*
)
{
QPainter
painter
(
this
);
painter
.
drawPixmap
(
(
this
->
width
()
-
this
->
pix
->
width
())
/
2
,
(
this
->
height
()
-
this
->
pix
->
height
())
/
2
,
*
this
->
pix
);
// paint pixmap on widget
this
->
indexToPlot
=
this
->
parentWindow
->
currentIndex
();
makeConnections
();
this
->
previousIndex
=
this
->
parentWindow
->
currentIndex
();
}
void
PainterWidget
::
makeConnections
()
{
getKPIUE
(
&
this
->
extendKPIUE
);
disconnect
(
timer
,
nullptr
,
nullptr
,
nullptr
);
disconnect
(
timerWaterFallTime
,
nullptr
,
nullptr
,
nullptr
);
if
((
this
->
indexToPlot
!=
this
->
previousIndex
)
&&
(
this
->
indexToPlot
==
6
))
// reset settings
{
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
this
->
iteration
=
0
;
for
(
int
i
=
0
;
i
<
this
->
waterFallh
;
i
++
)
this
->
waterFallAvg
[
i
]
=
0
;
}
if
(
this
->
indexToPlot
==
2
)
{
if
(
this
->
isWaterFallTimeActive
)
this
->
iteration
++
;
connect
(
timer
,
&
QTimer
::
timeout
,
this
,
&
PainterWidget
::
paintPixmap_uePdschIQ
);
// paintPixmap_uePdschIQ
}
else
if
(
this
->
indexToPlot
==
0
)
{
if
(
this
->
isWaterFallTimeActive
)
this
->
iteration
++
;
connect
(
timer
,
&
QTimer
::
timeout
,
this
,
&
PainterWidget
::
paintPixmap_uePbchIQ
);
// paintPixmap_uePbchIQ
}
else
if
(
this
->
indexToPlot
==
4
)
{
if
(
this
->
isWaterFallTimeActive
)
this
->
iteration
++
;
connect
(
timer
,
&
QTimer
::
timeout
,
this
,
&
PainterWidget
::
paintPixmap_uePdcchIQ
);
}
else
if
(
this
->
indexToPlot
==
3
)
{
if
(
this
->
isWaterFallTimeActive
)
this
->
iteration
++
;
connect
(
timer
,
&
QTimer
::
timeout
,
this
,
&
PainterWidget
::
paintPixmap_uePdschLLR
);
// paintPixmap_uePdschLLR
}
else
if
(
this
->
indexToPlot
==
1
)
{
if
(
this
->
isWaterFallTimeActive
)
this
->
iteration
++
;
connect
(
timer
,
&
QTimer
::
timeout
,
this
,
&
PainterWidget
::
paintPixmap_uePbchLLR
);
// paintPixmap_uePbchLLR
}
else
if
(
this
->
indexToPlot
==
5
)
{
if
(
this
->
isWaterFallTimeActive
)
this
->
iteration
++
;
connect
(
timer
,
&
QTimer
::
timeout
,
this
,
&
PainterWidget
::
paintPixmap_uePdcchLLR
);
}
else
if
(
this
->
indexToPlot
==
6
)
{
this
->
isWaterFallTimeActive
=
true
;
connect
(
timerWaterFallTime
,
&
QTimer
::
timeout
,
this
,
&
PainterWidget
::
paintPixmap_ueWaterFallTime
);
// water fall time domain
}
else
if
(
this
->
indexToPlot
==
7
)
{
if
(
this
->
isWaterFallTimeActive
)
this
->
iteration
++
;
connect
(
timer
,
&
QTimer
::
timeout
,
this
,
&
PainterWidget
::
paintPixmap_ueChannelResponse
);
// Channel Response
}
else
if
(
this
->
indexToPlot
==
8
)
{
connect
(
timer
,
&
QTimer
::
timeout
,
this
,
&
PainterWidget
::
KPI_DL_BLER
);
}
else
if
(
this
->
indexToPlot
==
9
)
{
connect
(
timer
,
&
QTimer
::
timeout
,
this
,
&
PainterWidget
::
KPI_DL_Throu
);
}
else
if
(
this
->
indexToPlot
==
10
)
{
connect
(
timer
,
&
QTimer
::
timeout
,
this
,
&
PainterWidget
::
KPI_DL_MCS
);
}
else
if
(
this
->
indexToPlot
==
11
)
{
connect
(
timer
,
&
QTimer
::
timeout
,
this
,
&
PainterWidget
::
KPI_Nof_RBs
);
}
timer
->
start
(
200
);
timerWaterFallTime
->
start
(
10
);
}
void
PainterWidget
::
KPI_Nof_RBs
()
{
// erase the previous paint
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
if
((
this
->
nofRBs
.
plot_idx
>
this
->
chartWidth
)
||
(
this
->
indexToPlot
!=
this
->
previousIndex
))
{
this
->
nofRBs
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
nofRBs
);
}
float
Xpaint
,
Ypaint
;
Xpaint
=
this
->
nofRBs
.
plot_idx
;
Ypaint
=
(
float
)
this
->
extendKPIUE
.
nofRBs
;
this
->
nofRBs
.
max_value
=
std
::
max
(
this
->
nofRBs
.
max_value
,
Ypaint
);
this
->
nofRBs
.
series
->
append
(
Xpaint
,
Ypaint
);
QChart
*
chart
=
new
QChart
();
chart
->
legend
()
->
hide
();
int
nofTicks
=
6
;
QValueAxis
*
axisX
=
new
QValueAxis
;
axisX
->
setTickCount
(
nofTicks
);
axisX
->
setRange
(
0
,
this
->
chartWidth
);
axisX
->
setTitleText
(
"Time Index"
);
chart
->
addAxis
(
axisX
,
Qt
::
AlignBottom
);
QValueAxis
*
axisY
=
new
QValueAxis
;
axisY
->
setTickCount
(
nofTicks
);
axisY
->
setRange
(
-
1
,
this
->
nofRBs
.
max_value
+
10
);
axisY
->
setTitleText
(
"Nof Scheduled RBs"
);
chart
->
addAxis
(
axisY
,
Qt
::
AlignLeft
);
chart
->
addSeries
(
this
->
nofRBs
.
series
);
this
->
nofRBs
.
series
->
attachAxis
(
axisX
);
this
->
nofRBs
.
series
->
attachAxis
(
axisY
);
QChartView
*
chartView
=
new
QChartView
(
chart
);
chartView
->
resize
(
this
->
chartWidth
,
this
->
chartHight
);
QPixmap
p
=
chartView
->
grab
();
*
this
->
pix
=
p
;
this
->
previousIndex
=
this
->
parentWindow
->
currentIndex
();
this
->
nofRBs
.
plot_idx
++
;
update
();
}
void
PainterWidget
::
KPI_DL_Throu
()
{
// erase the previous paint
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
uint32_t
blockSize
=
(
uint32_t
)
this
->
extendKPIUE
.
blockSize
;
float
bler_dl
=
this
->
extendKPIUE
.
DL_BLER
;
NR_DL_FRAME_PARMS
*
frame_parms
=
&
this
->
ue
->
frame_parms
;
uint16_t
slots_per_frame
=
frame_parms
->
slots_per_frame
;
float
slotDuration
=
10.0
/
(
float
)
slots_per_frame
;
// slot duration in msec
double
blerTerm
=
1.0
-
(
double
)
bler_dl
;
double
blockSizeBits
=
(
double
)(
blockSize
<<
3
);
double
ThrouputKBitSec
=
blerTerm
*
blockSizeBits
/
(
double
)
slotDuration
;
if
((
this
->
Throu
.
plot_idx
>
this
->
chartWidth
)
||
(
this
->
indexToPlot
!=
this
->
previousIndex
))
{
this
->
Throu
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
Throu
);
}
float
Xpaint
,
Ypaint
;
Xpaint
=
this
->
Throu
.
plot_idx
;
Ypaint
=
(
float
)(
ThrouputKBitSec
/
1000
);
// Throughput in MBit/sec
this
->
Throu
.
max_value
=
std
::
max
(
this
->
Throu
.
max_value
,
Ypaint
);
this
->
Throu
.
series
->
append
(
Xpaint
,
Ypaint
);
QLineSeries
*
series_LowLim
=
new
QLineSeries
();
series_LowLim
->
append
(
0
,
Limits_KPI_gNB
[
1
][
0
]);
series_LowLim
->
append
(
this
->
chartWidth
,
Limits_KPI_gNB
[
1
][
0
]);
series_LowLim
->
setColor
(
QColor
(
0
,
255
,
0
));
QLineSeries
*
series_UppLim
=
new
QLineSeries
();
series_UppLim
->
append
(
0
,
Limits_KPI_gNB
[
1
][
1
]);
series_UppLim
->
append
(
this
->
chartWidth
,
Limits_KPI_gNB
[
1
][
1
]);
series_UppLim
->
setColor
(
QColor
(
255
,
0
,
0
));
QChart
*
chart
=
new
QChart
();
chart
->
legend
()
->
hide
();
int
nofTicks
=
6
;
QValueAxis
*
axisX
=
new
QValueAxis
;
axisX
->
setTickCount
(
nofTicks
);
axisX
->
setRange
(
0
,
this
->
chartWidth
);
axisX
->
setTitleText
(
"Time Index"
);
chart
->
addAxis
(
axisX
,
Qt
::
AlignBottom
);
QValueAxis
*
axisY
=
new
QValueAxis
;
axisY
->
setTickCount
(
nofTicks
);
axisY
->
setRange
(
-
1
,
1.2
*
this
->
Throu
.
max_value
);
axisY
->
setTitleText
(
"UL Throughput Mbit/sec"
);
chart
->
addAxis
(
axisY
,
Qt
::
AlignLeft
);
chart
->
addSeries
(
this
->
Throu
.
series
);
this
->
Throu
.
series
->
attachAxis
(
axisX
);
this
->
Throu
.
series
->
attachAxis
(
axisY
);
chart
->
addSeries
(
series_LowLim
);
series_LowLim
->
attachAxis
(
axisX
);
series_LowLim
->
attachAxis
(
axisY
);
chart
->
addSeries
(
series_UppLim
);
series_UppLim
->
attachAxis
(
axisX
);
series_UppLim
->
attachAxis
(
axisY
);
QChartView
*
chartView
=
new
QChartView
(
chart
);
chartView
->
resize
(
this
->
chartWidth
,
this
->
chartHight
);
QPixmap
p
=
chartView
->
grab
();
*
this
->
pix
=
p
;
this
->
previousIndex
=
this
->
parentWindow
->
currentIndex
();
this
->
Throu
.
plot_idx
++
;
update
();
}
void
PainterWidget
::
KPI_DL_MCS
()
{
// erase the previous paint
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
if
((
this
->
DLMCS
.
plot_idx
>
this
->
chartWidth
)
||
(
this
->
indexToPlot
!=
this
->
previousIndex
))
{
this
->
DLMCS
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
DLMCS
);
if
(
this
->
indexToPlot
!=
this
->
previousIndex
)
resetKPIValues
(
&
this
->
DLMCS
);
}
float
Xpaint
,
Ypaint
;
Xpaint
=
this
->
DLMCS
.
plot_idx
;
Ypaint
=
(
float
)
this
->
extendKPIUE
.
dl_mcs
;
this
->
DLMCS
.
max_value
=
std
::
max
(
this
->
DLMCS
.
max_value
,
Ypaint
);
this
->
DLMCS
.
min_value
=
std
::
min
(
this
->
DLMCS
.
min_value
,
Ypaint
);
this
->
DLMCS
.
series
->
append
(
Xpaint
,
Ypaint
);
this
->
DLMCS
.
seriesMin
->
append
(
Xpaint
,
this
->
DLMCS
.
min_value
);
this
->
DLMCS
.
seriesMax
->
append
(
Xpaint
,
this
->
DLMCS
.
max_value
);
QChart
*
chart
=
new
QChart
();
chart
->
legend
()
->
show
();
int
nofTicks
=
6
;
QValueAxis
*
axisX
=
new
QValueAxis
;
axisX
->
setTickCount
(
nofTicks
);
axisX
->
setRange
(
0
,
this
->
chartWidth
);
axisX
->
setTitleText
(
"Time Index"
);
chart
->
addAxis
(
axisX
,
Qt
::
AlignBottom
);
QValueAxis
*
axisY
=
new
QValueAxis
;
axisY
->
setTickCount
(
nofTicks
);
axisY
->
setRange
(
-
1
,
this
->
DLMCS
.
max_value
+
2.0
);
axisY
->
setTitleText
(
"DL MCS"
);
chart
->
addAxis
(
axisY
,
Qt
::
AlignLeft
);
chart
->
addSeries
(
this
->
DLMCS
.
series
);
this
->
DLMCS
.
series
->
attachAxis
(
axisX
);
this
->
DLMCS
.
series
->
attachAxis
(
axisY
);
chart
->
addSeries
(
this
->
DLMCS
.
seriesMin
);
this
->
DLMCS
.
seriesMin
->
attachAxis
(
axisX
);
this
->
DLMCS
.
seriesMin
->
attachAxis
(
axisY
);
chart
->
addSeries
(
this
->
DLMCS
.
seriesMax
);
this
->
DLMCS
.
seriesMax
->
attachAxis
(
axisX
);
this
->
DLMCS
.
seriesMax
->
attachAxis
(
axisY
);
QChartView
*
chartView
=
new
QChartView
(
chart
);
chartView
->
resize
(
this
->
chartWidth
,
this
->
chartHight
);
QPixmap
p
=
chartView
->
grab
();
*
this
->
pix
=
p
;
this
->
previousIndex
=
this
->
parentWindow
->
currentIndex
();
this
->
DLMCS
.
plot_idx
++
;
update
();
}
void
PainterWidget
::
KPI_DL_BLER
()
{
// erase the previous paint
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
if
((
this
->
DLBLER
.
plot_idx
>
this
->
chartWidth
)
||
(
this
->
indexToPlot
!=
this
->
previousIndex
))
{
this
->
DLBLER
.
plot_idx
=
0
;
resetKPIPlot
(
&
this
->
DLBLER
);
}
float
Xpaint
,
Ypaint
;
Xpaint
=
this
->
DLBLER
.
plot_idx
;
Ypaint
=
this
->
extendKPIUE
.
DL_BLER
;
this
->
DLBLER
.
series
->
append
(
Xpaint
,
Ypaint
);
QLineSeries
*
series_LowLim
=
new
QLineSeries
();
series_LowLim
->
append
(
0
,
Limits_KPI_ue
[
0
][
0
]);
series_LowLim
->
append
(
this
->
chartWidth
,
Limits_KPI_ue
[
0
][
0
]);
series_LowLim
->
setColor
(
QColor
(
0
,
255
,
0
));
QLineSeries
*
series_UppLim
=
new
QLineSeries
();
series_UppLim
->
append
(
0
,
Limits_KPI_ue
[
0
][
1
]);
series_UppLim
->
append
(
this
->
chartWidth
,
Limits_KPI_ue
[
0
][
1
]);
series_UppLim
->
setColor
(
QColor
(
255
,
0
,
0
));
QChart
*
chart
=
new
QChart
();
chart
->
legend
()
->
hide
();
int
nofTicks
=
6
;
QValueAxis
*
axisX
=
new
QValueAxis
;
axisX
->
setTickCount
(
nofTicks
);
axisX
->
setRange
(
0
,
this
->
chartWidth
);
axisX
->
setTitleText
(
"Time Index"
);
chart
->
addAxis
(
axisX
,
Qt
::
AlignBottom
);
QValueAxis
*
axisY
=
new
QValueAxis
;
axisY
->
setTickCount
(
nofTicks
);
axisY
->
setRange
(
-
1
,
1.5
);
axisY
->
setTitleText
(
"DL BLER"
);
chart
->
addAxis
(
axisY
,
Qt
::
AlignLeft
);
chart
->
addSeries
(
this
->
DLBLER
.
series
);
this
->
DLBLER
.
series
->
attachAxis
(
axisX
);
this
->
DLBLER
.
series
->
attachAxis
(
axisY
);
chart
->
addSeries
(
series_LowLim
);
series_LowLim
->
attachAxis
(
axisX
);
series_LowLim
->
attachAxis
(
axisY
);
chart
->
addSeries
(
series_UppLim
);
series_UppLim
->
attachAxis
(
axisX
);
series_UppLim
->
attachAxis
(
axisY
);
QChartView
*
chartView
=
new
QChartView
(
chart
);
chartView
->
resize
(
this
->
chartWidth
,
this
->
chartHight
);
QPixmap
p
=
chartView
->
grab
();
*
this
->
pix
=
p
;
this
->
previousIndex
=
this
->
parentWindow
->
currentIndex
();
this
->
DLBLER
.
plot_idx
++
;
update
();
}
void
PainterWidget
::
paintPixmap_ueChannelResponse
()
{
scopeData_t
*
scope
=
(
scopeData_t
*
)
this
->
ue
->
scopeData
;
scope
->
flag_streaming
[
pbchDlChEstimateTime
]
=
1
;
scopeGraphData_t
**
UELiveData
=
(
scopeGraphData_t
**
)((
scopeData_t
*
)
this
->
ue
->
scopeData
)
->
liveDataUE
;
if
(
!
UELiveData
[
pbchDlChEstimateTime
])
return
;
const
scopeSample_t
*
tmp
=
(
scopeSample_t
*
)(
UELiveData
[
pbchDlChEstimateTime
]
+
1
);
const
scopeSample_t
**
data
=&
tmp
;
const
int
len
=
UELiveData
[
pbchDlChEstimateTime
]
->
lineSz
;
float
*
values
,
*
time
;
float
valuesBuffer
[
len
]
=
{
0
},
timeBuffer
[
len
]
=
{
0
};
values
=
valuesBuffer
;
time
=
timeBuffer
;
int
idx
=
0
;
int
nb_ant
=
1
;
int
eNB_id
=
0
;
for
(
int
ant
=
0
;
ant
<
nb_ant
;
ant
++
)
{
if
(
data
[
ant
]
!=
NULL
)
{
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
values
[
i
]
=
SquaredNorm
(
data
[
ant
][
i
]);
time
[
i
]
=
(
float
)
idx
;
idx
++
;
}
}
}
float
maxY
=
0
,
minY
=
0
;
for
(
int
k
=
0
;
k
<
len
;
k
++
)
{
maxY
=
std
::
max
(
maxY
,
values
[
k
]);
minY
=
std
::
min
(
minY
,
values
[
k
]);
}
float
maxYAbs
=
std
::
max
(
abs
(
maxY
),
abs
(
minY
));
QLineSeries
*
series
=
new
QLineSeries
();
QColor
MarkerColor
(
255
,
0
,
0
);
series
->
setColor
(
MarkerColor
);
float
Xpaint
,
Ypaint
;
float
minYScaled
=
0
,
maxYScaled
=
0
;
for
(
int
k
=
0
;
k
<
len
;
k
++
)
{
Xpaint
=
time
[
k
];
Ypaint
=
values
[
k
]
/
maxYAbs
*
50
;
series
->
append
(
Xpaint
,
Ypaint
);
maxYScaled
=
std
::
max
(
maxYScaled
,
Ypaint
);
minYScaled
=
std
::
min
(
minYScaled
,
Ypaint
);
}
QChart
*
chart
=
new
QChart
();
chart
->
legend
()
->
hide
();
int
nofTicks
=
6
;
QValueAxis
*
axisX
=
new
QValueAxis
;
axisX
->
setTickCount
(
nofTicks
);
axisX
->
setRange
(
0
,
len
);
axisX
->
setTitleText
(
"Time Index"
);
chart
->
addAxis
(
axisX
,
Qt
::
AlignBottom
);
QValueAxis
*
axisY
=
new
QValueAxis
;
axisY
->
setTickCount
(
nofTicks
);
axisY
->
setRange
((
minYScaled
+
0.4
*
minYScaled
),
(
maxYScaled
+
0.4
*
maxYScaled
));
axisY
->
setTitleText
(
"abs Channel"
);
chart
->
addAxis
(
axisY
,
Qt
::
AlignLeft
);
chart
->
addSeries
(
series
);
series
->
attachAxis
(
axisX
);
series
->
attachAxis
(
axisY
);
QChartView
*
chartView
=
new
QChartView
(
chart
);
chartView
->
resize
(
this
->
chartWidth
,
this
->
chartHight
);
QPixmap
p
=
chartView
->
grab
();
QPainter
PixPainter
(
&
p
);
float
freq_offset
=
(
float
)
this
->
ue
->
common_vars
.
freq_offset
;
std
::
string
strFreq
=
"Freq. Offset= "
+
std
::
to_string
(
freq_offset
);
QString
qstrFreq
=
QString
::
fromStdString
(
strFreq
);
PixPainter
.
drawText
(
100
,
1.6
*
maxYScaled
,
qstrFreq
);
float
timing_advance
=
(
float
)
this
->
ue
->
timing_advance
;
std
::
string
strTime
=
"Timing Advance= "
+
std
::
to_string
(
timing_advance
);
QString
qstrTime
=
QString
::
fromStdString
(
strTime
);
PixPainter
.
drawText
(
100
,
1.3
*
maxYScaled
,
qstrTime
);
*
this
->
pix
=
p
;
update
();
//call paintEvent()
}
void
PainterWidget
::
paintPixmap_uePdschIQ
()
{
// erase the previous paint
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
//paint the axis and I/Q samples
if
(
!
this
->
ue
->
pdsch_vars
[
0
][
0
]
->
rxdataF_comp0
[
0
])
return
;
NR_DL_FRAME_PARMS
*
frame_parms
=
&
this
->
ue
->
frame_parms
;
int
sz
=
7
*
2
*
frame_parms
->
N_RB_DL
*
12
;
// size of the malloced buffer
int
base
=
0
;
float
*
I
,
*
Q
;
float
FIinit
[
sz
*
RX_NB_TH_MAX
*
sizeof
(
*
I
)]
=
{
0
},
FQinit
[
sz
*
RX_NB_TH_MAX
*
sizeof
(
*
Q
)]
=
{
0
};
I
=
FIinit
;
Q
=
FQinit
;
for
(
int
thr
=
0
;
thr
<
RX_NB_TH_MAX
;
thr
++
)
{
scopeSample_t
*
pdsch_comp
=
(
scopeSample_t
*
)
this
->
ue
->
pdsch_vars
[
thr
][
0
]
->
rxdataF_comp0
[
0
];
for
(
int
s
=
0
;
s
<
sz
;
s
++
)
{
I
[
s
+
base
]
+=
pdsch_comp
[
s
].
r
;
Q
[
s
+
base
]
+=
pdsch_comp
[
s
].
i
;
}
base
+=
sz
;
}
float
maxX
=
0
,
maxY
=
0
,
minX
=
0
,
minY
=
0
;
for
(
int
k
=
0
;
k
<
base
;
k
++
)
{
maxX
=
std
::
max
(
maxX
,
I
[
k
]);
minX
=
std
::
min
(
minX
,
I
[
k
]);
maxY
=
std
::
max
(
maxY
,
Q
[
k
]);
minY
=
std
::
min
(
minY
,
Q
[
k
]);
}
float
maxXAbs
=
std
::
max
(
abs
(
maxX
),
abs
(
minX
));
float
maxYAbs
=
std
::
max
(
abs
(
maxY
),
abs
(
minY
));
float
Ipaint
,
Qpaint
;
QScatterSeries
*
series
=
new
QScatterSeries
();
series
->
setUseOpenGL
(
true
);
float
maxXScaled
=
0
,
maxYScaled
=
0
,
minXScaled
=
0
,
minYScaled
=
0
;
QVector
<
QPointF
>
points
(
base
);
// sz * RX_NB_TH_MAX * sizeof(*I)
for
(
int
k
=
0
;
k
<
base
;
k
++
)
{
//scale the I/Q samples!
Ipaint
=
I
[
k
]
/
maxXAbs
*
50
;
Qpaint
=
Q
[
k
]
/
maxYAbs
*
50
;
points
[
k
]
=
QPointF
(
Ipaint
,
Qpaint
);
maxXScaled
=
std
::
max
(
maxXScaled
,
Ipaint
);
minXScaled
=
std
::
min
(
minXScaled
,
Ipaint
);
maxYScaled
=
std
::
max
(
maxYScaled
,
Qpaint
);
minYScaled
=
std
::
min
(
minYScaled
,
Qpaint
);
}
series
->
replace
(
points
);
QColor
MarkerColor
(
0
,
255
,
0
);
series
->
setColor
(
MarkerColor
);
series
->
setMarkerSize
(
2
);
series
->
setBorderColor
(
Qt
::
transparent
);
series
->
setMarkerShape
(
QScatterSeries
::
MarkerShapeCircle
);
QChart
*
chart
=
new
QChart
();
chart
->
legend
()
->
hide
();
int
nofTicks
=
6
;
QValueAxis
*
axisX
=
new
QValueAxis
;
axisX
->
setTickCount
(
nofTicks
);
axisX
->
setRange
((
minXScaled
+
0.4
*
minXScaled
)
,
(
maxXScaled
+
0.4
*
maxXScaled
));
axisX
->
setTitleText
(
"Real"
);
chart
->
addAxis
(
axisX
,
Qt
::
AlignBottom
);
QValueAxis
*
axisY
=
new
QValueAxis
;
axisY
->
setTickCount
(
nofTicks
);
axisY
->
setRange
((
minYScaled
+
0.4
*
minYScaled
),
(
maxYScaled
+
0.4
*
maxYScaled
));
axisY
->
setTitleText
(
"Imag"
);
chart
->
addAxis
(
axisY
,
Qt
::
AlignLeft
);
chart
->
addSeries
(
series
);
series
->
attachAxis
(
axisX
);
series
->
attachAxis
(
axisY
);
QChartView
*
chartView
=
new
QChartView
();
chartView
->
resize
(
this
->
chartWidth
,
this
->
chartHight
);
chartView
->
setChart
(
chart
);
QPixmap
p
=
chartView
->
grab
();
*
this
->
pix
=
p
;
update
();
//call paintEvent()
}
void
PainterWidget
::
resizeEvent
(
QResizeEvent
*
event
)
{
if
((
width
()
!=
this
->
chartWidth
)
||
(
height
()
!=
this
->
chartHight
))
{
this
->
chartHight
=
height
();
this
->
chartWidth
=
width
();
// reset for waterfall plot
if
(
this
->
indexToPlot
==
6
)
{
QPixmap
*
newPix
=
new
QPixmap
(
this
->
chartWidth
,
this
->
chartHight
);
this
->
pix
=
newPix
;
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
this
->
iteration
=
0
;
this
->
waterFallh
=
this
->
chartHight
/
3
-
15
;
for
(
int
i
=
0
;
i
<
this
->
waterFallh
;
i
++
)
this
->
waterFallAvg
[
i
]
=
0
;
}
update
();
}
QWidget
::
resizeEvent
(
event
);
}
void
PainterWidget
::
paintPixmap_uePdcchIQ
()
{
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
scopeData_t
*
scope
=
(
scopeData_t
*
)
this
->
ue
->
scopeData
;
scope
->
flag_streaming
[
pdcchRxdataF_comp
]
=
1
;
scopeGraphData_t
**
UELiveData
=
(
scopeGraphData_t
**
)((
scopeData_t
*
)
this
->
ue
->
scopeData
)
->
liveDataUE
;
if
(
!
UELiveData
[
pdcchRxdataF_comp
])
return
;
const
int
len
=
UELiveData
[
pdcchRxdataF_comp
]
->
lineSz
;
scopeSample_t
*
pdcch_comp
=
(
scopeSample_t
*
)
(
UELiveData
[
pdcchRxdataF_comp
]
+
1
);
float
*
I
,
*
Q
;
float
FIinit
[
len
]
=
{
0
},
FQinit
[
len
]
=
{
0
};
I
=
FIinit
;
Q
=
FQinit
;
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
I
[
i
]
=
pdcch_comp
[
i
].
r
;
Q
[
i
]
=
pdcch_comp
[
i
].
i
;
}
float
maxX
=
0
,
maxY
=
0
,
minX
=
0
,
minY
=
0
;
for
(
int
k
=
0
;
k
<
len
;
k
++
)
{
maxX
=
std
::
max
(
maxX
,
I
[
k
]);
minX
=
std
::
min
(
minX
,
I
[
k
]);
maxY
=
std
::
max
(
maxY
,
Q
[
k
]);
minY
=
std
::
min
(
minY
,
Q
[
k
]);
}
float
maxXAbs
=
std
::
max
(
abs
(
maxX
),
abs
(
minX
));
float
maxYAbs
=
std
::
max
(
abs
(
maxY
),
abs
(
minY
));
QScatterSeries
*
series
=
new
QScatterSeries
();
series
->
setUseOpenGL
(
true
);
QColor
MarkerColor
(
0
,
0
,
255
);
series
->
setColor
(
MarkerColor
);
series
->
setMarkerSize
(
2
);
series
->
setBorderColor
(
Qt
::
transparent
);
series
->
setMarkerShape
(
QScatterSeries
::
MarkerShapeCircle
);
float
maxXScaled
=
0
,
maxYScaled
=
0
,
minXScaled
=
0
,
minYScaled
=
0
;
float
Ipaint
,
Qpaint
;
QVector
<
QPointF
>
points
(
len
);
for
(
int
k
=
0
;
k
<
len
;
k
++
)
{
//scale the I/Q samples!
if
(
abs
(
maxXAbs
-
0.0
)
>
100e-6
)
Ipaint
=
I
[
k
]
/
maxXAbs
*
50
;
else
Ipaint
=
I
[
k
];
if
(
abs
(
maxYAbs
-
0.0
)
>
100e-6
)
Qpaint
=
Q
[
k
]
/
maxYAbs
*
50
;
else
Qpaint
=
Q
[
k
];
//series->append(Ipaint, Qpaint);
points
[
k
]
=
QPointF
(
Ipaint
,
Qpaint
);
maxXScaled
=
std
::
max
(
maxXScaled
,
Ipaint
);
minXScaled
=
std
::
min
(
minXScaled
,
Ipaint
);
maxYScaled
=
std
::
max
(
maxYScaled
,
Qpaint
);
minYScaled
=
std
::
min
(
minYScaled
,
Qpaint
);
}
series
->
replace
(
points
);
QChart
*
chart
=
new
QChart
();
chart
->
legend
()
->
hide
();
int
nofTicks
=
6
;
QValueAxis
*
axisX
=
new
QValueAxis
;
axisX
->
setTickCount
(
nofTicks
);
if
(
(
minXScaled
!=
0
)
&&
(
maxXScaled
!=
0
))
{
axisX
->
setRange
((
minXScaled
+
0.4
*
minXScaled
)
,
(
maxXScaled
+
0.4
*
maxXScaled
));
}
else
{
axisX
->
setRange
(
-
10
,
10
);
}
axisX
->
setTitleText
(
"Real"
);
chart
->
addAxis
(
axisX
,
Qt
::
AlignBottom
);
QValueAxis
*
axisY
=
new
QValueAxis
;
axisY
->
setTickCount
(
nofTicks
);
if
((
minYScaled
!=
0
)
&&
(
maxYScaled
!=
0
))
{
axisY
->
setRange
((
minYScaled
+
0.4
*
minYScaled
),
(
maxYScaled
+
0.4
*
maxYScaled
));
}
else
{
axisY
->
setRange
(
-
10
,
10
);
}
axisY
->
setTitleText
(
"Imag"
);
chart
->
addAxis
(
axisY
,
Qt
::
AlignLeft
);
chart
->
addSeries
(
series
);
series
->
attachAxis
(
axisX
);
series
->
attachAxis
(
axisY
);
QChartView
*
chartView
=
new
QChartView
(
chart
);
chartView
->
resize
(
this
->
chartWidth
,
this
->
chartHight
);
QPixmap
p
=
chartView
->
grab
();
*
this
->
pix
=
p
;
update
();
//call paintEvent()
}
void
PainterWidget
::
paintPixmap_uePbchIQ
()
{
// erase the previous paint
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
scopeData_t
*
scope
=
(
scopeData_t
*
)
this
->
ue
->
scopeData
;
scope
->
flag_streaming
[
pbchRxdataF_comp
]
=
1
;
scopeGraphData_t
**
data
=
(
scopeGraphData_t
**
)((
scopeData_t
*
)
this
->
ue
->
scopeData
)
->
liveDataUE
;
if
(
!
data
[
pbchRxdataF_comp
])
return
;
const
int
len
=
data
[
pbchRxdataF_comp
]
->
lineSz
;
scopeSample_t
*
pbch_comp
=
(
scopeSample_t
*
)
(
data
[
pbchRxdataF_comp
]
+
1
);
float
*
I
,
*
Q
;
float
FIinit
[
len
]
=
{
0
},
FQinit
[
len
]
=
{
0
};
I
=
FIinit
;
Q
=
FQinit
;
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
I
[
i
]
=
pbch_comp
[
i
].
r
;
Q
[
i
]
=
pbch_comp
[
i
].
i
;
}
float
maxX
=
0
,
maxY
=
0
,
minX
=
0
,
minY
=
0
;
for
(
int
k
=
0
;
k
<
len
;
k
++
)
{
maxX
=
std
::
max
(
maxX
,
I
[
k
]);
minX
=
std
::
min
(
minX
,
I
[
k
]);
maxY
=
std
::
max
(
maxY
,
Q
[
k
]);
minY
=
std
::
min
(
minY
,
Q
[
k
]);
}
float
maxXAbs
=
std
::
max
(
abs
(
maxX
),
abs
(
minX
));
float
maxYAbs
=
std
::
max
(
abs
(
maxY
),
abs
(
minY
));
QScatterSeries
*
series
=
new
QScatterSeries
();
series
->
setUseOpenGL
(
true
);
QColor
MarkerColor
(
255
,
0
,
0
);
series
->
setColor
(
MarkerColor
);
series
->
setMarkerSize
(
2
);
series
->
setBorderColor
(
Qt
::
transparent
);
series
->
setMarkerShape
(
QScatterSeries
::
MarkerShapeCircle
);
int
Ipaint
,
Qpaint
;
QVector
<
QPointF
>
points
(
len
);
for
(
int
k
=
0
;
k
<
len
;
k
++
)
{
Ipaint
=
I
[
k
]
/
maxXAbs
*
50
;
Qpaint
=
Q
[
k
]
/
maxYAbs
*
50
;
points
[
k
]
=
QPointF
(
Ipaint
,
Qpaint
);
}
series
->
replace
(
points
);
QChart
*
chart
=
new
QChart
();
chart
->
legend
()
->
hide
();
int
nofTicks
=
6
;
QValueAxis
*
axisX
=
new
QValueAxis
;
axisX
->
setTickCount
(
nofTicks
);
axisX
->
setRange
((
minX
+
0.4
*
minX
)
,
(
maxX
+
0.4
*
maxX
));
axisX
->
setTitleText
(
"Real"
);
chart
->
addAxis
(
axisX
,
Qt
::
AlignBottom
);
QValueAxis
*
axisY
=
new
QValueAxis
;
axisY
->
setTickCount
(
nofTicks
);
axisY
->
setRange
((
minY
+
0.4
*
minY
),
(
maxY
+
0.4
*
maxY
));
axisY
->
setTitleText
(
"Imag"
);
chart
->
addAxis
(
axisY
,
Qt
::
AlignLeft
);
chart
->
addSeries
(
series
);
series
->
attachAxis
(
axisX
);
series
->
attachAxis
(
axisY
);
QChartView
*
chartView
=
new
QChartView
(
chart
);
chartView
->
resize
(
this
->
chartWidth
,
this
->
chartHight
);
QPixmap
p
=
chartView
->
grab
();
*
this
->
pix
=
p
;
update
();
//call paintEvent()
}
void
PainterWidget
::
paintPixmap_uePdschLLR
()
{
// erase the previous paint
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
//paint the axis and LLR values
if
(
!
this
->
ue
->
pdsch_vars
[
0
][
0
]
->
llr
[
0
])
return
;
int
num_re
=
4500
;
int
Qm
=
2
;
int
coded_bits_per_codeword
=
num_re
*
Qm
;
float
*
llr
,
*
bit
;
float
FBitinit
[
coded_bits_per_codeword
*
RX_NB_TH_MAX
]
=
{
0
},
FLlrinit
[
coded_bits_per_codeword
*
RX_NB_TH_MAX
]
=
{
0
};
bit
=
FBitinit
;
llr
=
FLlrinit
;
int
base
=
0
;
for
(
int
thr
=
0
;
thr
<
RX_NB_TH_MAX
;
thr
++
)
{
int16_t
*
pdsch_llr
=
(
int16_t
*
)
this
->
ue
->
pdsch_vars
[
thr
][
0
]
->
llr
[
0
];
// stream 0
for
(
int
i
=
0
;
i
<
coded_bits_per_codeword
;
i
++
)
{
llr
[
base
+
i
]
=
(
float
)
pdsch_llr
[
i
];
bit
[
base
+
i
]
=
(
float
)
base
+
i
;
}
base
+=
coded_bits_per_codeword
;
}
float
maxY
=
0
,
minY
=
0
;
for
(
int
k
=
0
;
k
<
base
;
k
++
)
{
maxY
=
std
::
max
(
maxY
,
llr
[
k
]);
minY
=
std
::
min
(
minY
,
llr
[
k
]);
}
float
maxYAbs
=
std
::
max
(
abs
(
maxY
),
abs
(
minY
));
QScatterSeries
*
series
=
new
QScatterSeries
();
series
->
setUseOpenGL
(
true
);
QColor
MarkerColor
(
0
,
255
,
0
);
series
->
setColor
(
MarkerColor
);
series
->
setMarkerSize
(
2
);
series
->
setBorderColor
(
Qt
::
transparent
);
series
->
setMarkerShape
(
QScatterSeries
::
MarkerShapeCircle
);
float
Xpaint
,
Ypaint
;
QVector
<
QPointF
>
points
(
base
);
float
minYScaled
=
0
,
maxYScaled
=
0
;
for
(
int
k
=
0
;
k
<
base
;
k
++
)
{
Xpaint
=
bit
[
k
];
Ypaint
=
llr
[
k
]
/
maxYAbs
*
50
;
points
[
k
]
=
QPointF
(
Xpaint
,
Ypaint
);
maxYScaled
=
std
::
max
(
maxYScaled
,
Ypaint
);
minYScaled
=
std
::
min
(
minYScaled
,
Ypaint
);
}
series
->
replace
(
points
);
QChart
*
chart
=
new
QChart
();
chart
->
legend
()
->
hide
();
int
nofTicks
=
6
;
QValueAxis
*
axisX
=
new
QValueAxis
;
axisX
->
setTickCount
(
nofTicks
);
axisX
->
setRange
(
0
,
base
);
axisX
->
setTitleText
(
"Sample Index"
);
chart
->
addAxis
(
axisX
,
Qt
::
AlignBottom
);
QValueAxis
*
axisY
=
new
QValueAxis
;
axisY
->
setTickCount
(
nofTicks
);
axisY
->
setRange
((
minYScaled
+
0.4
*
minYScaled
),
(
maxYScaled
+
0.4
*
maxYScaled
));
axisY
->
setTitleText
(
"LLR"
);
chart
->
addAxis
(
axisY
,
Qt
::
AlignLeft
);
chart
->
addSeries
(
series
);
series
->
attachAxis
(
axisX
);
series
->
attachAxis
(
axisY
);
QChartView
*
chartView
=
new
QChartView
(
chart
);
chartView
->
resize
(
this
->
chartWidth
,
this
->
chartHight
);
QPixmap
p
=
chartView
->
grab
();
*
this
->
pix
=
p
;
update
();
//call paintEvent()
}
void
PainterWidget
::
paintPixmap_uePdcchLLR
()
{
// erase the previous paint
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
scopeData_t
*
scope
=
(
scopeData_t
*
)
this
->
ue
->
scopeData
;
scope
->
flag_streaming
[
pdcchLlr
]
=
1
;
scopeGraphData_t
**
data
=
(
scopeGraphData_t
**
)((
scopeData_t
*
)
this
->
ue
->
scopeData
)
->
liveDataUE
;
if
(
!
data
[
pdcchLlr
])
return
;
const
int
len
=
data
[
pdcchLlr
]
->
lineSz
;
float
*
llr
,
*
bit
;
float
FBitinit
[
len
]
=
{
0
},
FLlrinit
[
len
]
=
{
0
};
bit
=
FBitinit
;
llr
=
FLlrinit
;
int16_t
*
pdcch_llr
=
(
int16_t
*
)(
data
[
pdcchLlr
]
+
1
);
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
llr
[
i
]
=
(
float
)
pdcch_llr
[
i
];
bit
[
i
]
=
(
float
)
i
;
}
float
maxY
=
0
,
minY
=
0
;
for
(
int
k
=
0
;
k
<
len
;
k
++
)
{
maxY
=
std
::
max
(
maxY
,
llr
[
k
]);
minY
=
std
::
min
(
minY
,
llr
[
k
]);
}
float
maxYAbs
=
std
::
max
(
abs
(
maxY
),
abs
(
minY
));
QScatterSeries
*
series
=
new
QScatterSeries
();
series
->
setUseOpenGL
(
true
);
QColor
MarkerColor
(
0
,
0
,
255
);
series
->
setColor
(
MarkerColor
);
series
->
setMarkerSize
(
2
);
series
->
setBorderColor
(
Qt
::
transparent
);
series
->
setMarkerShape
(
QScatterSeries
::
MarkerShapeCircle
);
float
minYScaled
=
0
,
maxYScaled
=
0
;
float
Xpaint
,
Ypaint
;
QVector
<
QPointF
>
points
(
len
);
for
(
int
k
=
0
;
k
<
len
;
k
++
)
{
Xpaint
=
bit
[
k
];
Ypaint
=
llr
[
k
]
/
maxYAbs
*
50
;
points
[
k
]
=
QPointF
(
Xpaint
,
Ypaint
);
maxYScaled
=
std
::
max
(
maxYScaled
,
Ypaint
);
minYScaled
=
std
::
min
(
minYScaled
,
Ypaint
);
}
series
->
replace
(
points
);
QChart
*
chart
=
new
QChart
();
chart
->
legend
()
->
hide
();
int
nofTicks
=
6
;
QValueAxis
*
axisX
=
new
QValueAxis
;
axisX
->
setTickCount
(
nofTicks
);
axisX
->
setRange
(
0
,
len
);
axisX
->
setTitleText
(
"Sample Index"
);
chart
->
addAxis
(
axisX
,
Qt
::
AlignBottom
);
QValueAxis
*
axisY
=
new
QValueAxis
;
axisY
->
setTickCount
(
nofTicks
);
axisY
->
setRange
((
minYScaled
+
0.4
*
minYScaled
),
(
maxYScaled
+
0.4
*
maxYScaled
));
axisY
->
setTitleText
(
"LLR"
);
chart
->
addAxis
(
axisY
,
Qt
::
AlignLeft
);
chart
->
addSeries
(
series
);
series
->
attachAxis
(
axisX
);
series
->
attachAxis
(
axisY
);
QChartView
*
chartView
=
new
QChartView
(
chart
);
chartView
->
resize
(
this
->
chartWidth
,
this
->
chartHight
);
QPixmap
p
=
chartView
->
grab
();
*
this
->
pix
=
p
;
update
();
//call paintEvent()
}
void
PainterWidget
::
paintPixmap_uePbchLLR
()
{
this
->
pix
->
fill
(
QColor
(
240
,
240
,
240
));
scopeData_t
*
scope
=
(
scopeData_t
*
)
this
->
ue
->
scopeData
;
scope
->
flag_streaming
[
pbchLlr
]
=
1
;
scopeGraphData_t
**
data
=
(
scopeGraphData_t
**
)((
scopeData_t
*
)
this
->
ue
->
scopeData
)
->
liveDataUE
;
if
(
!
data
[
pbchLlr
])
return
;
const
int
len
=
data
[
pbchLlr
]
->
lineSz
;
float
*
llr
,
*
bit
;
float
FBitinit
[
len
]
=
{
0
},
FLlrinit
[
len
]
=
{
0
};
bit
=
FBitinit
;
llr
=
FLlrinit
;
int16_t
*
llr_pbch
=
(
int16_t
*
)(
data
[
pbchLlr
]
+
1
);
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
llr
[
i
]
=
(
float
)
llr_pbch
[
i
];
bit
[
i
]
=
(
float
)
i
;
}
float
maxX
=
0
,
maxY
=
0
,
minX
=
0
,
minY
=
0
;
for
(
int
k
=
0
;
k
<
len
;
k
++
)
{
maxX
=
std
::
max
(
maxX
,
bit
[
k
]);
minX
=
std
::
min
(
minX
,
bit
[
k
]);
maxY
=
std
::
max
(
maxY
,
llr
[
k
]);
minY
=
std
::
min
(
minY
,
llr
[
k
]);
}
float
maxYAbs
=
std
::
max
(
abs
(
maxY
),
abs
(
minY
));
QScatterSeries
*
series
=
new
QScatterSeries
();
series
->
setUseOpenGL
(
true
);
QColor
MarkerColor
(
255
,
0
,
0
);
series
->
setColor
(
MarkerColor
);
series
->
setMarkerSize
(
2
);
series
->
setMarkerShape
(
QScatterSeries
::
MarkerShapeCircle
);
series
->
setBorderColor
(
Qt
::
transparent
);
QVector
<
QPointF
>
points
(
len
);
float
Xpaint
,
Ypaint
;
float
minYScaled
=
0
,
maxYScaled
=
0
;
for
(
int
k
=
0
;
k
<
len
;
k
++
)
{
Xpaint
=
bit
[
k
];
Ypaint
=
llr
[
k
]
/
maxYAbs
*
50
;
points
[
k
]
=
QPointF
(
Xpaint
,
Ypaint
);
maxYScaled
=
std
::
max
(
maxYScaled
,
Ypaint
);
minYScaled
=
std
::
min
(
minYScaled
,
Ypaint
);
}
series
->
replace
(
points
);
QChart
*
chart
=
new
QChart
();
chart
->
legend
()
->
hide
();
int
nofTicks
=
6
;
QValueAxis
*
axisX
=
new
QValueAxis
;
axisX
->
setTickCount
(
nofTicks
);
axisX
->
setRange
(
0
,
len
);
axisX
->
setTitleText
(
"Sample Index"
);
chart
->
addAxis
(
axisX
,
Qt
::
AlignBottom
);
QValueAxis
*
axisY
=
new
QValueAxis
;
axisY
->
setTickCount
(
nofTicks
);
axisY
->
setRange
((
minYScaled
+
0.4
*
minYScaled
),
(
maxYScaled
+
0.4
*
maxYScaled
));
axisY
->
setTitleText
(
"LLR"
);
chart
->
addAxis
(
axisY
,
Qt
::
AlignLeft
);
chart
->
addSeries
(
series
);
series
->
attachAxis
(
axisX
);
series
->
attachAxis
(
axisY
);
QChartView
*
chartView
=
new
QChartView
(
chart
);
chartView
->
resize
(
this
->
chartWidth
,
this
->
chartHight
);
QPixmap
p
=
chartView
->
grab
();
*
this
->
pix
=
p
;
update
();
//call paintEvent()
}
void
*
nrUEQtscopeThread
(
void
*
arg
)
{
PHY_VARS_NR_UE
*
ue
=
(
PHY_VARS_NR_UE
*
)
arg
;
int
argc
=
1
;
char
*
argv
[]
=
{
(
char
*
)
"nrqt_scopeUE"
};
QApplication
a
(
argc
,
argv
);
// Create a main window (widget)
QWidget
*
window
=
new
QWidget
();
window
->
setBaseSize
(
QSize
(
600
,
900
));
window
->
resize
(
600
,
900
);
window
->
setSizeIncrement
(
20
,
20
);
// Window title
window
->
setWindowTitle
(
"UE Scope"
);
// create the popup lists
KPIListSelect
*
combo1
=
new
KPIListSelect
(
window
);
combo1
->
setCurrentIndex
(
0
);
KPIListSelect
*
combo2
=
new
KPIListSelect
(
window
);
combo2
->
setCurrentIndex
(
1
);
KPIListSelect
*
combo3
=
new
KPIListSelect
(
window
);
combo3
->
setCurrentIndex
(
2
);
KPIListSelect
*
combo4
=
new
KPIListSelect
(
window
);
combo4
->
setCurrentIndex
(
3
);
KPIListSelect
*
combo5
=
new
KPIListSelect
(
window
);
combo5
->
setCurrentIndex
(
4
);
KPIListSelect
*
combo6
=
new
KPIListSelect
(
window
);
combo6
->
setCurrentIndex
(
7
);
// Initial Plots
PainterWidget
pwidgetueCombo3
(
combo3
,
ue
);
// I/Q PDSCH
PainterWidget
pwidgetueCombo4
(
combo4
,
ue
);
// LLR PDSCH */
PainterWidget
pwidgetueCombo1
(
combo1
,
ue
);
// I/Q PBCH
PainterWidget
pwidgetueCombo2
(
combo2
,
ue
);
// LLR PBCH
PainterWidget
pwidgetueCombo5
(
combo5
,
ue
);
// I/Q PDCCH
PainterWidget
pwidgetueCombo6
(
combo6
,
ue
);
// LLR PDCCH
while
(
true
)
{
// Main layout
QHBoxLayout
*
mainLayout
=
new
QHBoxLayout
;
// left and right layouts
QVBoxLayout
*
LeftLayout
=
new
QVBoxLayout
;
QVBoxLayout
*
RightLayout
=
new
QVBoxLayout
;
LeftLayout
->
addWidget
(
combo1
);
LeftLayout
->
addWidget
(
&
pwidgetueCombo1
,
20
);
LeftLayout
->
addStretch
();
// space for later plots
LeftLayout
->
addWidget
(
combo3
);
LeftLayout
->
addWidget
(
&
pwidgetueCombo3
,
20
);
LeftLayout
->
addStretch
();
// space for later plots
LeftLayout
->
addWidget
(
combo5
);
LeftLayout
->
addWidget
(
&
pwidgetueCombo5
,
20
);
LeftLayout
->
addStretch
();
// space for later plots
RightLayout
->
addWidget
(
combo2
);
RightLayout
->
addWidget
(
&
pwidgetueCombo2
,
20
);
RightLayout
->
addStretch
();
// space for later plots
RightLayout
->
addWidget
(
combo4
);
RightLayout
->
addWidget
(
&
pwidgetueCombo4
,
20
);
RightLayout
->
addStretch
();
// space for later plots
RightLayout
->
addWidget
(
combo6
);
RightLayout
->
addWidget
(
&
pwidgetueCombo6
,
20
);
RightLayout
->
addStretch
();
// space for later plots
// add the left and right layouts to the main layout
mainLayout
->
addLayout
(
LeftLayout
);
mainLayout
->
addLayout
(
RightLayout
);
// set the layout of the main window
window
->
setLayout
(
mainLayout
);
pwidgetueCombo1
.
makeConnections
();
pwidgetueCombo2
.
makeConnections
();
pwidgetueCombo3
.
makeConnections
();
pwidgetueCombo4
.
makeConnections
();
pwidgetueCombo5
.
makeConnections
();
pwidgetueCombo6
.
makeConnections
();
// display the main window
window
->
show
();
a
.
exec
();
}
pthread_exit
((
void
*
)
arg
);
//return NULL;
}
void
*
nrgNBQtscopeThread
(
void
*
arg
)
{
scopeData_t
*
p
=
(
scopeData_t
*
)
arg
;
int
argc
=
1
;
char
*
argv
[]
=
{
(
char
*
)
"nrqt_scopegNB"
};
QApplication
a
(
argc
,
argv
);
// Create a main window (widget)
QWidget
*
window
=
new
QWidget
();
window
->
resize
(
600
,
900
);
// Window title
window
->
setWindowTitle
(
"gNB Scope"
);
// create the popup lists
KPIListSelectgNB
*
combo1
=
new
KPIListSelectgNB
(
window
);
combo1
->
setCurrentIndex
(
0
);
KPIListSelectgNB
*
combo2
=
new
KPIListSelectgNB
(
window
);
combo2
->
setCurrentIndex
(
1
);
KPIListSelectgNB
*
combo3
=
new
KPIListSelectgNB
(
window
);
combo3
->
setCurrentIndex
(
2
);
KPIListSelectgNB
*
combo4
=
new
KPIListSelectgNB
(
window
);
combo4
->
setCurrentIndex
(
3
);
KPIListSelectgNB
*
combo5
=
new
KPIListSelectgNB
(
window
);
combo5
->
setCurrentIndex
(
4
);
KPIListSelectgNB
*
combo6
=
new
KPIListSelectgNB
(
window
);
combo6
->
setCurrentIndex
(
5
);
PainterWidgetgNB
pwidgetgnbCombo1
(
combo1
,
p
);
// I/Q PUSCH
PainterWidgetgNB
pwidgetgnbCombo2
(
combo2
,
p
);
// LLR PUSCH
PainterWidgetgNB
pwidgetgnbCombo3
(
combo3
,
p
);
// Channel Response
PainterWidgetgNB
pwidgetgnbCombo4
(
combo4
,
p
);
//
PainterWidgetgNB
pwidgetgnbCombo5
(
combo5
,
p
);
//
PainterWidgetgNB
pwidgetgnbCombo6
(
combo6
,
p
);
//
while
(
true
)
{
// Main layout
QHBoxLayout
*
mainLayout
=
new
QHBoxLayout
;
// left and right layouts
QVBoxLayout
*
LeftLayout
=
new
QVBoxLayout
;
QVBoxLayout
*
RightLayout
=
new
QVBoxLayout
;
LeftLayout
->
addWidget
(
combo1
);
LeftLayout
->
addWidget
(
&
pwidgetgnbCombo1
,
20
);
LeftLayout
->
addStretch
();
// space for later plots
LeftLayout
->
addWidget
(
combo3
);
LeftLayout
->
addWidget
(
&
pwidgetgnbCombo3
,
20
);
LeftLayout
->
addStretch
();
// space for later plots
LeftLayout
->
addWidget
(
combo5
);
LeftLayout
->
addWidget
(
&
pwidgetgnbCombo5
,
20
);
LeftLayout
->
addStretch
();
// space for later plots
RightLayout
->
addWidget
(
combo2
);
RightLayout
->
addWidget
(
&
pwidgetgnbCombo2
,
20
);
RightLayout
->
addStretch
();
// space for later plots
RightLayout
->
addWidget
(
combo4
);
RightLayout
->
addWidget
(
&
pwidgetgnbCombo4
,
20
);
RightLayout
->
addStretch
();
// space for later plots
RightLayout
->
addWidget
(
combo6
);
//
RightLayout
->
addWidget
(
&
pwidgetgnbCombo6
,
20
);
RightLayout
->
addStretch
();
// space for later plots
// add the left and right layouts to the main layout
mainLayout
->
addLayout
(
LeftLayout
);
mainLayout
->
addLayout
(
RightLayout
);
// set the layout of the main window
window
->
setLayout
(
mainLayout
);
pwidgetgnbCombo1
.
makeConnections
();
pwidgetgnbCombo2
.
makeConnections
();
pwidgetgnbCombo3
.
makeConnections
();
pwidgetgnbCombo4
.
makeConnections
();
pwidgetgnbCombo5
.
makeConnections
();
pwidgetgnbCombo6
.
makeConnections
();
// display the main window
window
->
show
();
a
.
exec
();
}
return
NULL
;
}
void
UEcopyData
(
PHY_VARS_NR_UE
*
ue
,
enum
UEdataType
type
,
void
*
dataIn
,
int
elementSz
,
int
colSz
,
int
lineSz
)
{
// Local static copy of the scope data bufs
// The active data buf is alterned to avoid interference between the Scope thread (display) and the Rx thread (data input)
// Index of "2" could be set to the number of Rx threads + 1
static
scopeGraphData_t
*
copyDataBufs
[
UEdataTypeNumberOfItems
][
2
]
=
{
0
};
static
int
copyDataBufsIdx
[
UEdataTypeNumberOfItems
]
=
{
0
};
scopeData_t
*
tmp
=
(
scopeData_t
*
)
ue
->
scopeData
;
if
(
tmp
)
{
// Begin of critical zone between UE Rx threads that might copy new data at the same time: might require a mutex
int
newCopyDataIdx
=
(
copyDataBufsIdx
[
type
]
==
0
)
?
1
:
0
;
copyDataBufsIdx
[
type
]
=
newCopyDataIdx
;
// End of critical zone between UE Rx threads
// New data will be copied in a different buffer than the live one
scopeGraphData_t
*
copyData
=
copyDataBufs
[
type
][
newCopyDataIdx
];
if
(
copyData
==
NULL
||
copyData
->
dataSize
<
elementSz
*
colSz
*
lineSz
)
{
scopeGraphData_t
*
ptr
=
(
scopeGraphData_t
*
)
realloc
(
copyData
,
sizeof
(
scopeGraphData_t
)
+
elementSz
*
colSz
*
lineSz
);
if
(
!
ptr
)
{
LOG_E
(
PHY
,
"can't realloc
\n
"
);
return
;
}
else
{
copyData
=
ptr
;
}
}
copyData
->
dataSize
=
elementSz
*
colSz
*
lineSz
;
copyData
->
elementSz
=
elementSz
;
copyData
->
colSz
=
colSz
;
copyData
->
lineSz
=
lineSz
;
memcpy
(
copyData
+
1
,
dataIn
,
elementSz
*
colSz
*
lineSz
);
copyDataBufs
[
type
][
newCopyDataIdx
]
=
copyData
;
// The new data just copied in the local static buffer becomes live now
((
scopeGraphData_t
**
)
tmp
->
liveDataUE
)[
type
]
=
copyData
;
}
}
void
nrUEinitQtScope
(
PHY_VARS_NR_UE
*
ue
)
{
ue
->
scopeData
=
malloc
(
sizeof
(
scopeData_t
));
scopeData_t
*
scope
=
(
scopeData_t
*
)
ue
->
scopeData
;
scope
->
copyData
=
UEcopyData
;
scope
->
liveDataUE
=
calloc
(
sizeof
(
scopeGraphData_t
*
),
UEdataTypeNumberOfItems
);
for
(
int
i
=
0
;
i
<
UEdataTypeNumberOfItems
;
i
++
){
scope
->
flag_streaming
[
i
]
=
0
;
}
pthread_t
qtscope_thread
;
threadCreate
(
&
qtscope_thread
,
nrUEQtscopeThread
,
ue
,
(
char
*
)
"qtscope"
,
-
1
,
sched_get_priority_min
(
SCHED_RR
));
}
void
nrgNBinitQtScope
(
scopeParms_t
*
p
)
{
p
->
gNB
->
scopeData
=
malloc
(
sizeof
(
scopeData_t
));
scopeData_t
*
scope
=
(
scopeData_t
*
)
p
->
gNB
->
scopeData
;
scope
->
gNB
=
p
->
gNB
;
scope
->
argc
=
p
->
argc
;
scope
->
argv
=
p
->
argv
;
scope
->
ru
=
p
->
ru
;
pthread_t
qtscope_thread
;
threadCreate
(
&
qtscope_thread
,
nrgNBQtscopeThread
,
p
->
gNB
->
scopeData
,
(
char
*
)
"qtscope"
,
-
1
,
sched_get_priority_min
(
SCHED_RR
));
}
extern
"C"
void
nrqtscope_autoinit
(
void
*
dataptr
)
{
AssertFatal
(
(
IS_SOFTMODEM_GNB_BIT
||
IS_SOFTMODEM_5GUE_BIT
),
"Scope cannot find NRUE or GNB context"
);
if
(
IS_SOFTMODEM_GNB_BIT
)
nrgNBinitQtScope
((
scopeParms_t
*
)
dataptr
);
else
nrUEinitQtScope
((
PHY_VARS_NR_UE
*
)
dataptr
);
//nrUEinitQtScope((PHY_VARS_NR_UE *)dataptr);
}
openair1/PHY/TOOLS/nr_phy_qt_scope.h
0 → 100644
View file @
34c2f0be
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/* Header file generated by Bo Zhao (Fraunhofer IIS) on Wed. Dec. 08, 2021*/
#ifndef QT_SCOPE_MAINWINDOW_H
#define QT_SCOPE_MAINWINDOW_H
#include <QComboBox>
#include <QMessageBox>
#include <QtCharts>
#include <QChartView>
#include <QLineSeries>
extern
"C"
{
#include <simple_executable.h>
#include <common/utils/system.h>
#include "common/ran_context.h"
#include <openair1/PHY/defs_gNB.h>
#include "PHY/defs_gNB.h"
#include "PHY/defs_nr_UE.h"
#include "PHY/defs_RU.h"
#include "executables/softmodem-common.h"
#include "phy_scope_interface.h"
#include <openair2/LAYER2/NR_MAC_gNB/mac_proto.h>
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
extern
RAN_CONTEXT_t
RC
;
}
typedef
struct
{
float
max_value
;
float
min_value
;
float
avg_value
;
int
plot_idx
;
uint64_t
avg_idx
;
uint64_t
nof_retrans
;
// especially for the KPI: nof retransmissions
QLineSeries
*
series
;
QLineSeries
*
seriesMin
;
QLineSeries
*
seriesMax
;
QLineSeries
*
seriesAvg
;
}
KPI_elements
;
// drop-down list UE
class
KPIListSelect
:
public
QComboBox
{
Q_OBJECT
public:
explicit
KPIListSelect
(
QWidget
*
parent
=
0
);
~
KPIListSelect
();
private:
};
// drop-down list gNB
class
KPIListSelectgNB
:
public
QComboBox
{
Q_OBJECT
public:
explicit
KPIListSelectgNB
(
QWidget
*
parent
=
0
);
~
KPIListSelectgNB
();
private:
};
// Paint first on a pixmap, then on the widget. Previous paint is erased
class
PainterWidget
:
public
QWidget
{
Q_OBJECT
public:
PainterWidget
(
QComboBox
*
parent
,
PHY_VARS_NR_UE
*
ue
);
void
makeConnections
();
void
resetKPIPlot
(
KPI_elements
*
inputStruct
);
void
resetKPIValues
(
KPI_elements
*
inputStruct
);
QPixmap
*
pix
;
QTimer
*
timer
;
int
chartHight
,
chartWidth
;
QComboBox
*
parentWindow
;
QTimer
*
timerWaterFallTime
;
// for waterfill graphs
int
waterFallh
;
int
iteration
;
double
*
waterFallAvg
;
bool
isWaterFallTimeActive
;
extended_kpi_ue
extendKPIUE
;
KPI_elements
DLBLER
;
KPI_elements
DLMCS
;
KPI_elements
Throu
;
KPI_elements
nofRBs
;
protected:
void
paintEvent
(
QPaintEvent
*
event
);
void
resizeEvent
(
QResizeEvent
*
event
)
override
;
public
slots
:
// IQ constellations
void
paintPixmap_uePdschIQ
();
void
paintPixmap_uePbchIQ
();
void
paintPixmap_uePdcchIQ
();
// LLR plots
void
paintPixmap_uePdschLLR
();
void
paintPixmap_uePbchLLR
();
void
paintPixmap_uePdcchLLR
();
// Waterfall
void
paintPixmap_ueWaterFallTime
();
void
paintPixmap_ueChannelResponse
();
// Extended KPIs
void
KPI_DL_BLER
();
void
KPI_DL_MCS
();
void
KPI_DL_Throu
();
void
KPI_Nof_RBs
();
private:
PHY_VARS_NR_UE
*
ue
;
int
indexToPlot
;
int
previousIndex
;
};
// Paint class for gNB
class
PainterWidgetgNB
:
public
QWidget
{
Q_OBJECT
public:
PainterWidgetgNB
(
QComboBox
*
parent
,
scopeData_t
*
p
);
void
makeConnections
();
void
createPixMap
(
float
*
xData
,
float
*
yData
,
int
len
,
QColor
MarkerColor
,
const
QString
xLabel
,
const
QString
yLabel
,
bool
scaleX
);
void
resetKPIPlot
(
KPI_elements
*
inputStruct
);
void
resetKPIValues
(
KPI_elements
*
inputStruct
);
QPixmap
*
pix
;
QTimer
*
timer
;
QTimer
*
timerRetrans
;
int
chartHight
,
chartWidth
;
int
nb_UEs
;
QComboBox
*
parentWindow
;
KPI_elements
ULBLER
;
KPI_elements
ULMCS
;
KPI_elements
DLBLER
;
KPI_elements
DLMCS
;
KPI_elements
ULThrou
;
KPI_elements
DLThrou
;
KPI_elements
nofRBs
;
KPI_elements
ULSNR
;
KPI_elements
DLSNR
;
KPI_elements
ULRetrans
[
4
];
KPI_elements
DLRetrans
[
4
];
protected:
void
paintEvent
(
QPaintEvent
*
event
);
void
resizeEvent
(
QResizeEvent
*
event
)
override
;
public
slots
:
void
KPI_PuschIQ
();
void
KPI_PuschLLR
();
void
KPI_ChannelResponse
();
void
KPI_UL_BLER
();
void
KPI_UL_MCS
();
void
KPI_DL_BLER
();
void
KPI_DL_MCS
();
void
KPI_UL_Throu
();
void
KPI_DL_Throu
();
void
KPI_Nof_RBs
();
void
KPI_UL_SNR
();
void
KPI_DL_SNR
();
void
KPI_UL_Retrans
();
void
KPI_DL_Retrans
();
private:
scopeData_t
*
p
;
int
indexToPlot
;
int
previousIndex
;
};
#endif // QT_SCOPE_MAINWINDOW_H
openair1/PHY/TOOLS/nr_phy_scope.c
View file @
34c2f0be
...
@@ -24,6 +24,7 @@
...
@@ -24,6 +24,7 @@
/* Form definition file generated by fdesign */
/* Form definition file generated by fdesign */
#include <stdlib.h>
#include <stdlib.h>
#include <stdio.h>
#include "nr_phy_scope.h"
#include "nr_phy_scope.h"
#include "executables/softmodem-common.h"
#include "executables/softmodem-common.h"
#include "executables/nr-softmodem-common.h"
#include "executables/nr-softmodem-common.h"
...
@@ -290,6 +291,8 @@ static void genericPowerPerAntena(OAIgraph_t *graph, const int nb_ant, const sc
...
@@ -290,6 +291,8 @@ static void genericPowerPerAntena(OAIgraph_t *graph, const int nb_ant, const sc
float
*
values
,
*
time
;
float
*
values
,
*
time
;
oai_xygraph_getbuff
(
graph
,
&
time
,
&
values
,
len
,
0
);
oai_xygraph_getbuff
(
graph
,
&
time
,
&
values
,
len
,
0
);
printf
(
"************Number of Antennas: %i"
,
nb_ant
);
for
(
int
ant
=
0
;
ant
<
nb_ant
;
ant
++
)
{
for
(
int
ant
=
0
;
ant
<
nb_ant
;
ant
++
)
{
if
(
data
[
ant
]
!=
NULL
)
{
if
(
data
[
ant
]
!=
NULL
)
{
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
...
@@ -757,6 +760,8 @@ static void uePdschIQ (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_
...
@@ -757,6 +760,8 @@ static void uePdschIQ (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_
memset
(
I
+
base
,
0
,
sz
*
RX_NB_TH_MAX
*
sizeof
(
*
I
));
memset
(
I
+
base
,
0
,
sz
*
RX_NB_TH_MAX
*
sizeof
(
*
I
));
memset
(
Q
+
base
,
0
,
sz
*
RX_NB_TH_MAX
*
sizeof
(
*
Q
));
memset
(
Q
+
base
,
0
,
sz
*
RX_NB_TH_MAX
*
sizeof
(
*
Q
));
//printf("sz: %i, sizeof(*I): %i\n", sz, sizeof(*I));
for
(
int
thr
=
0
;
thr
<
RX_NB_TH_MAX
;
thr
++
)
{
for
(
int
thr
=
0
;
thr
<
RX_NB_TH_MAX
;
thr
++
)
{
scopeSample_t
*
pdsch_comp
=
(
scopeSample_t
*
)
phy_vars_ue
->
pdsch_vars
[
thr
][
eNB_id
]
->
rxdataF_comp0
[
0
];
scopeSample_t
*
pdsch_comp
=
(
scopeSample_t
*
)
phy_vars_ue
->
pdsch_vars
[
thr
][
eNB_id
]
->
rxdataF_comp0
[
0
];
...
@@ -829,6 +834,7 @@ static OAI_phy_scope_t *create_phy_scope_nrue( int ID ) {
...
@@ -829,6 +834,7 @@ static OAI_phy_scope_t *create_phy_scope_nrue( int ID ) {
// LLR of PDCCH
// LLR of PDCCH
fdui
->
graph
[
5
]
=
nrUEcommonGraph
(
uePcchLLR
,
fdui
->
graph
[
5
]
=
nrUEcommonGraph
(
uePcchLLR
,
FL_POINTS_XYPLOT
,
0
,
curY
,
500
,
100
,
"PDCCH Log-Likelihood Ratios (LLR, mag)"
,
FL_CYAN
);
FL_POINTS_XYPLOT
,
0
,
curY
,
500
,
100
,
"PDCCH Log-Likelihood Ratios (LLR, mag)"
,
FL_CYAN
);
fl_set_xyplot_xgrid
(
fdui
->
graph
[
5
].
graph
,
FL_GRID_MAJOR
);
// I/Q PDCCH comp
// I/Q PDCCH comp
fdui
->
graph
[
6
]
=
nrUEcommonGraph
(
uePcchIQ
,
fdui
->
graph
[
6
]
=
nrUEcommonGraph
(
uePcchIQ
,
FL_POINTS_XYPLOT
,
500
,
curY
,
300
,
100
,
"PDCCH I/Q of MF Output"
,
FL_CYAN
);
FL_POINTS_XYPLOT
,
500
,
curY
,
300
,
100
,
"PDCCH I/Q of MF Output"
,
FL_CYAN
);
...
@@ -837,6 +843,7 @@ static OAI_phy_scope_t *create_phy_scope_nrue( int ID ) {
...
@@ -837,6 +843,7 @@ static OAI_phy_scope_t *create_phy_scope_nrue( int ID ) {
// LLR of PDSCH
// LLR of PDSCH
fdui
->
graph
[
7
]
=
nrUEcommonGraph
(
uePdschLLR
,
fdui
->
graph
[
7
]
=
nrUEcommonGraph
(
uePdschLLR
,
FL_POINTS_XYPLOT
,
0
,
curY
,
500
,
200
,
"PDSCH Log-Likelihood Ratios (LLR, mag)"
,
FL_YELLOW
);
FL_POINTS_XYPLOT
,
0
,
curY
,
500
,
200
,
"PDSCH Log-Likelihood Ratios (LLR, mag)"
,
FL_YELLOW
);
fl_set_xyplot_xgrid
(
fdui
->
graph
[
7
].
graph
,
FL_GRID_MAJOR
);
// I/Q PDSCH comp
// I/Q PDSCH comp
fdui
->
graph
[
8
]
=
nrUEcommonGraph
(
uePdschIQ
,
fdui
->
graph
[
8
]
=
nrUEcommonGraph
(
uePdschIQ
,
FL_POINTS_XYPLOT
,
500
,
curY
,
300
,
200
,
"PDSCH I/Q of MF Output"
,
FL_YELLOW
);
FL_POINTS_XYPLOT
,
500
,
curY
,
300
,
200
,
"PDSCH I/Q of MF Output"
,
FL_YELLOW
);
...
@@ -891,7 +898,7 @@ void phy_scope_nrUE(scopeGraphData_t **UEliveData,
...
@@ -891,7 +898,7 @@ void phy_scope_nrUE(scopeGraphData_t **UEliveData,
}
}
static
void
*
nrUEscopeThread
(
void
*
arg
)
{
static
void
*
nrUEscopeThread
(
void
*
arg
)
{
PHY_VARS_NR_UE
*
ue
=
(
PHY_VARS_NR_UE
*
)
arg
;
PHY_VARS_NR_UE
*
ue
=
(
PHY_VARS_NR_UE
*
)
arg
;
// local structure with all top-level phy date for UE, as passed through arg
size_t
stksize
;
size_t
stksize
;
pthread_attr_t
atr
=
{
0
};
pthread_attr_t
atr
=
{
0
};
pthread_attr_getstacksize
(
&
atr
,
&
stksize
);
pthread_attr_getstacksize
(
&
atr
,
&
stksize
);
...
@@ -899,7 +906,7 @@ static void *nrUEscopeThread(void *arg) {
...
@@ -899,7 +906,7 @@ static void *nrUEscopeThread(void *arg) {
int
fl_argc
=
1
;
int
fl_argc
=
1
;
char
*
name
=
"5G-UE-scope"
;
char
*
name
=
"5G-UE-scope"
;
fl_initialize
(
&
fl_argc
,
&
name
,
NULL
,
0
,
0
);
fl_initialize
(
&
fl_argc
,
&
name
,
NULL
,
0
,
0
);
OAI_phy_scope_t
*
form_nrue
=
create_phy_scope_nrue
(
0
);
OAI_phy_scope_t
*
form_nrue
=
create_phy_scope_nrue
(
0
);
// build scope, in which one figure is created for each KPI. Here, 9 KPI for UE
while
(
!
oai_exit
)
{
while
(
!
oai_exit
)
{
fl_freeze_form
(
form_nrue
->
phy_scope
);
fl_freeze_form
(
form_nrue
->
phy_scope
);
...
@@ -961,6 +968,8 @@ void nrUEinitScope(PHY_VARS_NR_UE *ue) {
...
@@ -961,6 +968,8 @@ void nrUEinitScope(PHY_VARS_NR_UE *ue) {
scopeData_t
*
scope
=
(
scopeData_t
*
)
ue
->
scopeData
;
scopeData_t
*
scope
=
(
scopeData_t
*
)
ue
->
scopeData
;
scope
->
copyData
=
UEcopyData
;
scope
->
copyData
=
UEcopyData
;
AssertFatal
(
scope
->
liveData
=
calloc
(
sizeof
(
scopeGraphData_t
*
),
UEdataTypeNumberOfItems
),
""
);
AssertFatal
(
scope
->
liveData
=
calloc
(
sizeof
(
scopeGraphData_t
*
),
UEdataTypeNumberOfItems
),
""
);
for
(
int
i
=
0
;
i
<
UEdataTypeNumberOfItems
;
i
++
)
scope
->
flag_streaming
[
i
]
=
1
;
pthread_t
forms_thread
;
pthread_t
forms_thread
;
threadCreate
(
&
forms_thread
,
nrUEscopeThread
,
ue
,
"scope"
,
-
1
,
OAI_PRIORITY_RT_LOW
);
threadCreate
(
&
forms_thread
,
nrUEscopeThread
,
ue
,
"scope"
,
-
1
,
OAI_PRIORITY_RT_LOW
);
}
}
...
...
openair1/PHY/TOOLS/phy_scope_interface.h
View file @
34c2f0be
...
@@ -29,11 +29,19 @@
...
@@ -29,11 +29,19 @@
* \note
* \note
* \warning
* \warning
*/
*/
#ifndef __PHY_SCOPE_INTERFACE_H
__
#ifndef __PHY_SCOPE_INTERFACE_H
#define __PHY_SCOPE_INTERFACE_H
__
#define __PHY_SCOPE_INTERFACE_H
#include <openair1/PHY/defs_gNB.h>
#include <openair1/PHY/defs_gNB.h>
#include <openair1/PHY/defs_nr_UE.h>
#include <openair1/PHY/defs_nr_UE.h>
typedef
struct
{
float
DL_BLER
;
uint32_t
blockSize
;
// block size, to be used for throughput calculation
uint8_t
dl_mcs
;
uint16_t
nofRBs
;
}
extended_kpi_ue
;
typedef
struct
{
typedef
struct
{
int
*
argc
;
int
*
argc
;
char
**
argv
;
char
**
argv
;
...
@@ -43,18 +51,20 @@ typedef struct {
...
@@ -43,18 +51,20 @@ typedef struct {
enum
UEdataType
{
enum
UEdataType
{
pbchDlChEstimateTime
,
pbchDlChEstimateTime
,
pbchLlr
,
pbchRxdataF_comp
,
pdcchLlr
,
pdcchRxdataF_comp
,
pdcchRxdataF_comp
,
pdcchLlr
,
pbchRxdataF_comp
,
pbchLlr
,
UEdataTypeNumberOfItems
UEdataTypeNumberOfItems
};
};
typedef
struct
scopeData_s
{
typedef
struct
scopeData_s
{
int
flag_streaming
[
UEdataTypeNumberOfItems
];
int
*
argc
;
int
*
argc
;
char
**
argv
;
char
**
argv
;
RU_t
*
ru
;
RU_t
*
ru
;
PHY_VARS_gNB
*
gNB
;
PHY_VARS_gNB
*
gNB
;
void
*
liveDataUE
;
void
*
liveData
;
void
*
liveData
;
void
(
*
slotFunc
)(
int32_t
*
data
,
int
slot
,
void
*
scopeData
);
void
(
*
slotFunc
)(
int32_t
*
data
,
int
slot
,
void
*
scopeData
);
void
(
*
copyData
)(
PHY_VARS_NR_UE
*
,
enum
UEdataType
,
void
*
data
,
int
elementSz
,
int
colSz
,
int
lineSz
);
void
(
*
copyData
)(
PHY_VARS_NR_UE
*
,
enum
UEdataType
,
void
*
data
,
int
elementSz
,
int
colSz
,
int
lineSz
);
...
@@ -64,4 +74,7 @@ int load_softscope(char *exectype, void *initarg);
...
@@ -64,4 +74,7 @@ int load_softscope(char *exectype, void *initarg);
int
end_forms
(
void
)
;
int
end_forms
(
void
)
;
#define UEscopeCopy(ue, type, ...) if(ue->scopeData) ((scopeData_t*)ue->scopeData)->copyData(ue, type, ##__VA_ARGS__);
#define UEscopeCopy(ue, type, ...) if(ue->scopeData) ((scopeData_t*)ue->scopeData)->copyData(ue, type, ##__VA_ARGS__);
void
getKPIUE
(
extended_kpi_ue
*
kpiStructure
);
#endif
#endif
openair1/PHY/defs_nr_UE.h
View file @
34c2f0be
...
@@ -36,8 +36,6 @@
...
@@ -36,8 +36,6 @@
#include "defs_nr_common.h"
#include "defs_nr_common.h"
#include "CODING/nrPolar_tools/nr_polar_pbch_defs.h"
#include "CODING/nrPolar_tools/nr_polar_pbch_defs.h"
#define _GNU_SOURCE
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <malloc.h>
#include <malloc.h>
...
...
openair1/PHY/impl_defs_nr.h
View file @
34c2f0be
...
@@ -139,7 +139,7 @@ typedef struct TDD_UL_DL_configCommon_s {
...
@@ -139,7 +139,7 @@ typedef struct TDD_UL_DL_configCommon_s {
struct
TDD_UL_DL_configCommon_s
*
p_next
;
struct
TDD_UL_DL_configCommon_s
*
p_next
;
}
TDD_UL_DL_configCommon_t
;
}
TDD_UL_DL_configCommon_t
;
typedef
struct
{
typedef
struct
TDD_UL_DL_SlotConfig_s
{
/// \ Identifies a slot within a dl-UL-TransmissionPeriodicity (given in tdd-UL-DL-configurationCommon)
/// \ Identifies a slot within a dl-UL-TransmissionPeriodicity (given in tdd-UL-DL-configurationCommon)
uint16_t
slotIndex
;
uint16_t
slotIndex
;
/// \ The direction (downlink or uplink) for the symbols in this slot. "allDownlink" indicates that all symbols in this slot are used
/// \ The direction (downlink or uplink) for the symbols in this slot. "allDownlink" indicates that all symbols in this slot are used
...
@@ -154,7 +154,7 @@ typedef struct {
...
@@ -154,7 +154,7 @@ typedef struct {
/// Corresponds to L1 parameter 'number-of-UL-symbols-dedicated' (see 38.211, section FFS_Section)
/// Corresponds to L1 parameter 'number-of-UL-symbols-dedicated' (see 38.211, section FFS_Section)
uint16_t
nrofUplinkSymbols
;
uint16_t
nrofUplinkSymbols
;
/// \ for setting a sequence
/// \ for setting a sequence
struct
TDD_UL_DL_SlotConfig_
t
*
p_next_TDD_UL_DL_SlotConfig
;
struct
TDD_UL_DL_SlotConfig_
s
*
p_next_TDD_UL_DL_SlotConfig
;
}
TDD_UL_DL_SlotConfig_t
;
}
TDD_UL_DL_SlotConfig_t
;
/***********************************************************************
/***********************************************************************
...
...
openair1/SCHED_NR/phy_frame_config_nr.c
View file @
34c2f0be
...
@@ -221,7 +221,7 @@ void add_tdd_dedicated_configuration_nr(NR_DL_FRAME_PARMS *frame_parms, int slot
...
@@ -221,7 +221,7 @@ void add_tdd_dedicated_configuration_nr(NR_DL_FRAME_PARMS *frame_parms, int slot
if
(
next
==
0
)
{
if
(
next
==
0
)
{
frame_parms
->
p_TDD_UL_DL_ConfigDedicated
=
p_TDD_UL_DL_ConfigDedicated
;
frame_parms
->
p_TDD_UL_DL_ConfigDedicated
=
p_TDD_UL_DL_ConfigDedicated
;
}
else
{
}
else
{
p_previous_TDD_UL_DL_ConfigDedicated
->
p_next_TDD_UL_DL_SlotConfig
=
(
struct
TDD_UL_DL_SlotConfig_t
*
)
p_TDD_UL_DL_ConfigDedicated
;
p_previous_TDD_UL_DL_ConfigDedicated
->
p_next_TDD_UL_DL_SlotConfig
=
(
TDD_UL_DL_SlotConfig_t
*
)
p_TDD_UL_DL_ConfigDedicated
;
}
}
p_TDD_UL_DL_ConfigDedicated
->
slotIndex
=
slotIndex
;
p_TDD_UL_DL_ConfigDedicated
->
slotIndex
=
slotIndex
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment