Partial source calibration dialog

This commit is contained in:
Jan Käberich 2020-11-16 20:05:29 +01:00
parent 6f717de0f1
commit 875f3b0170
28 changed files with 784 additions and 33 deletions

View file

@ -1,11 +1,13 @@
HEADERS += \
../VNA_embedded/Application/Communication/Protocol.hpp \
Calibration/amplitudecaldialog.h \
Calibration/calibration.h \
Calibration/calibrationtracedialog.h \
Calibration/calkit.h \
Calibration/calkitdialog.h \
Calibration/json.hpp \
Calibration/measurementmodel.h \
Calibration/sourcecaldialog.h \
CustomWidgets/colorpickerbutton.h \
CustomWidgets/informationbox.h \
CustomWidgets/siunitedit.h \
@ -48,11 +50,13 @@ HEADERS += \
SOURCES += \
../VNA_embedded/Application/Communication/Protocol.cpp \
Calibration/amplitudecaldialog.cpp \
Calibration/calibration.cpp \
Calibration/calibrationtracedialog.cpp \
Calibration/calkit.cpp \
Calibration/calkitdialog.cpp \
Calibration/measurementmodel.cpp \
Calibration/sourcecaldialog.cpp \
CustomWidgets/colorpickerbutton.cpp \
CustomWidgets/informationbox.cpp \
CustomWidgets/qwtplotpiecewisecurve.cpp \
@ -102,6 +106,7 @@ win32:LIBS += -LC:\Qwt-6.1.4\lib -lqwt
QT += widgets
FORMS += \
Calibration/amplitudecaldialog.ui \
Calibration/calibrationtracedialog.ui \
Calibration/calkitdialog.ui \
CustomWidgets/tilewidget.ui \

View file

