remove nrqtscope
This commit is contained in:
committed by
Robert Schmidt
parent
ae2a79e566
commit
394431a594
@@ -1885,21 +1885,6 @@ set (SIMUSRC
|
||||
add_library(SIMU STATIC ${SIMUSRC} )
|
||||
target_include_directories(SIMU PUBLIC ${OPENAIR1_DIR}/SIMULATION/TOOLS ${OPENAIR1_DIR}/SIMULATION/RF)
|
||||
|
||||
# Qt-based scope
|
||||
add_boolean_option(ENABLE_NRQTSCOPE OFF "Build the Qt-Scope" OFF)
|
||||
if (ENABLE_NRQTSCOPE)
|
||||
find_package(Qt5 REQUIRED COMPONENTS Widgets Charts)
|
||||
message ("Qt5 Widgets and Charts found for nrqtscope")
|
||||
set(QTSCOPE_SOURCE_NR
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/nr_phy_qt_scope.cpp
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/phy_scope_interface.c)
|
||||
# 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})
|
||||
target_link_libraries(nrqtscope PRIVATE Qt5::Widgets Qt5::Charts)
|
||||
target_link_libraries(nrqtscope PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
|
||||
endif()
|
||||
|
||||
add_library(SIMU_ETH STATIC
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c
|
||||
|
||||
@@ -46,7 +46,7 @@ BUILD_DOXYGEN=0
|
||||
DISABLE_HARDWARE_DEPENDENCY="False"
|
||||
CMAKE_BUILD_TYPE="RelWithDebInfo"
|
||||
CMAKE_CMD="$CMAKE"
|
||||
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope nrqtscope ldpc_cuda ldpc_t2 websrv oai_iqplayer"
|
||||
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope ldpc_cuda ldpc_t2 websrv oai_iqplayer"
|
||||
TARGET_LIST=""
|
||||
|
||||
function print_help() {
|
||||
|
||||
@@ -541,7 +541,6 @@ check_install_additional_tools (){
|
||||
doxygen \
|
||||
libgnutls28-dev \
|
||||
libpthread-stubs0-dev \
|
||||
libqt5charts5-dev \
|
||||
tshark \
|
||||
uml-utilities \
|
||||
iperf3 \
|
||||
|
||||
+2
-4
@@ -174,16 +174,14 @@ Using the help option of the build script you can get the list of available opti
|
||||
```bash
|
||||
./build_oai --build-lib all # build all
|
||||
./build_oai --build-lib telnetsrv # build only telnetsrv
|
||||
./build_oai --build-lib "telnetsrv enbscope uescope nrscope nrqtscope"
|
||||
./build_oai --build-lib telnetsrv --build-lib nrqtscope
|
||||
./build_oai --build-lib "telnetsrv enbscope uescope nrscope"
|
||||
```
|
||||
|
||||
The following libraries are build in CI and should always work: `telnetsrv`,
|
||||
`enbscope`, `uescope`, `nrscope`, `nrqtscope`.
|
||||
`enbscope`, `uescope`, `nrscope`.
|
||||
|
||||
Some libraries have further dependencies and might not build on every system:
|
||||
- `enbscope`, `uescope`, `nrscope`: libforms/X
|
||||
- `nrqtscope`: Qt5
|
||||
- `ldpc_cuda`: CUDA
|
||||
- `websrv`: npm and others
|
||||
- `ldpc_t2`: DPDK with patch
|
||||
|
||||
@@ -2291,7 +2291,6 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/nr_phy_scope.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/nr_phy_scope.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/lte_phy_scope.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/nr_phy_qt_scope.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/cadd_vv.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/phy_scope.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/signal_energy.c \
|
||||
|
||||
+1
-1
@@ -105,7 +105,7 @@ The other SDRs (AW2S, LimeSDR, ...) have no READMEs.
|
||||
|
||||
## Special-purpose libraries
|
||||
|
||||
- OAI has two scopes, one based on Xforms, one on Qt5, described in [this README](../openair1/PHY/TOOLS/readme.md)
|
||||
- OAI has a scope based on Xforms, described in [this README](../openair1/PHY/TOOLS/readme.md)
|
||||
- OAI comes with an integrated [telnet server](../common/utils/telnetsrv/DOC/telnethelp.md) to monitor and control
|
||||
- OAI comes with an integrated [web server](../common/utils/websrv/DOC/websrv.md)
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ RUN /bin/sh oaienv && \
|
||||
mkdir -p log && \
|
||||
./build_oai -c --ninja \
|
||||
--eNB --gNB --RU --UE --nrUE \
|
||||
--build-lib "telnetsrv enbscope uescope nrscope nrqtscope" \
|
||||
--build-lib "telnetsrv enbscope uescope nrscope" \
|
||||
-w USRP -t Ethernet \
|
||||
--build-e2 --cmake-opt -DXAPP_MULTILANGUAGE=OFF \
|
||||
--noavx512 \
|
||||
|
||||
@@ -769,15 +769,6 @@ int main( int argc, char **argv ) {
|
||||
load_softscope("nr",&p);
|
||||
}
|
||||
|
||||
if(IS_SOFTMODEM_DOSCOPE_QT) {
|
||||
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 && NFAPI_MODE != NFAPI_MODE_AERIAL) {
|
||||
printf("Not NFAPI mode - call init_eNB_afterRU()\n");
|
||||
init_eNB_afterRU();
|
||||
|
||||
@@ -594,10 +594,6 @@ int main(int argc, char **argv)
|
||||
init_openair0();
|
||||
lock_memory_to_ram();
|
||||
|
||||
if(IS_SOFTMODEM_DOSCOPE_QT) {
|
||||
load_softscope("nrqt",PHY_vars_UE_g[0][0]);
|
||||
}
|
||||
|
||||
if(IS_SOFTMODEM_DOSCOPE) {
|
||||
load_softscope("nr",PHY_vars_UE_g[0][0]);
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ void get_common_options(configmodule_interface_t *cfg, uint32_t execmask)
|
||||
uint32_t start_telnetsrv = 0, start_telnetclt = 0;
|
||||
uint32_t start_websrv = 0;
|
||||
uint32_t noS1 = 0, nokrnmod = 1, nonbiot = 0;
|
||||
uint32_t rfsim = 0, do_forms = 0, do_forms_qt = 0;
|
||||
uint32_t rfsim = 0, do_forms = 0;
|
||||
int nfapi_index = 0;
|
||||
char *logmem_filename = NULL;
|
||||
check_execmask(execmask);
|
||||
@@ -162,10 +162,6 @@ void get_common_options(configmodule_interface_t *cfg, uint32_t execmask)
|
||||
set_softmodem_optmask(SOFTMODEM_DOSCOPE_BIT);
|
||||
}
|
||||
|
||||
if (do_forms_qt) {
|
||||
set_softmodem_optmask(SOFTMODEM_DOSCOPE_QT_BIT);
|
||||
}
|
||||
|
||||
if (start_websrv) {
|
||||
load_module_shlib("websrv", NULL, 0, NULL);
|
||||
}
|
||||
|
||||
@@ -70,7 +70,6 @@ extern "C"
|
||||
#define CONFIG_HLP_SLF "Set the sidelink frequency for all component carriers\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_QT "Enable soft scope and L1 and L2 stats (QT)\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_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n"
|
||||
@@ -168,7 +167,6 @@ extern int usrp_tx_thread;
|
||||
{"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}, \
|
||||
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, .uptr=&do_forms, .defintval=0, TYPE_UINT, 0}, \
|
||||
{"dqt" , CONFIG_HLP_SOFTS_QT, PARAMFLAG_BOOL, .uptr=&do_forms_qt, .defintval=0, TYPE_UINT, 0}, \
|
||||
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, .iptr=&opp_enabled, .defintval=0, TYPE_INT, 0}, \
|
||||
{"numerology" , CONFIG_HLP_NUMEROLOGY, 0, .iptr=&NUMEROLOGY, .defintval=1, TYPE_INT, 0}, \
|
||||
{"band" , CONFIG_HLP_BAND, 0, .iptr=&BAND, .defintval=78, TYPE_INT, 0}, \
|
||||
@@ -298,7 +296,6 @@ extern int usrp_tx_thread;
|
||||
#define SOFTMODEM_4GUE_BIT (1<<22)
|
||||
#define SOFTMODEM_5GUE_BIT (1<<23)
|
||||
#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 MAPPING_SOFTMODEM_FUNCTIONS {{"enb",SOFTMODEM_ENB_BIT},{"gnb",SOFTMODEM_GNB_BIT},{"4Gue",SOFTMODEM_4GUE_BIT},{"5Gue",SOFTMODEM_5GUE_BIT}}
|
||||
@@ -311,7 +308,6 @@ extern int usrp_tx_thread;
|
||||
#define IS_SOFTMODEM_SIML1 ( get_softmodem_optmask() & SOFTMODEM_SIML1_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_QT ( get_softmodem_optmask() & SOFTMODEM_DOSCOPE_QT_BIT)
|
||||
#define IS_SOFTMODEM_IQPLAYER ( get_softmodem_optmask() & SOFTMODEM_RECPLAY_BIT)
|
||||
#define IS_SOFTMODEM_IQRECORDER ( get_softmodem_optmask() & SOFTMODEM_RECRECORD_BIT)
|
||||
#define IS_SOFTMODEM_TELNETCLT_BIT ( get_softmodem_optmask() & SOFTMODEM_TELNETCLT_BIT)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,563 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* Authors and copyright: Bo Zhao, Marwan Hammouda, Thomas Schlichter (Fraunhofer IIS)
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef QT_SCOPE_MAINWINDOW_H
|
||||
#define QT_SCOPE_MAINWINDOW_H
|
||||
|
||||
#include <QtCharts>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/// This is an enum class for the different gNB plot types
|
||||
enum class PlotTypeGnb {
|
||||
empty,
|
||||
waterFall,
|
||||
CIR,
|
||||
puschLLR,
|
||||
puschIQ,
|
||||
puschSNR,
|
||||
puschBLER,
|
||||
puschMCS,
|
||||
puschRETX,
|
||||
puschThroughput,
|
||||
pdschSNR,
|
||||
pdschBLER,
|
||||
pdschMCS,
|
||||
pdschRETX,
|
||||
pdschThroughput,
|
||||
pdschRBs,
|
||||
config
|
||||
};
|
||||
|
||||
/// This is an enum class fpr the different UE plot types
|
||||
enum class PlotTypeUE {
|
||||
empty,
|
||||
waterFall,
|
||||
CIR,
|
||||
pbchLLR,
|
||||
pbchIQ,
|
||||
pdcchLLR,
|
||||
pdcchIQ,
|
||||
pdschLLR,
|
||||
pdschIQ,
|
||||
pdschSNR,
|
||||
pdschBLER,
|
||||
pdschMCS,
|
||||
pdschThroughput,
|
||||
pdschRBs,
|
||||
frequencyOffset,
|
||||
timingAdvance,
|
||||
config,
|
||||
psbchLLR,
|
||||
psbchIQ,
|
||||
psbchRSRP,
|
||||
};
|
||||
|
||||
/// This abstract class defines an interface how the KPIPlot class can access values for the different KPI plot types
|
||||
class ValueProvider {
|
||||
public:
|
||||
/// This pure virtual function is meant to provide the KPI value to be plotted
|
||||
virtual float getValue() = 0;
|
||||
};
|
||||
|
||||
class ValueProviderUE : public ValueProvider {
|
||||
public:
|
||||
/// This pure virtual function is meant to provide the graph values to be plotted
|
||||
virtual scopeGraphData_t *getPlotValue()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
/// Class for emitting a queued signal to update plots
|
||||
class PlotUpdater : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
signals:
|
||||
void updatePlot(int numElt);
|
||||
};
|
||||
|
||||
/// An editable GUI field for a dialog box to set certain KPI configurations
|
||||
class ConfigBoxFloat : public QLineEdit {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
/// \param valuePtr Pointer to a float value, which can be edited through this ConfigBoxFloat
|
||||
/// \param parent Optional pointer to parent QWidget
|
||||
ConfigBoxFloat(float *valuePtr, QWidget *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
/// This function converts the value in the editable GUI field to float and writes it back to valuePtr
|
||||
void readText();
|
||||
|
||||
private:
|
||||
/// Member variable keeping the pointer to the float value
|
||||
float *valuePtr;
|
||||
};
|
||||
|
||||
/// Dialog box for configuring gNB KPI Limits
|
||||
class KPIConfigGnb : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
/// \param parent Optional pointer to parent QWidget
|
||||
explicit KPIConfigGnb(QWidget *parent = nullptr);
|
||||
};
|
||||
|
||||
/// Dialog box for configuring UE KPI Limits
|
||||
class KPIConfigUE : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
/// \param parent Optional pointer to parent QWidget
|
||||
explicit KPIConfigUE(QWidget *parent = nullptr);
|
||||
};
|
||||
|
||||
/// drop-down list gNB
|
||||
class KPIListSelectGnb : public QComboBox {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
/// \param parent Optional pointer to parent QWidget
|
||||
explicit KPIListSelectGnb(QWidget *parent = nullptr);
|
||||
};
|
||||
|
||||
/// drop-down list UE
|
||||
class KPIListSelectUE : public QComboBox {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
/// \param parent Optional pointer to parent QWidget
|
||||
explicit KPIListSelectUE(QWidget *parent = nullptr);
|
||||
};
|
||||
|
||||
/// Waterfall plot of RX signal power
|
||||
class WaterFall : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
/// \param values Pointer to the digital I/Q samples
|
||||
/// \param frame_parms Pointer to the NR_DL_FRAME_PARMS
|
||||
/// \param parent Optional pointer to parent QWidget
|
||||
WaterFall(complex16 *values, NR_DL_FRAME_PARMS *frame_parms, QWidget *parent = nullptr);
|
||||
|
||||
protected:
|
||||
/// This function is triggered when the own timer expires. It reads data from values and updates the image
|
||||
/// \param event Pointer to the timer event
|
||||
virtual void timerEvent(QTimerEvent *event) override;
|
||||
|
||||
/// This function is used to draw the image on the GUI
|
||||
/// \param event Pointer to the paint event
|
||||
virtual void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
/// This function is called to change the WaterFall size
|
||||
/// \param event Pointer to the resize event
|
||||
virtual void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
private:
|
||||
/// Pointer to the digital I/Q samples
|
||||
complex16 *values;
|
||||
|
||||
/// Pointer to the NR_DL_FRAME_PARMS
|
||||
NR_DL_FRAME_PARMS *frame_parms;
|
||||
|
||||
/// Pointer to the image
|
||||
QImage *image;
|
||||
|
||||
/// Counter of the drawn lines
|
||||
int iteration;
|
||||
|
||||
/// pointer to an array storing per-row average power values
|
||||
double *waterFallAvg;
|
||||
};
|
||||
|
||||
/// Chart class for plotting the Channel Impulse Response
|
||||
class CIRPlot : public QChart {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
/// \param data Pointer to the CIR data
|
||||
/// \param len Length of the CIR data
|
||||
CIRPlot(complex16 *data, int len);
|
||||
|
||||
protected:
|
||||
/// This function is triggered when the own timer expires. It updates the plotted CIR
|
||||
/// \param event Pointer to the timer event
|
||||
virtual void timerEvent(QTimerEvent *event) override;
|
||||
|
||||
/// Pointer to the CIR data
|
||||
complex16 *data;
|
||||
|
||||
/// Length of the CIR data
|
||||
int len;
|
||||
|
||||
/// Line series used to plot the CIR in the chart
|
||||
QLineSeries *series;
|
||||
|
||||
/// Horizontal axis of the chart
|
||||
QValueAxis *axisX;
|
||||
|
||||
/// Vertical axis of the chart
|
||||
QValueAxis *axisY;
|
||||
};
|
||||
|
||||
class CIRPlotUE : public CIRPlot {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CIRPlotUE(complex16 *data, int len, ValueProviderUE *valueProvider) : CIRPlot(data, len), valueProvider(valueProvider)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
/// This function is triggered when the own timer expires. It updates the plotted CIR
|
||||
/// \param event Pointer to the timer event
|
||||
virtual void timerEvent(QTimerEvent *event) override;
|
||||
|
||||
private:
|
||||
ValueProviderUE *valueProvider;
|
||||
};
|
||||
|
||||
/// Chart class for plotting LLRs
|
||||
class LLRPlot : public QChart {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
/// \param data Pointer to the LLR data
|
||||
/// \param len Length of the LLR data
|
||||
/// \param interval update interval in ms (0 means no timer-triggered updates)
|
||||
/// \param plotUpdater pointer to a PlotUpdater for update notifications
|
||||
LLRPlot(int16_t *data, int len, int interval = 1000, PlotUpdater *plotUpdater = nullptr);
|
||||
|
||||
/// Destructor
|
||||
~LLRPlot();
|
||||
|
||||
public slots:
|
||||
/// This function updates the plotted LLR
|
||||
void updatePlot(int len);
|
||||
|
||||
protected:
|
||||
/// This function is triggered when the own timer expires. It calls updatePlot() to update the plotted LLR
|
||||
/// \param event Pointer to the timer event
|
||||
virtual void timerEvent(QTimerEvent *event) override;
|
||||
|
||||
/// Pointer to the LLR data
|
||||
int16_t *data;
|
||||
|
||||
/// Length of the LLR data
|
||||
int len;
|
||||
|
||||
/// Pointer to a PlotUpdater for update notifications
|
||||
PlotUpdater *plotUpdater;
|
||||
|
||||
/// Scatter series used to plot the LLR in the chart
|
||||
QScatterSeries *series;
|
||||
|
||||
/// Horizontal axis of the chart
|
||||
QValueAxis *axisX;
|
||||
|
||||
/// Vertical axis of the chart
|
||||
QValueAxis *axisY;
|
||||
};
|
||||
|
||||
class LLRPlotUE : public LLRPlot {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LLRPlotUE(int16_t *data, int len, ValueProviderUE *valueProvider) : LLRPlot(data, len), valueProvider(valueProvider)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
/// This function is triggered when the own timer expires. It updates the plotted I/Q constellation diagram
|
||||
/// \param event Pointer to the timer event
|
||||
virtual void timerEvent(QTimerEvent *event) override;
|
||||
|
||||
private:
|
||||
ValueProviderUE *valueProvider;
|
||||
};
|
||||
|
||||
/// Chart class for plotting the I/Q constellation diagram
|
||||
class IQPlot : public QChart {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
/// \param data Pointer to the complex I/Q data
|
||||
/// \param len Length of the I/Q data
|
||||
/// \param interval update interval in ms (0 means no timer-triggered updates)
|
||||
/// \param plotUpdater pointer to a PlotUpdater for update notifications
|
||||
IQPlot(complex16 *data, int len, int interval = 1000, PlotUpdater *plotUpdater = nullptr);
|
||||
|
||||
/// Destructor
|
||||
~IQPlot();
|
||||
|
||||
public slots:
|
||||
/// This function updates the plotted I/Q constellation diagram
|
||||
void updatePlot(int len);
|
||||
|
||||
protected:
|
||||
/// This function is triggered when the own timer expires. It calls updatePlot() to update the plotted I/Q constellation diagram
|
||||
/// \param event Pointer to the timer event
|
||||
virtual void timerEvent(QTimerEvent *event) override;
|
||||
|
||||
/// Pointer to the I/Q data
|
||||
complex16 *data;
|
||||
|
||||
/// Length of the I/Q data
|
||||
int len;
|
||||
|
||||
/// Pointer to a PlotUpdater for update notifications
|
||||
PlotUpdater *plotUpdater;
|
||||
|
||||
/// Scatter series used to plot the I/Q constellation diagram
|
||||
QScatterSeries *series;
|
||||
|
||||
/// Horizontal axis of the chart
|
||||
QValueAxis *axisX;
|
||||
|
||||
/// Vertical axis of the chart
|
||||
QValueAxis *axisY;
|
||||
};
|
||||
|
||||
class IQPlotUE : public IQPlot {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
IQPlotUE(complex16 *data, int len, ValueProviderUE *valueProvider) : IQPlot(data, len), valueProvider(valueProvider)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
/// This function is triggered when the own timer expires. It updates the plotted I/Q constellation diagram
|
||||
/// \param event Pointer to the timer event
|
||||
virtual void timerEvent(QTimerEvent *event) override;
|
||||
|
||||
private:
|
||||
/// Pointer to an instance of a class that implements the ValueProvider interface
|
||||
ValueProviderUE *valueProvider;
|
||||
};
|
||||
|
||||
/// Generic class for plotting KPI values with min., max. and average bars
|
||||
class KPIPlot : public QChart {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
/// \param valueProvider Pointer to an instance of a class that implements the ValueProvider interface
|
||||
/// \param limits Optional parameter pointing to an array of two floating point values indicating lower and upper bounds
|
||||
KPIPlot(ValueProvider *valueProvider, float *limits = nullptr);
|
||||
|
||||
protected:
|
||||
/// This function is triggered when the own timer expires. It updates the plotted KPI chart
|
||||
/// \param event Pointer to the timer event
|
||||
virtual void timerEvent(QTimerEvent *event) override;
|
||||
|
||||
private:
|
||||
/// Pointer to an instance of a class that implements the ValueProvider interface
|
||||
ValueProvider *valueProvider;
|
||||
|
||||
/// Pointer to an array of two floating point values indicating lower and upper bounds
|
||||
float *limits;
|
||||
|
||||
/// smallest observed KPI value
|
||||
float minValue;
|
||||
|
||||
/// biggest observed KPI value
|
||||
float maxValue;
|
||||
|
||||
/// Accumulated KPI valus, used to compute the average
|
||||
float sumValue;
|
||||
|
||||
/// Index (horizontal position) of the last plotted KPI value
|
||||
int plotIdx;
|
||||
|
||||
/// Line series used to plot the KPI values
|
||||
QLineSeries *series;
|
||||
|
||||
/// Line series used to plot an indication of the smallest observed KPI value
|
||||
QLineSeries *seriesMin;
|
||||
|
||||
/// Line series used to plot an indication of the biggest observed KPI value
|
||||
QLineSeries *seriesMax;
|
||||
|
||||
/// Line series used to plot an indication of the average KPI value
|
||||
QLineSeries *seriesAvg;
|
||||
|
||||
/// Horizontal axis of the chart
|
||||
QValueAxis *axisX;
|
||||
|
||||
/// Vertical axis of the chart
|
||||
QValueAxis *axisY;
|
||||
};
|
||||
|
||||
/// Crart class for plotting HARQ retransmission counters
|
||||
class RTXPlot : public QChart {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
/// \param rounds Pointer to the HARQ round counters
|
||||
RTXPlot(uint64_t *rounds);
|
||||
|
||||
protected:
|
||||
/// This function is triggered when the own timer expires. It updates the plotted HARQ retransmission counters
|
||||
/// \param event Pointer to the timer event
|
||||
virtual void timerEvent(QTimerEvent *event) override;
|
||||
|
||||
private:
|
||||
/// Pointer to the HARQ round counters
|
||||
uint64_t *rounds;
|
||||
|
||||
/// Last stored HARQ round counters
|
||||
uint64_t lastRounds[4];
|
||||
|
||||
/// Maximum observed HARQ retransmissions
|
||||
int maxValue;
|
||||
|
||||
/// Index (horizontal position) of the last plotted HARQ retransmission value
|
||||
int plotIdx;
|
||||
|
||||
/// Line series used to plot the four HARQ retransmission counters
|
||||
QLineSeries *series[4];
|
||||
|
||||
/// Horizontal axis of the chart
|
||||
QValueAxis *axisX;
|
||||
|
||||
/// Vertical axis of the chart
|
||||
QValueAxis *axisY;
|
||||
};
|
||||
|
||||
/// Widget showing one selectable gNB KPI
|
||||
class PainterWidgetGnb : public QWidget, public ValueProvider {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
/// \param config Pointer to the dialog box for configuring gNB KPI Limits
|
||||
/// \param comboBox Pointer to the drop-down list selecting the KPI to be shown here
|
||||
/// \param p Pointer to the gNB parameters
|
||||
PainterWidgetGnb(QWidget *config, QComboBox *comboBox, scopeData_t *p);
|
||||
|
||||
/// This function provides the current KPI value to be plotted
|
||||
virtual float getValue() override;
|
||||
|
||||
protected:
|
||||
/// This function is called to change the widget size
|
||||
/// \param event Pointer to the resize event
|
||||
virtual void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
public slots:
|
||||
/// This function is called when a different KPI is selected
|
||||
/// \param type selected KPI type
|
||||
void makeConnections(int type);
|
||||
|
||||
private:
|
||||
/// Pointer to the dialog box for configuring gNB KPI Limits
|
||||
QWidget *config;
|
||||
|
||||
/// Pointer to the drop-down list selecting the KPI to be shown here
|
||||
QComboBox *comboBox;
|
||||
|
||||
/// Pointer to the gNB parameters
|
||||
scopeData_t *p;
|
||||
|
||||
/// Pointer to a class to view all QChart based KPIs
|
||||
QChartView *chartView;
|
||||
|
||||
/// Pointer to the waterfall diagram
|
||||
WaterFall *waterFall;
|
||||
|
||||
/// Currently plotted KPI type
|
||||
PlotTypeGnb plotType;
|
||||
};
|
||||
|
||||
/// Widget showing one selectable UE KPI
|
||||
class PainterWidgetUE : public QWidget, public ValueProviderUE {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
/// \param config Pointer to the dialog box for configuring UE KPI Limits
|
||||
/// \param comboBox Pointer to the drop-down list selecting the KPI to be shown here
|
||||
/// \param ue Pointer to the UE parameters
|
||||
PainterWidgetUE(QWidget *config, QComboBox *comboBox, PHY_VARS_NR_UE *ue);
|
||||
|
||||
/// This function provides the current KPI value to be plotted
|
||||
virtual float getValue() override;
|
||||
|
||||
virtual scopeGraphData_t *getPlotValue() override;
|
||||
|
||||
protected:
|
||||
/// This function is called to change the widget size
|
||||
/// \param event Pointer to the resize event
|
||||
virtual void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
public slots:
|
||||
/// This function is called when a different KPI is selected
|
||||
/// \param type selected KPI type
|
||||
void makeConnections(int type);
|
||||
|
||||
private:
|
||||
/// Pointer to the dialog box for configuring UE KPI Limits
|
||||
QWidget *config;
|
||||
|
||||
/// Pointer to the drop-down list selecting the KPI to be shown here
|
||||
QComboBox *comboBox;
|
||||
|
||||
/// Pointer to the UE parameters
|
||||
PHY_VARS_NR_UE *ue;
|
||||
|
||||
/// Pointer to a class to view all QChart based KPIs
|
||||
QChartView *chartView;
|
||||
|
||||
/// Pointer to the waterfall diagram
|
||||
WaterFall *waterFall;
|
||||
|
||||
/// Currently plotted KPI type
|
||||
PlotTypeUE plotType;
|
||||
};
|
||||
|
||||
#endif // QT_SCOPE_MAINWINDOW_H
|
||||
@@ -31,66 +31,3 @@ or
|
||||
```
|
||||
phy_scope_gNB(0, phy_vars_gnb, phy_vars_ru, UE_id)
|
||||
```
|
||||
|
||||
# Qt-based Scope
|
||||
|
||||
## Building Instructions
|
||||
For the new qt-based scope designed for NR, please consider the following:
|
||||
|
||||
1. run the gNB or the UE with the option '--dqt'.
|
||||
2. make sure to install the Qt5 packages before running the scope. Otherwise, the scope will NOT be displayed! Note that Qt6 does NOT work.
|
||||
3. To build the new scope, add 'nrqtscope' after the '--build-lib' option. So, the complete command would be
|
||||
|
||||
```
|
||||
./build_oai --gNB -w USRP --nrUE --build-lib nrqtscope
|
||||
```
|
||||
|
||||
## New Features
|
||||
|
||||
1. New KPIs for both gNB and UE, e.g., BLER, MCS, throughout, and number of scheduled RBs.
|
||||
2. For each of the gNB and UE, a main widget is created with a 3x2 grid of sub-widgets, each to display one KPI.
|
||||
3. Each of the sub-widgets has a drop-down list to choose the KPI to show in that sub-widget.
|
||||
4. Both of the gNB and UE scopes can be resized using the mouse movement.
|
||||
|
||||
## Troubleshoot
|
||||
|
||||
Similar as with the Xforms-based scope, you should allow root to open X
|
||||
windows if using Xorg:
|
||||
```
|
||||
xhost +si:localuser:root
|
||||
```
|
||||
|
||||
If you run on Wayland (e.g., Gnome on Ubuntu 22), you might get this error:
|
||||
```
|
||||
Warning: Ignoring XDG_SESSION_TYPE=wayland on Gnome. Use QT_QPA_PLATFORM=wayland to run on Wayland anyway.
|
||||
Authorization required, but no authorization protocol specified
|
||||
qt.qpa.xcb: could not connect to display :0
|
||||
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
|
||||
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
|
||||
```
|
||||
|
||||
We have to force the use of Wayland. Before that, make sure that the Qt-Wayland
|
||||
plugin is installed. Also, there seems to be a problem with the qt5-gtk
|
||||
platform theme, so remove it:
|
||||
```
|
||||
sudo apt-get install qtwayland5
|
||||
sudo apt-get remove qt5-gtk-platformtheme
|
||||
```
|
||||
|
||||
Now, force the Wayland plugin; also make sure to pass `-E` to sudo:
|
||||
```
|
||||
sudo -E QT_QPA_PLATFORM=wayland ./nr-softmodem --sa -O <conf> --dqt
|
||||
```
|
||||
|
||||
Furthermore, if you get the following warning, _followed by a segfault_ (i.e.,
|
||||
if it runs, you can ignore this)
|
||||
```
|
||||
QStandardPaths: wrong ownership on runtime directory /run/user/1000, 1000 instead of 0
|
||||
```
|
||||
You can set the XDG runtime directory like one of the following options (try in
|
||||
order, keep `QT_QPA_PLATFORM` if necessary)
|
||||
```
|
||||
sudo -E XDG_RUNTIME_DIR=/run/user/0 ./nr-softmodem ...
|
||||
sudo -E XDG_RUNTIME_DIR=/tmp/runtime-root ./nr-softmodem ...
|
||||
sudo -E XDG_RUNTIME_DIR= ./nr-softmodem ...
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user