Valgrind memory bugfixes + auto port extension

This commit is contained in:
Jan Käberich 2020-10-31 23:03:34 +01:00
parent 7f691bd37d
commit a5c9f1e3d3
19 changed files with 183 additions and 45 deletions

View File

@ -123,3 +123,5 @@ RESOURCES += \
icons.qrc
CONFIG += c++14
REVISION = $$system(git rev-parse HEAD)
DEFINES += GITHASH=\\"\"$$REVISION\\"\"

View File

@ -676,8 +676,9 @@ istream& operator >>(istream &in, Calibration &c)
{
std::string line;
while(getline(in, line)) {
QString qLine = QString::fromStdString(line).simplified();
for(auto m : c.Measurements()) {
if(Calibration::MeasurementToString(m) == QString::fromStdString(line)) {
if(Calibration::MeasurementToString(m) == qLine) {
// this is the correct measurement
c.clearMeasurement(m);
uint timestamp;
@ -699,8 +700,8 @@ istream& operator >>(istream &in, Calibration &c)
}
}
for(auto t : Calibration::Types()) {
if(Calibration::TypeToString(t) == QString::fromStdString(line)) {
// try to P2 this calibration type
if(Calibration::TypeToString(t) == qLine) {
// try to apply this calibration type
if(c.calculationPossible(t)) {
c.constructErrorTerms(t);
} else {

View File

@ -8,12 +8,13 @@
SIUnitEdit::SIUnitEdit(QString unit, QString prefixes, int precision, QWidget *parent)
: QLineEdit(parent)
{
_value = 0;
this->unit = unit;
this->prefixes = prefixes;
this->precision = precision;
setAlignment(Qt::AlignCenter);
installEventFilter(this);
setValidator(new QDoubleValidator);
setValidator(new QDoubleValidator(this));
connect(this, &QLineEdit::editingFinished, [this]() {
parseNewValue(1.0);
});

View File

@ -40,7 +40,7 @@ USBInBuffer::~USBInBuffer()
qWarning() << "Timed out waiting for mutex acquisition during disconnect";
}
}
delete buffer;
delete[] buffer;
}
void USBInBuffer::removeBytes(int handled_bytes)
@ -71,16 +71,15 @@ void USBInBuffer::Callback(libusb_transfer *transfer)
emit DataReceived();
inCallback = false;
break;
case LIBUSB_TRANSFER_ERROR:
qCritical() << "LIBUSB_TRANSFER_ERROR";
case LIBUSB_TRANSFER_NO_DEVICE:
qCritical() << "LIBUSB_TRANSFER_NO_DEVICE";
case LIBUSB_TRANSFER_OVERFLOW:
qCritical() << "LIBUSB_TRANSFER_OVERFLOW";
case LIBUSB_TRANSFER_STALL:
qCritical() << "LIBUSB_TRANSFER_STALL";
libusb_free_transfer(transfer);
this->transfer = nullptr;
return;
case LIBUSB_TRANSFER_ERROR:
case LIBUSB_TRANSFER_OVERFLOW:
case LIBUSB_TRANSFER_STALL:
qCritical() << "LIBUSB_ERROR" << transfer->status;
libusb_free_transfer(transfer);
emit TransferError();
return;
break;
@ -129,6 +128,7 @@ Device::Device(QString serial)
qDebug() << "Starting device connection...";
m_handle = nullptr;
lastInfoValid = false;
libusb_init(&m_context);
SearchDevices([=](libusb_device_handle *handle, QString found_serial) -> bool {
@ -202,6 +202,7 @@ Device::~Device()
libusb_close(m_handle);
m_receiveThread->join();
libusb_exit(m_context);
delete m_receiveThread;
}
}
@ -245,9 +246,7 @@ bool Device::SetManual(Protocol::ManualControl manual)
bool Device::SetIdle()
{
Protocol::SweepSettings s;
s.excitePort1 = 0;
s.excitePort2 = 0;
Protocol::SweepSettings s = {};
return Configure(s);
}

View File

@ -4,7 +4,7 @@
Generator::Generator(AppWindow *window)
: Mode(window, "Signal Generator")
{
central = new SignalgeneratorWidget();
central = new SignalgeneratorWidget(window);
auto pref = Preferences::getInstance();

View File

@ -43,9 +43,10 @@
SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window)
: Mode(window, "Spectrum Analyzer"),
central(new TileWidget(traceModel))
central(new TileWidget(traceModel, window))
{
averages = 1;
settings = {};
// Create default traces
auto tPort1 = new Trace("Port1", Qt::yellow);
@ -120,7 +121,6 @@ SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window)
auto tb_acq = new QToolBar("Acquisition");
auto eBandwidth = new SIUnitEdit("Hz", " k", 3);
eBandwidth->setValueQuiet(settings.RBW);
eBandwidth->setFixedWidth(70);
eBandwidth->setToolTip("RBW");
connect(eBandwidth, &SIUnitEdit::valueChanged, this, &SpectrumAnalyzer::SetRBW);
@ -180,7 +180,7 @@ SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window)
markerModel = new TraceMarkerModel(traceModel);
auto tracesDock = new QDockWidget("Traces");
tracesDock->setWidget(new TraceWidget(traceModel, this, true));
tracesDock->setWidget(new TraceWidget(traceModel, window, true));
window->addDockWidget(Qt::LeftDockWidgetArea, tracesDock);
docks.insert(tracesDock);

View File

@ -22,6 +22,9 @@ MarkerWidget::MarkerWidget(TraceMarkerModel &model, QWidget *parent) :
MarkerWidget::~MarkerWidget()
{
delete ui->tableView->itemDelegateForColumn(TraceMarkerModel::ColIndexTrace);
delete ui->tableView->itemDelegateForColumn(TraceMarkerModel::ColIndexType);
delete ui->tableView->itemDelegateForColumn(TraceMarkerModel::ColIndexSettings);
delete ui;
}

View File

@ -9,6 +9,14 @@ TraceModel::TraceModel(QObject *parent)
traces.clear();
}
TraceModel::~TraceModel()
{
while(!traces.empty()) {
delete traces[0];
traces.erase(traces.begin());
}
}
void TraceModel::addTrace(Trace *t)
{
beginInsertRows(QModelIndex(), traces.size(), traces.size());

View File

@ -11,6 +11,7 @@ class TraceModel : public QAbstractTableModel
Q_OBJECT
public:
TraceModel(QObject *parent = 0);
~TraceModel();
void addTrace(Trace *t);
void removeTrace(unsigned int index);

View File

@ -75,7 +75,7 @@ void TracePlot::updateContextMenu()
contextmenu->addSection("Traces");
// Populate context menu
for(auto t : traces) {
auto action = new QAction(t.first->name());
auto action = new QAction(t.first->name(), contextmenu);
action->setCheckable(true);
if(t.second) {
action->setChecked(true);
@ -86,7 +86,7 @@ void TracePlot::updateContextMenu()
contextmenu->addAction(action);
}
contextmenu->addSeparator();
auto close = new QAction("Close");
auto close = new QAction("Close", contextmenu);
contextmenu->addAction(close);
connect(close, &QAction::triggered, [=]() {
markedForDeletion = true;

View File

@ -115,6 +115,25 @@ TraceXYPlot::TraceXYPlot(TraceModel &model, QWidget *parent)
: TracePlot(parent),
selectedMarker(nullptr)
{
YAxis[0].log = false;
YAxis[0].Ytype = YAxisType::Disabled;
YAxis[0].rangeDiv = 1;
YAxis[0].rangeMax = 10;
YAxis[0].rangeMin = 0;
YAxis[0].autorange = false;
YAxis[1].log = false;
YAxis[1].Ytype = YAxisType::Disabled;
YAxis[1].rangeDiv = 1;
YAxis[1].rangeMax = 10;
YAxis[1].rangeMin = 0;
YAxis[1].autorange = false;
XAxis.Xtype = XAxisType::Frequency;
XAxis.log = false;
XAxis.rangeDiv = 1;
XAxis.rangeMax = 10;
XAxis.rangeMin = 0;
XAxis.autorange = true;
plot = new QwtPlot(this);
auto canvas = new QwtPlotCanvas(plot);
@ -274,7 +293,7 @@ bool TraceXYPlot::isTDRtype(TraceXYPlot::YAxisType type)
void TraceXYPlot::updateContextMenu()
{
contextmenu->clear();
auto setup = new QAction("Axis setup...");
auto setup = new QAction("Axis setup...", contextmenu);
connect(setup, &QAction::triggered, [this]() {
auto setup = new XYplotAxisDialog(this);
setup->show();
@ -295,7 +314,7 @@ void TraceXYPlot::updateContextMenu()
continue;
}
auto action = new QAction(t.first->name());
auto action = new QAction(t.first->name(), contextmenu);
action->setCheckable(true);
if(tracesAxis[axis].find(t.first) != tracesAxis[axis].end()) {
action->setChecked(true);
@ -307,7 +326,7 @@ void TraceXYPlot::updateContextMenu()
}
}
contextmenu->addSeparator();
auto close = new QAction("Close");
auto close = new QAction("Close", contextmenu);
contextmenu->addAction(close);
connect(close, &QAction::triggered, [=]() {
markedForDeletion = true;

View File

@ -2,6 +2,7 @@
#include "ui_portextensioneditdialog.h"
#include <QCheckBox>
#include <cmath>
#include <QDebug>
using namespace std;
@ -31,11 +32,92 @@ void PortExtension::applyToMeasurement(Protocol::Datapoint &d)
if(measurements.size() > 0) {
if(d.pointNum == 0) {
// sweep complete, evaluate measurement
// TODO
double last_phase = 0.0;
double phasediff_sum = 0.0;
vector<double> att_x, att_y;
double avg_x = 0.0, avg_y = 0.0;
for(auto m : measurements) {
// grab correct measurement
complex<double> reflection;
if(isPort1) {
reflection = complex<double>(m.real_S11, m.imag_S11);
} else {
reflection = complex<double>(m.real_S22, m.imag_S22);
}
// remove calkit if specified
if(!isIdeal) {
complex<double> calStandard;
auto standards = kit->toSOLT(m.frequency);
if(isOpen) {
calStandard = standards.Open;
} else {
calStandard = standards.Short;
}
// remove effect of calibration standard
reflection /= calStandard;
}
// sum phase differences to previous point
auto phase = arg(reflection);
if(m.pointNum == 0) {
last_phase = phase;
} else {
auto phasediff = phase - last_phase;
last_phase = phase;
if(phasediff > M_PI) {
phasediff -= 2 * M_PI;
} else if(phasediff <= -M_PI) {
phasediff += 2 * M_PI;
}
phasediff_sum += phasediff;
qDebug() << phasediff;
}
double x = sqrt(m.frequency / measurements.back().frequency);
double y = 20*log10(abs(reflection));
att_x.push_back(x);
att_y.push_back(y);
avg_x += x;
avg_y += y;
}
auto phase = phasediff_sum / (measurements.size() - 1);
auto freq_diff = measurements[1].frequency - measurements[0].frequency;
auto delay = -phase / (2 * M_PI * freq_diff);
// measured delay is two-way but port extension expects one-way
delay /= 2;
// calculate linear regression with transformed square root model
avg_x /= measurements.size();
avg_y /= measurements.size();
double sum_top = 0.0;
double sum_bottom = 0.0;
for(unsigned int i=0;i<att_x.size();i++) {
sum_top += (att_x[i] - avg_x)*(att_y[i] - avg_y);
sum_bottom += (att_x[i] - avg_x)*(att_x[i] - avg_x);
}
double beta = sum_top / sum_bottom;
double alpha = avg_y - beta * avg_x;
double DCloss = -alpha / 2;
double loss = -beta / 2;
double freq = measurements.back().frequency;
if(isPort1) {
ui->P1Time->setValue(delay);
ui->P1DCloss->setValue(DCloss);
ui->P1Loss->setValue(loss);
ui->P1Frequency->setValue(freq);
} else {
ui->P2Time->setValue(delay);
ui->P2DCloss->setValue(DCloss);
ui->P2Loss->setValue(loss);
ui->P2Frequency->setValue(freq);
}
if(msgBox) {
msgBox->close();
msgBox = nullptr;
}
measurements.clear();
} else {
measurements.push_back(d);
}
@ -94,7 +176,7 @@ void PortExtension::edit()
constexpr double c = 299792458;
auto dialog = new QDialog();
auto ui = new Ui::PortExtensionEditDialog();
ui = new Ui::PortExtensionEditDialog();
ui->setupUi(dialog);
// set initial values

View File

@ -7,6 +7,10 @@
#include "Calibration/calkit.h"
#include <QMessageBox>
namespace Ui {
class PortExtensionEditDialog;
}
class PortExtension : public QObject
{
Q_OBJECT
@ -39,6 +43,7 @@ private:
bool isIdeal;
std::vector<Protocol::Datapoint> measurements;
QMessageBox *msgBox;
Ui::PortExtensionEditDialog *ui;
};
#endif // PORTEXTENSION_H

View File

@ -86,7 +86,7 @@ VNA::VNA(AppWindow *window)
central->Child2()->Child2()->setPlot(tracesmith2);
// Create menu entries and connections
auto calMenu = new QMenu("Calibration");
auto calMenu = new QMenu("Calibration", window);
window->menuBar()->insertMenu(window->getUi()->menuWindow->menuAction(), calMenu);
actions.insert(calMenu->menuAction());
auto calDisable = calMenu->addAction("Disabled");
@ -112,13 +112,13 @@ VNA::VNA(AppWindow *window)
portExtension.setCalkit(&cal.getCalibrationKit());
// Tools menu
auto toolsMenu = new QMenu("Tools");
auto toolsMenu = new QMenu("Tools", window);
window->menuBar()->insertMenu(window->getUi()->menuWindow->menuAction(), toolsMenu);
actions.insert(toolsMenu->menuAction());
auto impedanceMatching = toolsMenu->addAction("Impedance Matching");
connect(impedanceMatching, &QAction::triggered, this, &VNA::StartImpedanceMatching);
defaultCalMenu = new QMenu("Default Calibration");
defaultCalMenu = new QMenu("Default Calibration", window);
assignDefaultCal = defaultCalMenu->addAction("Assign...");
removeDefaultCal = defaultCalMenu->addAction("Remove");
removeDefaultCal->setEnabled(false);
@ -201,7 +201,6 @@ VNA::VNA(AppWindow *window)
// Acquisition toolbar
auto tb_acq = new QToolBar("Acquisition");
auto dbm = new QDoubleSpinBox();
dbm->setValue(settings.cdbm_excitation * 100);
dbm->setFixedWidth(95);
dbm->setRange(-100.0, 100.0);
dbm->setSingleStep(0.25);
@ -215,7 +214,6 @@ VNA::VNA(AppWindow *window)
auto points = new QSpinBox();
points->setFixedWidth(55);
points->setRange(1, 4501);
points->setValue(settings.points);
points->setSingleStep(100);
points->setToolTip("Points/sweep");
connect(points, qOverload<int>(&QSpinBox::valueChanged), this, &VNA::SetPoints);
@ -224,7 +222,6 @@ VNA::VNA(AppWindow *window)
tb_acq->addWidget(points);
auto eBandwidth = new SIUnitEdit("Hz", " k", 3);
eBandwidth->setValueQuiet(settings.if_bandwidth);
eBandwidth->setFixedWidth(70);
eBandwidth->setToolTip("IF bandwidth");
connect(eBandwidth, &SIUnitEdit::valueChanged, this, &VNA::SetIFBandwidth);
@ -255,7 +252,7 @@ VNA::VNA(AppWindow *window)
calMenuGroup->addAction(calDisable);
for(auto type : Calibration::Types()) {
cbType->addItem(Calibration::TypeToString(type), (int) type);
auto menuAction = new QAction(Calibration::TypeToString(type));
auto menuAction = new QAction(Calibration::TypeToString(type), calMenu);
calMenuGroup->addAction(menuAction);
connect(menuAction, &QAction::triggered, [=](){
ApplyCalibration(type);
@ -316,7 +313,7 @@ VNA::VNA(AppWindow *window)
toolbars.insert(tb_portExtension);
markerModel = new TraceMarkerModel(traceModel);
markerModel = new TraceMarkerModel(traceModel, this);
auto tracesDock = new QDockWidget("Traces");
tracesDock->setWidget(new TraceWidget(traceModel));
@ -609,13 +606,13 @@ void VNA::ApplyCalibration(Calibration::Type type)
emit CalibrationApplied(type);
}
} catch (runtime_error e) {
QMessageBox::critical(this, "Calibration failure", e.what());
QMessageBox::critical(window, "Calibration failure", e.what());
DisableCalibration(true);
}
} else {
// Not all required traces available
// TODO start tracedata dialog with required traces
QMessageBox::information(this, "Missing calibration traces", "Not all calibration traces for this type of calibration have been measured. The calibration can be enabled after the missing traces have been acquired.");
QMessageBox::information(window, "Missing calibration traces", "Not all calibration traces for this type of calibration have been measured. The calibration can be enabled after the missing traces have been acquired.");
DisableCalibration(true);
StartCalibrationDialog(type);
}
@ -679,11 +676,11 @@ void VNA::LoadSweepSettings()
QSettings s;
settings.f_start = s.value("SweepStart", pref.Startup.DefaultSweep.start).toULongLong();
settings.f_stop = s.value("SweepStop", pref.Startup.DefaultSweep.stop).toULongLong();
ConstrainAndUpdateFrequencies();
SetIFBandwidth(s.value("SweepBandwidth", pref.Startup.DefaultSweep.bandwidth).toUInt());
SetPoints(s.value("SweepPoints", pref.Startup.DefaultSweep.points).toInt());
SetIFBandwidth(s.value("SweepBandwidth", pref.Startup.DefaultSweep.bandwidth).toUInt());
SetAveraging(s.value("SweepAveraging", pref.Startup.DefaultSweep.averaging).toInt());
SetSourceLevel(s.value("SweepLevel", pref.Startup.DefaultSweep.excitation).toDouble());
ConstrainAndUpdateFrequencies();
}
void VNA::StoreSweepSettings()

View File

@ -59,8 +59,6 @@ AppWindow::AppWindow(QWidget *parent)
device = nullptr;
ui->setupUi(this);
// ui->statusbar->insertPermanentWidget(0, &lDeviceStatus);
// ui->statusbar->insertPermanentWidget(1, new QPushButton("Test"));
ui->statusbar->addWidget(&lConnectionStatus);
auto div1 = new QFrame;
div1->setFrameShape(QFrame::VLine);
@ -91,8 +89,6 @@ AppWindow::AppWindow(QWidget *parent)
auto vna = new VNA(this);
new Generator(this);
new SpectrumAnalyzer(this);
// auto signalGenWidget = new Signalgenerator;
// modeSGen = new GUIMode(this, "Signal Generator", signalGenWidget);
// UI connections
connect(ui->actionUpdate_Device_List, &QAction::triggered, this, &AppWindow::UpdateDeviceList);
@ -112,6 +108,11 @@ AppWindow::AppWindow(QWidget *parent)
// settings might have changed, update necessary stuff
TraceXYPlot::updateGraphColors();
});
connect(ui->actionAbout, &QAction::triggered, [=](){
auto commit = QString(GITHASH);
commit.truncate(7);
QMessageBox::about(this, "About", "More information: github.com/jankae/VNA2\n\nVersion: " + commit);
});
setWindowTitle("VNA");
@ -137,6 +138,11 @@ AppWindow::AppWindow(QWidget *parent)
}
}
AppWindow::~AppWindow()
{
delete ui;
}
void AppWindow::closeEvent(QCloseEvent *event)
{
delete device;

View File

@ -28,7 +28,7 @@ class AppWindow : public QMainWindow
Q_OBJECT
public:
AppWindow(QWidget *parent = nullptr);
~AppWindow();
Ui::MainWindow *getUi() const;
QStackedWidget *getCentral() const;

View File

@ -69,9 +69,16 @@
<addaction name="menuToolbars"/>
<addaction name="actionPreferences"/>
</widget>
<widget class="QMenu" name="menuHelp">
<property name="title">
<string>Help</string>
</property>
<addaction name="actionAbout"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuDevice"/>
<addaction name="menuWindow"/>
<addaction name="menuHelp"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<action name="actionQuit">
@ -139,6 +146,11 @@
<string>Preferences</string>
</property>
</action>
<action name="actionAbout">
<property name="text">
<string>About</string>
</property>
</action>
</widget>
<resources>
<include location="icons.qrc"/>

View File

@ -9,7 +9,8 @@ QWidget* Mode::cornerWidget = nullptr;
QButtonGroup* Mode::modeButtonGroup = nullptr;
Mode::Mode(AppWindow *window, QString name)
: window(window),
: QObject(window),
window(window),
name(name),
central(nullptr)
{

View File

@ -9,10 +9,11 @@
#include <set>
#include "appwindow.h"
class Mode : public QWidget
class Mode : public QObject
{
public:
Mode(AppWindow *window, QString name);
virtual void activate();
virtual void deactivate();
QString getName() const;