@ -0,0 +1,187 @@
#include "amplitudecaldialog.h"
#include "ui_amplitudecaldialog.h"
#include "mode.h"
#include "unit.h"
#include <QDebug>
AmplitudeCalDialog::AmplitudeCalDialog(Device *dev, QWidget *parent) :
QDialog(parent),
ui(new Ui::AmplitudeCalDialog),
dev(dev),
model(this)
{
activeMode = Mode::getActiveMode();
activeMode->deactivate();
dev->SetIdle();
ui->setupUi(this);
ui->view->setModel(&model);
ui->view->setColumnWidth(AmplitudeModel::ColIndexFreq, 100);
ui->view->setColumnWidth(AmplitudeModel::ColIndexCorrectionFactors, 150);
ui->view->setColumnWidth(AmplitudeModel::ColIndexPort1, 150);
ui->view->setColumnWidth(AmplitudeModel::ColIndexPort2, 150);
connect(dev, &Device::AmplitudeCorrectionPointReceived, this, &AmplitudeCalDialog::ReceivedPoint);
connect(ui->load, &QPushButton::clicked, this, &AmplitudeCalDialog::LoadFromDevice);
connect(ui->add, &QPushButton::clicked, this, &AmplitudeCalDialog::AddPoint);
connect(ui->remove, &QPushButton::clicked, this, &AmplitudeCalDialog::RemovePoint);
}
AmplitudeCalDialog::~AmplitudeCalDialog()
{
delete ui;
activeMode->activate();
}
void AmplitudeCalDialog::reject()
{
// TODO check for unsaved data
delete this;
}
std::vector<AmplitudeCalDialog::CorrectionPoint> AmplitudeCalDialog::getPoints() const
{
return points;
}
void AmplitudeCalDialog::setAmplitude(double amplitude, unsigned int point, bool port2)
{
if(point >= points.size()) {
return;
}
if(port2) {
points[point].amplitudePort2 = amplitude;
} else {
points[point].amplitudePort1 = amplitude;
}
}
void AmplitudeCalDialog::ReceivedPoint(Protocol::AmplitudeCorrectionPoint p)
{
qDebug() << "Received a point";
CorrectionPoint c;
c.frequency = p.freq * 10.0;
c.correctionPort1 = p.port1;
c.correctionPort2 = p.port2;
model.beginInsertRows(QModelIndex(), points.size(), points.size());
points.push_back(c);
model.endInsertRows();
emit pointsUpdated();
}
void AmplitudeCalDialog::LoadFromDevice()
{
model.beginResetModel();
points.clear();
model.endResetModel();
qDebug() << "Asking for amplitude calibration";
dev->SendCommandWithoutPayload(requestCommand());
}
void AmplitudeCalDialog::SaveToDevice()
{
for(unsigned int i=0;i<points.size();i++) {
auto p = points[i];
Protocol::PacketInfo info;
info.type = pointType();
info.amplitudePoint.freq = p.frequency / 10.0;
info.amplitudePoint.port1 = p.correctionPort1;
info.amplitudePoint.port2 = p.correctionPort2;
info.amplitudePoint.totalPoints = points.size();
info.amplitudePoint.pointNum = i;
dev->SendPacket(info);
}
}
void AmplitudeCalDialog::RemovePoint()
{
unsigned int row = ui->view->currentIndex().row();
if(row < points.size()) {
model.beginRemoveRows(QModelIndex(), row, row);
points.erase(points.begin() + row);
model.endInsertRows();
}
}
void AmplitudeCalDialog::AddPoint()
{
}
AmplitudeModel::AmplitudeModel(AmplitudeCalDialog *c) :
QAbstractTableModel(),
c(c)
{
}
int AmplitudeModel::rowCount(const QModelIndex &parent) const
{
return c->getPoints().size();
}
int AmplitudeModel::columnCount(const QModelIndex &parent) const
{
return ColIndexLast;
}
QVariant AmplitudeModel::data(const QModelIndex &index, int role) const
{
if(role == Qt::DisplayRole && index.row() < c->getPoints().size()) {
auto p = c->getPoints()[index.row()];
switch(index.column()) {
case ColIndexFreq:
return Unit::ToString(p.frequency, "Hz", " kMG", 6);
break;
case ColIndexCorrectionFactors:
return QString::number(p.correctionPort1) + ", " + QString::number(p.correctionPort2);
break;
case ColIndexPort1:
return Unit::ToString(p.amplitudePort1, "dbm", " ", 4);
break;
case ColIndexPort2:
return Unit::ToString(p.amplitudePort2, "dbm", " ", 4);
break;
}
}
return QVariant();
}
bool AmplitudeModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if((unsigned int) index.row() >= c->getPoints().size()) {
return false;
}
switch(index.column()) {
case ColIndexPort1:
c->setAmplitude(value.toDouble(), index.row(), false);
return true;
case ColIndexPort2:
c->setAmplitude(value.toDouble(), index.row(), true);
return true;
}
return false;
}
QVariant AmplitudeModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if(orientation == Qt::Horizontal && role == Qt::DisplayRole) {
switch(section) {
case ColIndexFreq: return "Frequency"; break;
case ColIndexCorrectionFactors: return "Correction Factors"; break;
case ColIndexPort1: return "Amplitude Port 1"; break;
case ColIndexPort2: return "Amplitude Port 2"; break;
default: return QVariant(); break;
}
} else {
return QVariant();
}
}
Qt::ItemFlags AmplitudeModel::flags(const QModelIndex &index) const
{
int flags = Qt::NoItemFlags;
switch(index.column()) {
case ColIndexPort1: flags |= Qt::ItemIsEnabled | Qt::ItemIsEditable; break;
case ColIndexPort2: flags |= Qt::ItemIsEnabled | Qt::ItemIsEditable; break;
}
return (Qt::ItemFlags) flags;
}

View file

@ -0,0 +1,77 @@
#ifndef AMPLITUDECALDIALOG_H
#define AMPLITUDECALDIALOG_H
#include <QDialog>
#include "mode.h"
#include "Device/device.h"
namespace Ui {
class AmplitudeCalDialog;
}
class AmplitudeCalDialog;
class AmplitudeModel : public QAbstractTableModel
{
friend AmplitudeCalDialog;
Q_OBJECT
public:
AmplitudeModel(AmplitudeCalDialog *c);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
private:
enum {
ColIndexFreq,
ColIndexCorrectionFactors,
ColIndexPort1,
ColIndexPort2,
ColIndexLast
};
AmplitudeCalDialog *c;
};
class AmplitudeCalDialog : public QDialog
{
Q_OBJECT
public:
explicit AmplitudeCalDialog(Device *dev, QWidget *parent = nullptr);
~AmplitudeCalDialog();
void reject() override;
class CorrectionPoint {
public:
double frequency;
double correctionPort1;
double correctionPort2;
double amplitudePort1;
double amplitudePort2;
};
std::vector<CorrectionPoint> getPoints() const;
void setAmplitude(double amplitude, unsigned int point, bool port2);
protected slots:
void ReceivedPoint(Protocol::AmplitudeCorrectionPoint p);
void LoadFromDevice();
void SaveToDevice();
void RemovePoint();
void AddPoint();
signals:
void pointsUpdated();
protected:
virtual Protocol::PacketType requestCommand() = 0;
virtual Protocol::PacketType pointType() = 0;
std::vector<CorrectionPoint> points;
Ui::AmplitudeCalDialog *ui;
Device *dev;
Mode *activeMode;
AmplitudeModel model;
};
#endif // SOURCECALDIALOG_H

