Fix bug in QT scope

The UE copies scope data not in a single buffer to avoid overwiring in case of multiple slots processing in parallel. But the scope upates data from single buffer thats assigned during selection. A getPlotValue() method is created to update the data pointer on every timerEvent.
This commit is contained in:
Sakthivel Velumani
2023-04-03 10:25:13 -04:00
parent 9e4d522937
commit 0004626ac7
2 changed files with 170 additions and 10 deletions
+113 -6
View File
@@ -317,6 +317,34 @@ void CIRPlot::timerEvent(QTimerEvent *event)
this->series->replace(points);
}
void CIRPlotUE::timerEvent(QTimerEvent *event)
{
if (!this->isVisible())
return;
scopeGraphData_t *data = this->valueProvider->getPlotValue();
if (data) {
this->data = (complex16 *)(data + 1);
this->len = data->lineSz;
QVector<QPointF> points(this->len);
float maxY = this->axisY->max();
for (int i = 0; i < this->len / 2; i++) {
float value = SquaredNorm(this->data[i + this->len / 2]);
points[i] = QPointF(i - this->len / 2, value);
maxY = std::max(maxY, value);
}
for (int i = 0; i < this->len / 2; i++) {
float value = SquaredNorm(this->data[i]);
points[i + this->len / 2] = QPointF(i, value);
maxY = std::max(maxY, value);
}
this->axisY->setMax(maxY);
this->series->replace(points);
}
}
LLRPlot::LLRPlot(int16_t *data, int len) : data(data), len(len)
{
this->legend()->hide();
@@ -361,6 +389,28 @@ void LLRPlot::timerEvent(QTimerEvent *event)
this->series->replace(points);
}
void LLRPlotUE::timerEvent(QTimerEvent *event)
{
if (!this->isVisible())
return;
scopeGraphData_t *data = this->valueProvider->getPlotValue();
if (data) {
this->data = (int16_t *)(data + 1);
this->len = data->lineSz;
QVector<QPointF> points(this->len);
int maxY = this->axisY->max();
for (int i = 0; i < this->len; i++) {
points[i] = QPointF(i, this->data[i]);
maxY = std::max(maxY, abs(this->data[i]));
}
this->axisY->setRange(-maxY, maxY);
this->series->replace(points);
}
}
IQPlot::IQPlot(complex16 *data, int len) : data(data), len(len)
{
this->legend()->hide();
@@ -407,6 +457,32 @@ void IQPlot::timerEvent(QTimerEvent *event)
this->series->replace(points);
}
void IQPlotUE::timerEvent(QTimerEvent *event)
{
if (!this->isVisible())
return;
scopeGraphData_t *data = this->valueProvider->getPlotValue();
if (data) {
this->data = (complex16 *)(data + 1);
this->len = data->lineSz;
QVector<QPointF> points(this->len);
int maxX = this->axisX->max();
int maxY = this->axisY->max();
for (int i = 0; i < this->len; i++) {
points[i] = QPointF(this->data[i].r, this->data[i].i);
maxX = std::max(maxX, abs(this->data[i].r));
maxY = std::max(maxY, abs(this->data[i].i));
}
this->axisX->setRange(-maxX, maxX);
this->axisY->setRange(-maxY, maxY);
this->series->replace(points);
}
}
KPIPlot::KPIPlot(ValueProvider *valueProvider, float *limits) : valueProvider(valueProvider), limits(limits)
{
this->series = new QLineSeries();
@@ -815,11 +891,42 @@ float PainterWidgetUE::getValue()
case PlotTypeUE::timingAdvance:
return (float)this->ue->timing_advance;
default:
return 0;
}
}
scopeGraphData_t *PainterWidgetUE::getPlotValue()
{
scopeData_t *scope = (scopeData_t *)this->ue->scopeData;
scopeGraphData_t **data = (scopeGraphData_t **)scope->liveData;
switch (this->plotType) {
case PlotTypeUE::CIR:
return data[pbchDlChEstimateTime];
case PlotTypeUE::pbchLLR:
return data[pbchLlr];
case PlotTypeUE::pbchIQ:
return data[pbchRxdataF_comp];
case PlotTypeUE::pdcchLLR:
return data[pdcchLlr];
case PlotTypeUE::pdcchIQ:
return data[pdcchRxdataF_comp];
case PlotTypeUE::pdschLLR:
return data[pdschLlr];
case PlotTypeUE::pdschIQ:
return data[pdschRxdataF_comp];
default:
return nullptr;
}
}
/* @UE Class: this function is called when a resize event is detected, then the widget will be adjusted accordignly. */
void PainterWidgetUE::resizeEvent(QResizeEvent *event)
{
@@ -890,7 +997,7 @@ void PainterWidgetUE::makeConnections(int type)
this->comboBox->setCurrentIndex(static_cast<int>(PlotTypeUE::empty));
break;
}
newChart = new LLRPlot((int16_t *)(data[pbchLlr] + 1), data[pbchLlr]->lineSz);
newChart = new LLRPlotUE((int16_t *)(data[pbchLlr] + 1), data[pbchLlr]->lineSz, this);
break;
}
case PlotTypeUE::pbchIQ: {
@@ -900,7 +1007,7 @@ void PainterWidgetUE::makeConnections(int type)
this->comboBox->setCurrentIndex(static_cast<int>(PlotTypeUE::empty));
break;
}
newChart = new IQPlot((complex16 *)(data[pbchRxdataF_comp] + 1), data[pbchRxdataF_comp]->lineSz);
newChart = new IQPlotUE((complex16 *)(data[pbchRxdataF_comp] + 1), data[pbchRxdataF_comp]->lineSz, this);
break;
}
case PlotTypeUE::pdcchLLR: {
@@ -910,7 +1017,7 @@ void PainterWidgetUE::makeConnections(int type)
this->comboBox->setCurrentIndex(static_cast<int>(PlotTypeUE::empty));
break;
}
newChart = new LLRPlot((int16_t *)(data[pdcchLlr] + 1), data[pdcchLlr]->lineSz);
newChart = new LLRPlotUE((int16_t *)(data[pdcchLlr] + 1), data[pdcchLlr]->lineSz, this);
break;
}
case PlotTypeUE::pdcchIQ: {
@@ -920,7 +1027,7 @@ void PainterWidgetUE::makeConnections(int type)
this->comboBox->setCurrentIndex(static_cast<int>(PlotTypeUE::empty));
break;
}
newChart = new IQPlot((complex16 *)(data[pdcchRxdataF_comp] + 1), data[pdcchRxdataF_comp]->lineSz);
newChart = new IQPlotUE((complex16 *)(data[pdcchRxdataF_comp] + 1), data[pdcchRxdataF_comp]->lineSz, this);
break;
}
case PlotTypeUE::pdschLLR: {
@@ -930,7 +1037,7 @@ void PainterWidgetUE::makeConnections(int type)
this->comboBox->setCurrentIndex(static_cast<int>(PlotTypeUE::empty));
break;
}
newChart = new LLRPlot((int16_t *)(data[pdschLlr] + 1), data[pdschLlr]->lineSz);
newChart = new LLRPlotUE((int16_t *)(data[pdschLlr] + 1), data[pdschLlr]->lineSz, this);
break;
}
case PlotTypeUE::pdschIQ: {
@@ -940,7 +1047,7 @@ void PainterWidgetUE::makeConnections(int type)
this->comboBox->setCurrentIndex(static_cast<int>(PlotTypeUE::empty));
break;
}
newChart = new IQPlot((complex16 *)(data[pdschRxdataF_comp] + 1), data[pdschRxdataF_comp]->lineSz);
newChart = new IQPlotUE((complex16 *)(data[pdschRxdataF_comp] + 1), data[pdschRxdataF_comp]->lineSz, this);
break;
}
+57 -4
View File
@@ -91,6 +91,14 @@ class ValueProvider {
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;
}
};
/// An editable GUI field for a dialog box to set certain KPI configurations
class ConfigBoxFloat : public QLineEdit {
Q_OBJECT
@@ -206,7 +214,6 @@ class CIRPlot : public QChart {
/// \param event Pointer to the timer event
virtual void timerEvent(QTimerEvent *event) override;
private:
/// Pointer to the CIR data
complex16 *data;
@@ -223,6 +230,21 @@ class CIRPlot : public QChart {
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
@@ -238,7 +260,6 @@ class LLRPlot : public QChart {
/// \param event Pointer to the timer event
virtual void timerEvent(QTimerEvent *event) override;
private:
/// Pointer to the LLR data
int16_t *data;
@@ -255,6 +276,21 @@ class LLRPlot : public QChart {
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
@@ -270,7 +306,6 @@ class IQPlot : public QChart {
/// \param event Pointer to the timer event
virtual void timerEvent(QTimerEvent *event) override;
private:
/// Pointer to the I/Q data
complex16 *data;
@@ -287,6 +322,22 @@ class IQPlot : public QChart {
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
@@ -422,7 +473,7 @@ class PainterWidgetGnb : public QWidget, public ValueProvider {
};
/// Widget showing one selectable UE KPI
class PainterWidgetUE : public QWidget, public ValueProvider {
class PainterWidgetUE : public QWidget, public ValueProviderUE {
Q_OBJECT
public:
@@ -435,6 +486,8 @@ class PainterWidgetUE : public QWidget, public ValueProvider {
/// 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