View file

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AmplitudeCalDialog</class>
<widget class="QDialog" name="AmplitudeCalDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>766</width>
<height>599</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QTableView" name="view">
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectItems</enum>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="add">
<property name="text">
<string>Add Point</string>
</property>
<property name="icon">
<iconset theme="list-add" resource="../icons.qrc">
<normaloff>:/icons/add.png</normaloff>:/icons/add.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="remove">
<property name="text">
<string>Delete Point</string>
</property>
<property name="icon">
<iconset theme="list-remove" resource="../icons.qrc">
<normaloff>:/icons/remove.png</normaloff>:/icons/remove.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="help">
<property name="text">
<string>Help</string>
</property>
<property name="icon">
<iconset theme="help"/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="load">
<property name="text">
<string>Load from Device</string>
</property>
<property name="icon">
<iconset theme="document-open" resource="../icons.qrc">
<normaloff>:/icons/open.png</normaloff>:/icons/open.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="save">
<property name="text">
<string>Save to Device</string>
</property>
<property name="icon">
<iconset theme="document-save" resource="../icons.qrc">
<normaloff>:/icons/save.png</normaloff>:/icons/save.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<resources>
<include location="../icons.qrc"/>
</resources>
<connections/>
</ui>

View file

@ -0,0 +1,8 @@
#include "sourcecaldialog.h"
SourceCalDialog::SourceCalDialog(Device *dev)
: AmplitudeCalDialog(dev)
{
setWindowTitle("Source Calibration Dialog");
LoadFromDevice();
}

View file

@ -0,0 +1,17 @@
#ifndef SOURCECALDIALOG_H
#define SOURCECALDIALOG_H
#include <QObject>
#include "amplitudecaldialog.h"
class SourceCalDialog : public AmplitudeCalDialog
{
Q_OBJECT
public:
SourceCalDialog(Device *dev);
protected:
Protocol::PacketType requestCommand() override { return Protocol::PacketType::RequestSourceCal; }
Protocol::PacketType pointType() override { return Protocol::PacketType::SourceCalPoint; }
};
#endif // SOURCECALDIALOG_H

View file

@ -434,6 +434,10 @@ void Device::ReceivedData()
case Protocol::PacketType::SpectrumAnalyzerResult:
emit SpectrumResultReceived(packet.spectrumResult);
break;
case Protocol::PacketType::SourceCalPoint:
case Protocol::PacketType::ReceiverCalPoint:
emit AmplitudeCorrectionPointReceived(packet.amplitudePoint);
break;
case Protocol::PacketType::DeviceInfo:
if(packet.info.ProtocolVersion != Protocol::Version) {
if(!lastInfoValid) {

View file

@ -13,8 +13,8 @@
Q_DECLARE_METATYPE(Protocol::Datapoint);
Q_DECLARE_METATYPE(Protocol::ManualStatus);
Q_DECLARE_METATYPE(Protocol::DeviceInfo);
Q_DECLARE_METATYPE(Protocol::SpectrumAnalyzerResult);
Q_DECLARE_METATYPE(Protocol::AmplitudeCorrectionPoint);
class USBInBuffer : public QObject {
Q_OBJECT;
@ -74,6 +74,7 @@ signals:
void DatapointReceived(Protocol::Datapoint);
void ManualStatusReceived(Protocol::ManualStatus);
void SpectrumResultReceived(Protocol::SpectrumAnalyzerResult);
void AmplitudeCorrectionPointReceived(Protocol::AmplitudeCorrectionPoint);
void DeviceInfoUpdated();
void ConnectionLost();
void AckReceived();

View file

@ -63,7 +63,7 @@ void FirmwareUpdateDialog::on_bStart_clicked()
addStatus("Erasing device memory...");
dev->SendCommandWithoutPayload(Protocol::PacketType::ClearFlash);
timer.setSingleShot(true);
timer.start(10000);
timer.start(20000);
}
void FirmwareUpdateDialog::addStatus(QString line)

View file

@ -144,7 +144,6 @@ ManualControlDialog::ManualControlDialog(Device &dev, QWidget *parent) :
MakeReadOnly(ui->refmag);
MakeReadOnly(ui->refphase);
qRegisterMetaType<Protocol::ManualStatus>("Status");
connect(&dev, &Device::ManualStatusReceived, this, &ManualControlDialog::NewStatus);
connect(ui->SourceCE, &QCheckBox::toggled, [=](bool) { UpdateDevice(); });

View file

@ -192,8 +192,6 @@ SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window)
window->addDockWidget(Qt::BottomDockWidgetArea, markerDock);
docks.insert(markerDock);
qRegisterMetaType<Protocol::SpectrumAnalyzerResult>("SpectrumResult");
// Set initial sweep settings
auto pref = Preferences::getInstance();
if(pref.Startup.RememberSweepSettings) {

View file

@ -360,8 +360,6 @@ VNA::VNA(AppWindow *window)
window->addDockWidget(Qt::BottomDockWidgetArea, markerDock);
docks.insert(markerDock);
qRegisterMetaType<Protocol::Datapoint>("Datapoint");
// Set initial sweep settings
auto pref = Preferences::getInstance();
if(pref.Acquisition.alwaysExciteBothPorts) {

View file

@ -44,6 +44,7 @@
#include "VNA/vna.h"
#include "Generator/generator.h"
#include "SpectrumAnalyzer/spectrumanalyzer.h"
#include "Calibration/sourcecaldialog.h"
using namespace std;
@ -100,6 +101,7 @@ AppWindow::AppWindow(QWidget *parent)
connect(ui->actionQuit, &QAction::triggered, this, &AppWindow::close);
connect(ui->actionManual_Control, &QAction::triggered, this, &AppWindow::StartManualControl);
connect(ui->actionFirmware_Update, &QAction::triggered, this, &AppWindow::StartFirmwareUpdateDialog);
connect(ui->actionSource_Calibration, &QAction::triggered, this, &AppWindow::SourceCalibrationDialog);
connect(ui->actionPreferences, &QAction::triggered, [=](){
Preferences::getInstance().edit();
// settings might have changed, update necessary stuff
@ -129,6 +131,9 @@ AppWindow::AppWindow(QWidget *parent)
vna->activate();
qRegisterMetaType<Protocol::Datapoint>("Datapoint");
qRegisterMetaType<Protocol::ManualStatus>("Manual");
qRegisterMetaType<Protocol::SpectrumAnalyzerResult>("SpectrumAnalyzerResult");
qRegisterMetaType<Protocol::AmplitudeCorrectionPoint>("AmplitudeCorrection");
// List available devices
if(UpdateDeviceList() && Preferences::getInstance().Startup.ConnectToFirstDevice) {
@ -181,6 +186,7 @@ void AppWindow::ConnectToDevice(QString serial)
ui->actionDisconnect->setEnabled(true);
ui->actionManual_Control->setEnabled(true);
ui->actionFirmware_Update->setEnabled(true);
ui->actionSource_Calibration->setEnabled(true);
Mode::getActiveMode()->initializeDevice();
UpdateReference();
@ -207,6 +213,7 @@ void AppWindow::DisconnectDevice()
ui->actionDisconnect->setEnabled(false);
ui->actionManual_Control->setEnabled(false);
ui->actionFirmware_Update->setEnabled(false);
ui->actionSource_Calibration->setEnabled(false);
for(auto a : deviceActionGroup->actions()) {
a->setChecked(false);
}
@ -349,6 +356,12 @@ void AppWindow::DeviceNeedsUpdate(int reported, int expected)
}
}
void AppWindow::SourceCalibrationDialog()
{
auto d = new SourceCalDialog(device);
d->exec();
}
Device *AppWindow::getDevice() const
{
return device;

View file

@ -44,6 +44,7 @@ private slots:
void UpdateReference();
void StartFirmwareUpdateDialog();
void DeviceNeedsUpdate(int reported, int expected);
void SourceCalibrationDialog();
private:
void DeviceConnectionLost();
void CreateToolbars();

View file

@ -48,6 +48,8 @@
<addaction name="separator"/>
<addaction name="actionManual_Control"/>
<addaction name="actionFirmware_Update"/>
<addaction name="separator"/>
<addaction name="actionSource_Calibration"/>
</widget>
<widget class="QMenu" name="menuWindow">
<property name="title">
@ -151,6 +153,14 @@
<string>About</string>
</property>
</action>
<action name="actionSource_Calibration">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Source Calibration</string>
</property>
</action>
</widget>
<resources>
<include location="icons.qrc"/>